On 06/17/2016 12:37 PM, Jakub Jelinek wrote:
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?
Yes, kind of, because then you can jump into code before this little sequence and the whole pushq/movq/jmp/leave/ret would just behave like a normal ret. This is admittedly a concern for smaller functions that look a lot like this; maybe we need to pad function entry points as well.
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 declare myself agnostic.
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.
You'd also have to find useful code before this sequence, and in any case it's just a single ret where we used to have many. But maybe there's a one-byte trap that could be used instead.
Bernd