Messages in this thread | | | Date | Tue, 01 Mar 2022 19:32:47 -0800 | From | Joao Moreira <> | Subject | Re: [RFC][PATCH 6/6] objtool: Add IBT validation / fixups |
| |
On 2022-03-01 19:06, Peter Collingbourne wrote: > Hi Peter, > > One issue with this call sequence is that: > > On Fri, Feb 11, 2022 at 02:38:03PM +0100, Peter Zijlstra wrote: >> caller: >> cmpl $0xdeadbeef, -0x4(%rax) # 7 bytes > > Because this instruction ends in the constant 0xdeadbeef, it may > be used as a "gadget" that would effectively allow branching to an > arbitrary address in %rax if the attacker can arrange to set ZF=1. > >> je 1f # 2 bytes >> ud2 # 2 bytes >> 1: call __x86_indirect_thunk_rax # 5 bytes >> >> >> .align 16 >> .byte 0xef, 0xbe, 0xad, 0xde # 4 bytes >> func: >> endbr # 4 bytes >> ... >> ret > > I think we can avoid this problem with a slight tweak to your > instruction sequence, at the cost of 2 bytes per function prologue. > First, change the call sequence like so: > > cmpl $0xdeadbeef, -0x6(%rax) # 6 bytes > je 1f # 2 bytes > ud2 # 2 bytes > 1: call __x86_indirect_thunk_rax # 5 bytes > > The key difference is that we've changed 0x4 to 0x6. > > Then change the function prologue to this: > > .align 16 > .byte 0xef, 0xbe, 0xad, 0xde # 4 bytes > .zero 2 # 2 bytes > func: > > The end result of the above is that the constant embedded in the cmpl > instruction may only be used to reach the following ud2 instruction, > which will "harmlessly" terminate execution in the same way as if > the prologue signature did not match.
FWIIW, this makes sense IMHO. These additional pre-prologue bytes are also what might be needed to enable the smaller version of FineIBT that I suggested in this thread some time ago.
| |