Control Flow Intergreity (CFI) Schemes

Prologue

I document these points when I learn CFI related materials.

kCFI

kCFI is a Control-Flow Integrity implementation for the Linux kernel not hardware support is required.

The following config would enable it:

./scripts/config -e CFI_CLANG
./scripts/config -d CFI_PERMISSIVE

make LLVM=1 LD=ld.lld olddefconfig
make LLVM=1 LD=ld.lld -j"$(nproc)"

Example

When we do forward controlflow changing (e.g., call/jmp), it checks the hash (4 bytes before the function, generated during compilation).

   0xffffffff8201b8c5 <sock_common_setsockopt+21>    mov    r10d, 0xaddc65c5                R10D => 0xaddc65c5
   0xffffffff8201b8cb <sock_common_setsockopt+27>    add    r10d, dword ptr [r11 - 4]
   0xffffffff8201b8cf <sock_common_setsockopt+31>    je     0xffffffff8201b8d3          <sock_common_setsockopt+35>

Crash

[    3.846651] CFI failure at sock_common_setsockopt+0x21/0x30 (target: br_dev_set_multicast_list+0x9/0x10; expected t)
[    3.847431] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
[    3.847719] CPU: 0 PID: 172 Comm: exploit Not tainted 6.1.36 #4
[    3.848034] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.or4
[    3.848607] RIP: 0010:sock_common_setsockopt+0x21/0x30
[    3.848890] Code: 90 90 90 90 b8 ba b0 f6 94 f3 0f 1e fa 0f

IBT

IBT reuqires hardware support which checks if the next instruction is “ENDBR64”(“ENDBR32” for i386).

The hardware support requires CPU support ibt:

cat /proc/cpuinfo| grep ibt

The software support requires the kernel have

CONFIG_X86_CET=y
CONFIG_X86_KERNEL_IBT=y