3 ms·
It's not exploitable. It's an exploit mitigation, in fact. It's not a bug; it's intentional that it works this way. And Nathan Michaels didn't think that if
by JdeBP 1y ago
It's not exploitable. It's an exploit mitigation, in fact. It's not a bug; it's intentional that it works this way. And Nathan Michaels didn't think that if you want to find Theo de Raadt writing on some subject, better try OpenBSD discussion fora, not the LLVM mailing list. (-:
This was put into OpenBSD back in 2017. It's not "trap instructions". It's "trapsleds". The idea is to trap the sleds (a.k.a. slides) of NOP instructions that linkers used to put in between compiled code for alignment, and which could be exploited with "return-oriented programming" where an attacker could cause execution to jump to any address in the padding range (possibly needing the inexactitude because of constraints upon byte substitutions) and slide along all of the NOPs to the target function.
* https://undeadly.org/cgi?action=article;sid=20170622065629 https://undeadly.org/cgi?action=article;sid=20170622065629
* https://isopenbsdsecu.re/mitigations/trapsled/ https://isopenbsdsecu.re/mitigations/trapsled/
- vintagedave 1y agoThe article states that on ARM Thumb, the instruction meant to be interpreted as a trap does not trap but jumps, instead.
- JdeBP 1y ago[flagged]
- colanderman 1y agoYou are misunderstanding the purpose of the initial jump in a trap sled. It is to redirect code which expects to flow through the sled past the traps, while leaving the traps for anything else which lands in that range. The padding the article is talking about lives between functions. It is not meant to be executed, nothing is needed to jump over it. (The unconditional bx lr before it is the return at the end of the function.)
- JdeBP 1y ago[flagged]
- tourist2d 1y ago[dead]
- colanderman 1y agoFrom your own link: > The trapsleds implemented in this diff convert NOP sleds longer than 2 bytes from a series of 0x66666690 instructions to a 2 byte short JMP over a series of INT3 instructions that fill the rest of the gap. The BMI instructions in the article are not jumping over breakpoint (INT3) instructions. They're conditionally jumping backwards by some amount. Why in your belief is this? Please use your own words or a relevant direct quote to state your understanding of how a trapsled works.
- deleted 1y ago[deleted]
- Dylan16807 1y ago> It's not exploitable. The article doesn't say it is. > It's an exploit mitigation, in fact. The article made that clear. > It's not a bug; it's intentional that it works this way. What is "this way"? Trap or jump? If you're saying a jump is supposed to count as a trap, it's a pretty bad one. It still allows a lot of jumps to the padding to continue and execute valuable code.
- JdeBP 1y ago[flagged]
- Dylan16807 1y agoIt says why it jumps over nops in the middle of a function. No explanation for jumping backwards at the end of a function. And it replaces the nops with int3. Not another jump. This code keeps stacking d4.
- MayeulC 1y agoPutting instructions that halt execution in unreachable parts of the code would make sense, but this is just a jump with a fixed offset, which may technically still be exploitable. If trap instructions are not possible, I would at least try to make it an unconditional jump to create an infinite loop.
- colanderman 1y agoThe instructions have to be trap instructions for it to work. The conditional branch-backward instruction it is is almost as bad as the series of NOPs, since it is still likely to redirect an attacker to functioning code. (If the attacker can clear the mi flag first, these are just NOPs!) Hence yes, this is a broken exploit mitigation.
- JdeBP 1y agoAnd this is where the OpenBSD people will paraphrase Henry Spencer and say that those who do not understand OpenBSD are doomed to reinvent it badly. (Personally, I think that that's putting OpenBSD onto a pedestal. It's no ideal; one gets the same tradeoffs and problems as everywhere else.) In this case, the reinvention for LLVM targetting ARM, that credits seeing this committed to OpenBSD by Theo de Raadt, totally ignored that the original for gas targetting x86 both trapped and jumped. I intentionally also pointed you to a collection of several critiques of the whole idea, long-since made. (-:
- tourist2d 1y ago[dead]
- deleted 1y ago[deleted]
- colanderman 1y agoWhy, in your own words, is the jump supposed to be there? (Keep in mind this code is in between two functions.) And why, in your own words, is it OK for the jump to be a conditional backwards jump?
- Dylan16807 1y agoSo now you're saying this is a bad reinvention? Your first comment says "it's intentional that it works this way".
- ajross 1y agoI think you're misunderstanding. 32 bit ARM has TWO instruction encodings. OpenBSD apparently only knows about one. In thumb encoding, the instruction is a branch, not a trap.
- Aurornis 1y ago> It's not exploitable. It's an exploit mitigation, in fact. It's not a bug; it's intentional that it works this way. If the instructions are branching instead of trapping (as explained in the article) then it would be exploitable as a ROP gadget and it would be a bug.
- quantumwoke 1y agoYour second link suggests that this mitigation is not very helpful these days. I suppose in that light it doesn't really matter if LLVM changes it to a trap instruction or not.
- ajross 1y agoYes yes, but it's only an exploit mitigation if the bytes encode a mitigating instruction. On 32 bit ARM, they do. In thumb mode[1], they don't. That's interesting enough to be worth a blog post. [1] For those who don't realize: author is on a Cortex-M processor per the ISA Ref they cite. These devices support *only* thumb instructions. Although as of thumb2, the encoding is now variable-length and there are lots of not-at-all-orthogonal-with-big-ARM 32 bit variants too. It's... not really the same architecture at all, to be honest.
- amluto 1y agoThe discussions you linked to are about amd64, where 0xcc is indeed reliably a trap. The OP is about ARM, and it’s about 0xd4d4, not 0xcc.