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