Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CFI: Add support for gcc CFI in aarch64
Based on Sami's patch[1], this patch makes the corresponding kernel configuration of CFI available when compiling the kernel with the gcc[2]. The code after enabling cfi is as follows: int (*p)(void); int func (int) { p(); } __cfi_func: .4byte 0x439d3502 func: ...... adrp x0, p add x0, x0, :lo12:p mov w1, 23592 movk w1, 0x4601, lsl 16 cmp w0, w1 beq .L2 ...... bl cfi_check_failed .L2: blr x19 ret In the compiler part[4], there are some differences from Sami's implementation[3], mainly including: 1. When a typeid mismatch is detected, the cfi_check_failed function will be called instead of the brk instruction. This function needs to be implemented by the compiler user. If there are user mode programs or other systems that want to use this feature, it may be more convenient to use a callback (so this compilation option is set to -fsanitize=cfi instead of kcfi). 2. A reserved typeid (such as 0x0U on the aarch64 platform) is always inserted in front of functions that should not be called indirectly. Functions that can be called indirectly will not use this hash value, which prevents instructions/data before the function from being used as a typeid by an attacker. 3. Some bits are ignored in the typeid to avoid conflicts between the typeid and the instruction set of a specific platform, thereby preventing an attacker from bypassing the CFI check by using the instruction as a typeid, such as on the aarch64 platform: * If the following instruction sequence exists: 400620: a9be7bfd stp x29, x30, [sp, #-32]! 400624: 910003fd mov x29, sp 400628: f9000bf3 str x19, [sp, torvalds#16] * If the expected typeid of the indirect call is exactly 0x910003fd, the attacker can jump to the next instruction position of any "mov x29,sp" instruction (such as 0x400628 here). 4. Insert a symbol __cfi_<function> before each function's typeid, which may be helpful for fine-grained KASLR implementations (or not?). 5. The current implementation of gcc only supports the aarch64 platform. This produces the following oops on CFI failure (generated using lkdtm): /kselftest_install/lkdtm # ./CFI_FORWARD_PROTO.sh [ 74.856516] lkdtm: Performing direct entry CFI_FORWARD_PROTO [ 74.856878] lkdtm: Calling matched prototype ... [ 74.857011] lkdtm: Calling mismatched prototype ... [ 74.857133] CFI failure at lkdtm_indirect_call+0x30/0x50 (target: lkdtm_increment_int+0x0/0x1c; expected type: 0xc59c68f1) [ 74.858185] Kernel panic - not syncing: Oops - CFI [ 74.859240] CPU: 0 PID: 129 Comm: cat Not tainted 6.0.0-rc4-00024-g32bf7f14f497-dirty torvalds#150 [ 74.859481] Hardware name: linux,dummy-virt (DT) [ 74.859795] Call trace: [ 74.859959] dump_backtrace.part.0+0xcc/0xe0 [ 74.860212] show_stack+0x18/0x5c [ 74.860327] dump_stack_lvl+0x64/0x84 [ 74.860398] dump_stack+0x18/0x38 [ 74.860443] panic+0x170/0x36c [ 74.860496] cfi_check_failed+0x38/0x44 [ 74.860564] lkdtm_indirect_call+0x30/0x50 [ 74.860614] lkdtm_CFI_FORWARD_PROTO+0x3c/0x6c [ 74.860701] lkdtm_do_action+0x44/0x58 [ 74.860764] direct_entry+0x148/0x160 [ 74.860814] full_proxy_write+0x74/0xe0 [ 74.860874] vfs_write+0xd8/0x2d0 [ 74.860942] ksys_write+0x70/0x110 [ 74.861000] __arm64_sys_write+0x1c/0x30 [ 74.861067] invoke_syscall+0x5c/0x140 [ 74.861117] el0_svc_common.constprop.0+0x44/0xf0 [ 74.861190] do_el0_svc+0x2c/0xc0 [ 74.861233] el0_svc+0x20/0x60 [ 74.861287] el0t_64_sync_handler+0xf4/0x124 [ 74.861340] el0t_64_sync+0x160/0x164 [ 74.861782] SMP: stopping secondary CPUs [ 74.862336] Kernel Offset: disabled [ 74.862439] CPU features: 0x0000,00075024,699418af [ 74.862799] Memory Limit: none [ 74.863373] ---[ end Kernel panic - not syncing: Oops - CFI ]--- The gcc-related patches[4] are based on tag: releases/gcc-12.2.0. Any suggestion please let me know :). Thanks, Dan. [1] https://lore.kernel.org/all/20220908215504.3686827-1-samitolvanen@google.com/ [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107048 [3] https://reviews.llvm.org/D119296 [4] https://lore.kernel.org/linux-hardening/20221219055431.22596-1-ashimida.1990@gmail.com/ Signed-off-by: Dan Li <ashimida.1990@gmail.com>
- Loading branch information