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