Re: [RFC][PATCH 6/6] objtool: Add IBT validation / fixups

From: Fāng-ruì Sòng
Date: Wed Jun 08 2022 - 13:53:59 EST


Hi Peter,

On Tue, Mar 1, 2022 at 7:06 PM Peter Collingbourne <pcc@xxxxxxxxxx> 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.

Do you mind elaborating how this instruction can be used as a gadget?
How does it look like?

The information will be useful to the summary of Sami's KCFI LLVM
patch: https://reviews.llvm.org/D119296

> > 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.
>
> Peter
>


--
宋方睿