Messages in this thread | | | Date | Fri, 29 Apr 2022 13:36:23 -0700 | Subject | [RFC PATCH 00/21] KCFI support | From | Sami Tolvanen <> |
| |
KCFI is a proposed forward-edge control-flow integrity scheme for Clang, which is more suitable for kernel use than the existing CFI scheme used by CONFIG_CFI_CLANG. KCFI doesn't require LTO, doesn't alter function references to point to a jump table, and won't break function address equality. The latest LLVM patches are here:
https://reviews.llvm.org/D119296 https://reviews.llvm.org/D124211
This RFC series replaces the current arm64 CFI implementation with KCFI and adds support for x86_64.
The proposed compiler patches add a built-in function that allows CFI checks to be disabled for specific indirect calls. This is necessary to prevent unnecessary checks from being emitted for static_call trampoline calls that are later patched into direct calls. However, as the call expression must be passed as an argument to the built-in, this requires changing the static_call macro API to include the call arguments. Patch 14 changes the macros to accept arguments and patch 15 disables checks for the generated calls.
KCFI also requires assembly functions that are indirectly called from C code to be annotated with type identifiers. As type information is only available in C, the compiler emits expected type identifiers into the symbol table, so they can be referenced from assembly without having to hardcode type hashes. Patch 7 adds helper macros for annotating functions, and patches 8 and 18 add annotations.
In case of a type mismatch, KCFI always traps. To support error handling, the compiler generates a .kcfi_traps section that contains the locations of each trap. Patches 9 and 21 add arch-specific error handlers. In addition, to support x86_64, objtool must be able to identify KCFI type identifiers that are emitted before function entries. The compiler generates an additional .kcfi_types section, which points to each emitted type identifier. Patch 16 adds objtool support.
To test this series, you'll need to compile your own Clang toolchain with the patches linked above. You can also find the complete source tree here:
https://github.com/samitolvanen/llvm-project/commits/kcfi-rfc
This series is also available in GitHub:
https://github.com/samitolvanen/linux/commits/kcfi-rfc
Sami Tolvanen (21): efi/libstub: Filter out CC_FLAGS_CFI arm64/vdso: Filter out CC_FLAGS_CFI kallsyms: Ignore __kcfi_typeid_ cfi: Remove CONFIG_CFI_CLANG_SHADOW cfi: Drop __CFI_ADDRESSABLE cfi: Switch to -fsanitize=kcfi cfi: Add type helper macros arm64/crypto: Add types to indirect called assembly functions arm64: Add CFI error handling treewide: Drop function_nocfi treewide: Drop WARN_ON_FUNCTION_MISMATCH treewide: Drop __cficanonical cfi: Add the cfi_unchecked macro treewide: static_call: Pass call arguments to the macro static_call: Use cfi_unchecked objtool: Add support for CONFIG_CFI_CLANG x86/tools/relocs: Ignore __kcfi_typeid_ relocations x86: Add types to indirect called assembly functions x86/purgatory: Disable CFI x86/vdso: Disable CFI x86: Add support for CONFIG_CFI_CLANG
Makefile | 13 +- arch/Kconfig | 18 +- arch/arm/include/asm/paravirt.h | 2 +- arch/arm64/crypto/ghash-ce-core.S | 5 +- arch/arm64/crypto/sm3-ce-core.S | 3 +- arch/arm64/include/asm/brk-imm.h | 2 + arch/arm64/include/asm/compiler.h | 16 - arch/arm64/include/asm/ftrace.h | 2 +- arch/arm64/include/asm/insn.h | 1 + arch/arm64/include/asm/mmu_context.h | 2 +- arch/arm64/include/asm/paravirt.h | 2 +- arch/arm64/kernel/acpi_parking_protocol.c | 2 +- arch/arm64/kernel/cpufeature.c | 2 +- arch/arm64/kernel/ftrace.c | 2 +- arch/arm64/kernel/machine_kexec.c | 2 +- arch/arm64/kernel/psci.c | 2 +- arch/arm64/kernel/smp_spin_table.c | 2 +- arch/arm64/kernel/traps.c | 57 ++++ arch/arm64/kernel/vdso/Makefile | 3 +- arch/x86/Kconfig | 1 + arch/x86/crypto/aesni-intel_glue.c | 7 +- arch/x86/crypto/blowfish-x86_64-asm_64.S | 5 +- arch/x86/entry/vdso/Makefile | 3 +- arch/x86/events/core.c | 40 +-- arch/x86/include/asm/kvm_host.h | 6 +- arch/x86/include/asm/linkage.h | 7 + arch/x86/include/asm/paravirt.h | 4 +- arch/x86/kernel/traps.c | 39 ++- arch/x86/kvm/cpuid.c | 2 +- arch/x86/kvm/hyperv.c | 4 +- arch/x86/kvm/irq.c | 2 +- arch/x86/kvm/kvm_cache_regs.h | 10 +- arch/x86/kvm/lapic.c | 32 +- arch/x86/kvm/mmu.h | 4 +- arch/x86/kvm/mmu/mmu.c | 8 +- arch/x86/kvm/mmu/spte.c | 4 +- arch/x86/kvm/pmu.c | 4 +- arch/x86/kvm/trace.h | 4 +- arch/x86/kvm/x86.c | 326 ++++++++++----------- arch/x86/kvm/x86.h | 4 +- arch/x86/kvm/xen.c | 4 +- arch/x86/lib/memcpy_64.S | 3 +- arch/x86/purgatory/Makefile | 4 + arch/x86/tools/relocs.c | 1 + drivers/cpufreq/amd-pstate.c | 8 +- drivers/firmware/efi/libstub/Makefile | 2 + drivers/firmware/psci/psci.c | 4 +- drivers/misc/lkdtm/usercopy.c | 2 +- include/asm-generic/bug.h | 16 - include/asm-generic/vmlinux.lds.h | 38 +-- include/linux/cfi.h | 50 ++-- include/linux/cfi_types.h | 57 ++++ include/linux/compiler-clang.h | 10 +- include/linux/compiler.h | 16 +- include/linux/compiler_types.h | 4 +- include/linux/entry-common.h | 2 +- include/linux/init.h | 4 +- include/linux/kernel.h | 2 +- include/linux/module.h | 8 +- include/linux/pci.h | 4 +- include/linux/perf_event.h | 6 +- include/linux/sched.h | 2 +- include/linux/static_call.h | 18 +- include/linux/static_call_types.h | 13 +- include/linux/tracepoint.h | 2 +- kernel/cfi.c | 340 ++++------------------ kernel/kthread.c | 3 +- kernel/module.c | 49 +--- kernel/static_call_inline.c | 2 +- kernel/trace/bpf_trace.c | 2 +- kernel/workqueue.c | 2 +- scripts/Makefile.build | 3 +- scripts/kallsyms.c | 1 + scripts/link-vmlinux.sh | 3 + scripts/module.lds.S | 24 +- security/keys/trusted-keys/trusted_core.c | 14 +- tools/include/linux/static_call_types.h | 13 +- tools/objtool/arch/x86/include/arch/elf.h | 2 + tools/objtool/builtin-check.c | 3 +- tools/objtool/check.c | 128 +++++++- tools/objtool/elf.c | 13 + tools/objtool/include/objtool/arch.h | 1 + tools/objtool/include/objtool/builtin.h | 2 +- tools/objtool/include/objtool/elf.h | 2 + 84 files changed, 748 insertions(+), 793 deletions(-) create mode 100644 include/linux/cfi_types.h
-- 2.36.0.464.gb9c8b46e94-goog
| |