On Fri, Jun 17, 2016 at 12:06:48PM +0200, Bernd Schmidt wrote: > This is another step to flesh out -mmitigate-rop for i386 a little more. The > basic idea was (I think) Richard Henderson's: if we could arrange to have > every return preceded by a leave instruction, it would make it harder to > construct an attack since it takes away a certain amount of control over the > stack pointer. I extended this to move the leave/ret pair to libgcc, > preceded by a sequence of nops, so as to take away the possibility of > jumping into the middle of an instruction preceding the leave/ret pair and > thereby skipping the leave.
Do you really need to require frame pointer for this? I mean, couldn't you instead use what you do if a function needs frame pointer and otherwise just replace the original ret with pushq %rbp movq %rsp, %rbp jmp __rop_ret ? Or would that defeat the purpose of the mitigation? Though, I think it is very common to have functions that just don't do anything in many of libraries and so the pushq %rbp; movq %rsp, %rbp; jmp __rop_ret sequence would still very likely appear somewhere. As for __rop_ret, if you are non-PLT jmp to it, I bet it must be in the same executable or shared library as the code branching to it, so should be .hidden. Is libgcc.a really the best place for it though? I mean, in various cases we don't even link libgcc.a (sometimes we only link libgcc_s.so.1). Wouldn't it be better to emit the __rop_ret stuff into every CU into a comdat section, like we do e.g. for the i686 PIC pads. Is this stuff meant only for -m64, or also for 32-bit code? If the latter, then e.g. the i686 PIC pads is something where you also have ret without leave before it. Looking at nop; nop; 1: jmp 1b; leave; ret if you branch into the middle of the jmp insn (0x3 below), there is: 0: 90 nop 1: 90 nop 2: eb fe jmp 0x2 4: c9 leaveq 5: c3 retq and thus: 3: fe c9 dec %cl 5: c3 retq and thus if you don't mind decreasing %cl, you still have retq without leave before it. But I very likely just don't understand the ROP threat stuff enough. Jakub