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
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
On 22/04/29 01:36PM, Sami Tolvanen wrote: > 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 Many thanks for continuing to work on this! As a user who has been following the evolution of this patch series for a while now, I have a couple of burning questions: 1) The LLVM patch says that kCFI is not compatible with execute-only memory. Is there a plan ahead for kCFI if and when execute-only memory is implemented? 2) kCFI only checks indirect calls while Clang's traditional CFI has more schemes like bad cast checking and so on. Are there any major security tradeoffs as a result of this? V/R Kenton Groombridge
On Sat, Apr 30, 2022 at 9:08 AM Kenton Groombridge <me@concord.sh> wrote: > Many thanks for continuing to work on this! As a user who has been > following the evolution of this patch series for a while now, I have a > couple of burning questions: > > 1) The LLVM patch says that kCFI is not compatible with execute-only > memory. Is there a plan ahead for kCFI if and when execute-only memory > is implemented? There's no plan for executable-only memory right now, that would require type hashes to be moved somewhere else to read-only memory. > 2) kCFI only checks indirect calls while Clang's traditional CFI has > more schemes like bad cast checking and so on. Are there any major > security tradeoffs as a result of this? No, cfi-icall is only scheme that's relevant for the kernel. The other schemes implemented in Clang are mostly useful for C++. Sami
On Fri, Apr 29, 2022 at 01:36:23PM -0700, Sami Tolvanen wrote: > 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 > > [...] > 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 And note that this RFC is seeking to break a bit of a circular dependency with regard to the design of __builtin_kcfi_call_unchecked (D124211 above), as the implementation has gone around a few times in review within LLVM, and we want to make sure that kernel folks are okay with what was settled on. If there are no objections on the kernel side, then we can land the KCFI patches, as this is basically the only remaining blocker. -Kees -- Kees Cook
On Fri, Apr 29, 2022 at 03:53:12PM -0700, Kees Cook wrote: > On Fri, Apr 29, 2022 at 01:36:23PM -0700, Sami Tolvanen wrote: > > 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 > > > > [...] > > 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 > > And note that this RFC is seeking to break a bit of a circular dependency > with regard to the design of __builtin_kcfi_call_unchecked (D124211 > above), as the implementation has gone around a few times in review within > LLVM, and we want to make sure that kernel folks are okay with what was > settled on. If there are no objections on the kernel side, then we can > land the KCFI patches, as this is basically the only remaining blocker. So aside from the static_call usage, was there any other? Anyway, I think I hate that __builtin, I'd *much* rather see a variable attribute or qualifier for this, such that one can mark a function pointer as not doing CFI. I simply doesn't make sense to have a builtin that operates on an expression. The whole thing is about indirect calls, IOW function pointers.
On Sat, Apr 30, 2022 at 2:02 AM Peter Zijlstra <peterz@infradead.org> wrote: > > On Fri, Apr 29, 2022 at 03:53:12PM -0700, Kees Cook wrote: > > On Fri, Apr 29, 2022 at 01:36:23PM -0700, Sami Tolvanen wrote: > > > 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 > > > > > > [...] > > > 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 > > > > And note that this RFC is seeking to break a bit of a circular dependency > > with regard to the design of __builtin_kcfi_call_unchecked (D124211 > > above), as the implementation has gone around a few times in review within > > LLVM, and we want to make sure that kernel folks are okay with what was > > settled on. If there are no objections on the kernel side, then we can > > land the KCFI patches, as this is basically the only remaining blocker. > > So aside from the static_call usage, was there any other? Not at the moment, and it looks like we can get rid of that too. > Anyway, I think I hate that __builtin, I'd *much* rather see a variable > attribute or qualifier for this, such that one can mark a function > pointer as not doing CFI. > > I simply doesn't make sense to have a builtin that operates on an > expression. The whole thing is about indirect calls, IOW function > pointers. I also thought an attribute would be more convenient, but the compiler folks prefer a built-in: https://reviews.llvm.org/D122673 Sami
On Mon, May 02, 2022 at 08:22:57AM -0700, Sami Tolvanen wrote: > > Anyway, I think I hate that __builtin, I'd *much* rather see a variable > > attribute or qualifier for this, such that one can mark a function > > pointer as not doing CFI. > > > > I simply doesn't make sense to have a builtin that operates on an > > expression. The whole thing is about indirect calls, IOW function > > pointers. > > I also thought an attribute would be more convenient, but the compiler > folks prefer a built-in: > > https://reviews.llvm.org/D122673 That seems to mostly worry about C++ things (overload sets, template specialization, name mangling) we kernel folks don't seem to much care about. I'll stick with saying type system makes more sense to me though.
On Mon, May 2, 2022 at 1:02 PM Peter Zijlstra <peterz@infradead.org> wrote: > > On Mon, May 02, 2022 at 08:22:57AM -0700, Sami Tolvanen wrote: > > > > Anyway, I think I hate that __builtin, I'd *much* rather see a variable > > > attribute or qualifier for this, such that one can mark a function > > > pointer as not doing CFI. > > > > > > I simply doesn't make sense to have a builtin that operates on an > > > expression. The whole thing is about indirect calls, IOW function > > > pointers. > > > > I also thought an attribute would be more convenient, but the compiler > > folks prefer a built-in: > > > > https://reviews.llvm.org/D122673 > > That seems to mostly worry about C++ things (overload sets, template > specialization, name mangling) we kernel folks don't seem to much care > about. > > I'll stick with saying type system makes more sense to me though. I'd say it's not only the C++ issues but more the "action at a distance" that's implied by having this be part of the type system. With this being in the function type it's hard to tell whether any particular call will have CFI disabled, without needing to go and look at how the function pointer is defined. On the other hand, if we explicitly mark up the calls with CFI disabled, the code becomes easier to audit (think Rust "unsafe" blocks). Does it seem any better to you to have this be marked up via the function expression, rather than the call? The idea is that this would always compile to a check-free function call, no matter what "func" is: __builtin_kcfi_call_unchecked(func)(args) We already have this, to some degree, with KCFI as implemented: CFI checks are disabled if the function expression refers to a declared function. The builtin would allow overriding the decision to also disable CFI checks for function expressions that use the builtin. It also wouldn't preclude a type based system later on (the builtin would become effectively a cast to the "unchecked" type). Peter
On Tue, May 03, 2022 at 03:35:34PM -0700, Peter Collingbourne wrote: > On Mon, May 2, 2022 at 1:02 PM Peter Zijlstra <peterz@infradead.org> wrote: > > > > On Mon, May 02, 2022 at 08:22:57AM -0700, Sami Tolvanen wrote: > > > > > > Anyway, I think I hate that __builtin, I'd *much* rather see a variable > > > > attribute or qualifier for this, such that one can mark a function > > > > pointer as not doing CFI. > > > > > > > > I simply doesn't make sense to have a builtin that operates on an > > > > expression. The whole thing is about indirect calls, IOW function > > > > pointers. > > > > > > I also thought an attribute would be more convenient, but the compiler > > > folks prefer a built-in: > > > > > > https://reviews.llvm.org/D122673 > > > > That seems to mostly worry about C++ things (overload sets, template > > specialization, name mangling) we kernel folks don't seem to much care > > about. > > > > I'll stick with saying type system makes more sense to me though. > > I'd say it's not only the C++ issues but more the "action at a > distance" that's implied by having this be part of the type system. > With this being in the function type it's hard to tell whether any > particular call will have CFI disabled, without needing to go and look > at how the function pointer is defined. Look at how we use volatile: *(volatile int *)(&foo) we don't use volatile on actual variable definitions (much), but instead cast it in at the usage site. Same can be done with this if so desired. > On the other hand, if we > explicitly mark up the calls with CFI disabled, the code becomes > easier to audit (think Rust "unsafe" blocks). I don't know any Rust. To me Rust still looks like line noise. > Does it seem any better to you to have this be marked up via the > function expression, rather than the call? The idea is that this would > always compile to a check-free function call, no matter what "func" > is: > > __builtin_kcfi_call_unchecked(func)(args) > > We already have this, to some degree, with KCFI as implemented: CFI > checks are disabled if the function expression refers to a declared > function. The builtin would allow overriding the decision to also > disable CFI checks for function expressions that use the builtin. It > also wouldn't preclude a type based system later on (the builtin would > become effectively a cast to the "unchecked" type). That's still a bit naf; you've effectively made that builtin a type-cast.
Hi Sami,
On Fri, Apr 29, 2022 at 01:36:23PM -0700, Sami Tolvanen wrote:
> 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 is really exciting to see!
I wanted to give this a spin on arm64, but I'm seeing some very odd toolchain
behaviour. I'm not sure if I've done something wrong, or if I'm just hitting an
edge-case, but it looks like using -fsanitize=kcfi causes the toolchain to hit
out-of-memory errors and other issues which look like they could be memory
corruption.
Setup-wise:
* My build machine is a "Intel(R) Xeon(R) CPU E5-2660 v4" with 56 HW threads
and 64GB of RAM, running x86_64 Debian 11.3.
* I applied D119296 atop LLVM commit 11d3e31c60bd (per the "Parents" part of
the Revision Contents on https://reviews.llvm.org/D119296), and built that
with:
cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='clang;lld
cmake --build build
Aside: I'll go build a Debug release to compare this to.
* I applied this series atop v5.18-rc4.
* I normally build with -j50, and LLVM=1.
Aside from a single ifdef issue in compiler-clang.h, defconfig builds cleanly,
but defconfig + CONFIG_CFI_CLANG produces lots of out of memory errors and some
other errors which look erroneous. I see a bunch of errors even when I
significantly reduce my build parallelism (e.g. down to -j10, a reduction of
5x).
Some of these don't look right at all, e.g.
| make: *** [Makefile:1823: fs] Error 2
| ^[^[<inline asm>:5:1: error: unexpected token at start of statement
| 93825275602704
| ^
| 1 error generated.
| make[2]: *** [scripts/Makefile.build:289: arch/arm64/kernel/suspend.o] Error 1
| make[2]: *** Waiting for unfinished jobs....
| make[1]: *** [scripts/Makefile.build:551: arch/arm64/kernel] Error 2
| <inline asm>:5:1: error: unexpected token at start of statement
| @<U+001D><U+001A>8DV
| ^
| 1 error generated.
| make[3]: *** [scripts/Makefile.build:289: drivers/phy/amlogic/phy-meson8b-usb2.o] Error 1
| make[3]: *** Waiting for unfinished jobs....
| make[2]: *** [scripts/Makefile.build:551: drivers/phy/amlogic] Error 2
| make[2]: *** Waiting for unfinished jobs....
| make[1]: *** [scripts/Makefile.build:551: kernel/sched] Error 2
| make: *** [Makefile:1823: kernel] Error 2
| make: *** Waiting for unfinished jobs....
... maybe those are due to memory corruption / bad out-of-memory handling?
Some are out-of-memory errors:
| LLVM ERROR: out of memory
| Allocation failed
| PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
| Stack dump:
| 0. Program arguments: clang -Wp,-MMD,kernel/dma/.pool.o.d -nostdinc -I./arch/arm64/include -I./arch/arm64/include/generated -I./include -I./arch/arm64/include/uapi -I./arch/arm64/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -mlittle-endian -DKASAN_SHADOW_SCALE_SHIFT= -Qunused-arguments -fmacro-prefix-map=./= -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Wno-format-security -std=gnu11 --target=aarch64-linux-gnu -fintegrated-as -Werror=unknown-warning-option -Werror=ignored-optimization-argument -mgeneral-regs-only -DCONFIG_CC_HAS_K_CONSTRAINT=1 -Wno-psabi -fno-asynchronous-unwind-tables -fno-unwind-tables -mbranch-protection=pac-ret+leaf+bti -Wa,-march=armv8.5-a -DARM64_ASM_ARCH=\"armv8.5-a\" -DKASAN_SHADOW_SCALE_SHIFT= -fno-delete-null-pointer-checks -Wno-frame-address -Wno-address-of-packed-member -O2 -Wframe-larger-than=2048 -fstack-protector-strong -Wimplicit-fallthrough -Wno-gnu -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -fno-stack-clash-protection -fsanitize=kcfi -fno-sanitize-blacklist -Wdeclaration-after-statement -Wvla -Wno-pointer-sign -Wcast-function-type -fno-strict-overflow -fno-stack-check -Werror=date-time -Werror=incompatible-pointer-types -Wno-initializer-overrides -Wno-format -Wno-sign-compare -Wno-format-zero-length -Wno-pointer-to-enum-cast -Wno-tautological-constant-out-of-range-compare -Wno-unaligned-access -mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=1184 -DKBUILD_MODFILE=\"kernel/dma/pool\" -DKBUILD_BASENAME=\"pool\" -DKBUILD_MODNAME=\"pool\" -D__KBUILD_MODNAME=kmod_pool -c -o kernel/dma/pool.o kernel/dma/pool.c
| 1. <eof> parser at end of file
| 2. Per-file LLVM IR generation
| #0 0x00005559ef670830 PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
| #1 0x00005559ef66e6e4 llvm::sys::CleanupOnSignal(unsigned long) (/home/mark/src/llvm-project/build/bin/clang-15+0x36136e4)
| #2 0x00005559ef5ab3f8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
| #3 0x00007f5ac3547140 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14140)
| #4 0x00007f5ac302ace1 raise (/lib/x86_64-linux-gnu/libc.so.6+0x3bce1)
| #5 0x00007f5ac3014537 abort (/lib/x86_64-linux-gnu/libc.so.6+0x25537)
| #6 0x00005559ef5b2389 (/home/mark/src/llvm-project/build/bin/clang-15+0x3557389)
| #7 0x00005559ef5e00f7 (/home/mark/src/llvm-project/build/bin/clang-15+0x35850f7)
| #8 0x00005559ef641191 llvm::raw_svector_ostream::write_impl(char const*, unsigned long) (/home/mark/src/llvm-project/build/bin/clang-15+0x35e6191)
| #9 0x00005559ef64325e llvm::raw_ostream::write(char const*, unsigned long) (/home/mark/src/llvm-project/build/bin/clang-15+0x35e825e)
| #10 0x00005559ef611dae llvm::Twine::str[abi:cxx11]() const (/home/mark/src/llvm-project/build/bin/clang-15+0x35b6dae)
| #11 0x00005559efac97be clang::CodeGen::CodeGenModule::FinalizeKCFITypePrefixes() (/home/mark/src/llvm-project/build/bin/clang-15+0x3a6e7be)
| #12 0x00005559efafd53c clang::CodeGen::CodeGenModule::Release() (/home/mark/src/llvm-project/build/bin/clang-15+0x3aa253c)
| #13 0x00005559f07564aa (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
| #14 0x00005559f07543e5 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/mark/src/llvm-project/build/bin/clang-15+0x46f93e5)
| #15 0x00005559f11b85a9 clang::ParseAST(clang::Sema&, bool, bool) (/home/mark/src/llvm-project/build/bin/clang-15+0x515d5a9)
| #16 0x00005559f00cf419 clang::FrontendAction::Execute() (/home/mark/src/llvm-project/build/bin/clang-15+0x4074419)
| #17 0x00005559f005a85b clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/mark/src/llvm-project/build/bin/clang-15+0x3fff85b)
| #18 0x00005559f0183860 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/mark/src/llvm-project/build/bin/clang-15+0x4128860)
| #19 0x00005559ed0f051c cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/mark/src/llvm-project/build/bin/clang-15+0x109551c)
| #20 0x00005559ed0ed3f9 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
| #21 0x00005559efed5fa5 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::'lambda'()>(long) Job.cpp:0:0
| #22 0x00005559ef5ab4f3 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/mark/src/llvm-project/build/bin/clang-15+0x35504f3)
| #23 0x00005559efed6304 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (.part.0) Job.cpp:0:0
| #24 0x00005559efea7b36 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/mark/src/llvm-project/build/bin/clang-15+0x3e4cb36)
| #25 0x00005559efea84e9 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/mark/src/llvm-project/build/bin/clang-15+0x3e4d4e9)
| #26 0x00005559efeb6619 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/mark/src/llvm-project/build/bin/clang-15+0x3e5b619)
| #27 0x00005559ed033793 main (/home/mark/src/llvm-project/build/bin/clang-15+0xfd8793)
| #28 0x00007f5ac3015d0a __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d0a)
| #29 0x00005559ed0ecdaa _start (/home/mark/src/llvm-project/build/bin/clang-15+0x1091daa)
| clang-15: error: clang frontend command failed with exit code 134 (use -v to see invocation)
| clang version 15.0.0 (https://github.com/llvm/llvm-project.git 1e3994ce3cd7b217678edd589392c3c3c1575880)
| Target: aarch64-unknown-linux-gnu
| Thread model: posix
| InstalledDir: /home/mark/src/llvm-project/build/bin
| clang-15: note: diagnostic msg:
| ********************
|
| PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
| Preprocessed source(s) and associated run script(s) are located at:
| clang-15: note: diagnostic msg: /tmp/pool-b4bab3.c
| clang-15: note: diagnostic msg: /tmp/pool-b4bab3.sh
| clang-15: note: diagnostic msg:
|
| ********************
| make[2]: *** [scripts/Makefile.build:289: kernel/dma/pool.o] Error 134
| make[1]: *** [scripts/Makefile.build:551: kernel/dma] Error 2
| make[1]: *** Waiting for unfinished jobs....
Note: I've kept those files, but as the c file is 3.9M I have not included that here.
There appar to be other failures too:
| [mark@lakrids:~/src/linux]% PATH=/home/mark/src/llvm-project/build/bin/:$PATH make LLVM=1 ARCH=arm64 -j10 Image -s
| PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
| Stack dump:
| 0. Program arguments: clang -Wp,-MMD,mm/.util.o.d -nostdinc -I./arch/arm64/include -I./arch/arm64/include/generated -I./include -I./arch/arm64/include/uapi -I./arch/arm64/include/generated/uapi -I./i
| nclude/uapi -I./include/generated/uapi -include ./include/linux/compiler-version.h -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -mlittle-endian -DKASAN_SHADOW_SCALE_SHIFT= -Qunused-arguments -fmacro-prefix-map=./= -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Wno-format-security -std=gnu11 --target=aarch64-linux-gnu -fintegrated-as -Werror=unknown-warning-option -Werror=ignored-optimization-argument -mgeneral-regs-only -DCONFIG_CC_HAS_K_CONSTRAINT=1 -Wno-psabi -fno-asynchronous-unwind-tables -fno-unwind-tables -mbranch-protection=pac-ret+leaf+bti -Wa,-march=armv8.5-a -DARM64_ASM_ARCH=\"armv8.5-a\" -DKASAN_SHADOW_SCALE_SHIFT= -fno-delete-null-pointer-checks -Wno-frame-address -Wno-address-of-packed-member -O2 -Wframe-larger-than=2048 -fstack-protector-strong -Wimplicit-fallthrough -Wno-gnu -Wno-unused-but-set-variable -Wno-unused-const-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -fno-stack-clash-protection -fsanitize=kcfi -fno-sanitize-blacklist -Wdeclaration-after-statement -Wvla -Wno-pointer-sign -Wcast-function-type -fno-strict-overflow -fno-stack-check -Werror=date-time -Werror=incompatible-pointer-types -Wno-initializer-overrides -Wno-format -Wno-sign-compare -Wno-format-zero-length -Wno-pointer-to-enum-cast -Wno-tautological-constant-out-of-range-compare -Wno-unaligned-access -mstack-protector-guard=sysreg -mstack-protector-guard-reg=sp_el0 -mstack-protector-guard-offset=1184 -DKBUILD_MODFILE=\"mm/util\" -DKBUILD_BASENAME=\"util\" -DKBUILD_MODNAME=\"util\" -D__KBUILD_MODNAME=kmod_util -c -o mm/util.o mm/util.c
| 1. <eof> parser at end of file
| 2. Per-file LLVM IR generation
| #0 0x0000559484667830 PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
| #1 0x00005594846656e4 llvm::sys::CleanupOnSignal(unsigned long) (/home/mark/src/llvm-project/build/bin/clang-15+0x36136e4)
| #2 0x00005594845a23f8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
| #3 0x00007f490bbd1140 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14140)
| #4 0x0000559484608ca8 llvm::Twine::printOneChild(llvm::raw_ostream&, llvm::Twine::Child, llvm::Twine::NodeKind) const (/home/mark/src/llvm-project/build/bin/clang-15+0x35b6ca8)
| #5 0x0000559484608dae llvm::Twine::str[abi:cxx11]() const (/home/mark/src/llvm-project/build/bin/clang-15+0x35b6dae)
| #6 0x0000559484ac07be clang::CodeGen::CodeGenModule::FinalizeKCFITypePrefixes() (/home/mark/src/llvm-project/build/bin/clang-15+0x3a6e7be)
| #7 0x0000559484af453c clang::CodeGen::CodeGenModule::Release() (/home/mark/src/llvm-project/build/bin/clang-15+0x3aa253c)
| #8 0x000055948574d4aa (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
| #9 0x000055948574b3e5 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/mark/src/llvm-project/build/bin/clang-15+0x46f93e5)
| #10 0x00005594861af5a9 clang::ParseAST(clang::Sema&, bool, bool) (/home/mark/src/llvm-project/build/bin/clang-15+0x515d5a9)
| #11 0x00005594850c6419 clang::FrontendAction::Execute() (/home/mark/src/llvm-project/build/bin/clang-15+0x4074419)
| #12 0x000055948505185b clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/mark/src/llvm-project/build/bin/clang-15+0x3fff85b)
| #13 0x000055948517a860 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/mark/src/llvm-project/build/bin/clang-15+0x4128860)
| #14 0x00005594820e751c cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/mark/src/llvm-project/build/bin/clang-15+0x109551c)
| #15 0x00005594820e43f9 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) driver.cpp:0:0
| #16 0x0000559484eccfa5 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::'lambda'()>(long) Job.cpp:0:0
| #17 0x00005594845a24f3 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/mark/src/llvm-project/build/bin/clang-15+0x35504f3)
| #18 0x0000559484ecd304 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const (.part.0) Job.cpp:0:0
| #19 0x0000559484e9eb36 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const (/home/mark/src/llvm-project/build/bin/clang-15+0x3e4cb36)
| #20 0x0000559484e9f4e9 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) const (/home/mark/src/llvm-project/build/bin/clang-15+0x3e4d4e9)
| #21 0x0000559484ead619 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) (/home/mark/src/llvm-project/build/bin/clang-15+0x3e5b619)
| #22 0x000055948202a793 main (/home/mark/src/llvm-project/build/bin/clang-15+0xfd8793)
| #23 0x00007f490b69fd0a __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26d0a)
| #24 0x00005594820e3daa _start (/home/mark/src/llvm-project/build/bin/clang-15+0x1091daa)
| clang-15: error: clang frontend command failed with exit code 135 (use -v to see invocation)
| clang version 15.0.0 (https://github.com/llvm/llvm-project.git 1e3994ce3cd7b217678edd589392c3c3c1575880)
| Target: aarch64-unknown-linux-gnu
| Thread model: posix
| InstalledDir: /home/mark/src/llvm-project/build/bin
| clang-15: note: diagnostic msg:
| ********************
|
| PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
| Preprocessed source(s) and associated run script(s) are located at:
| clang-15: note: diagnostic msg: /tmp/util-30a0f2.c
| clang-15: note: diagnostic msg: /tmp/util-30a0f2.sh
| clang-15: note: diagnostic msg:
|
| ********************
Note: I've saved those files for now, but the c file is 4.8M, so I haven't included it
inline or attached it here.
Thanks,
Mark.
Hi Mark, On Wed, May 4, 2022 at 9:18 AM Mark Rutland <mark.rutland@arm.com> wrote: > I wanted to give this a spin on arm64, but I'm seeing some very odd toolchain > behaviour. I'm not sure if I've done something wrong, or if I'm just hitting an > edge-case, but it looks like using -fsanitize=kcfi causes the toolchain to hit > out-of-memory errors and other issues which look like they could be memory > corruption. Thanks for the detailed bug report! It definitely looks like something is wrong with the recent switch from std::string to Twine in the Clang code. I didn't see this issue when compiling the arm64 kernel, but I'll take a closer look and see if I can reproduce it. Sami
On Wed, May 4, 2022 at 9:41 AM Sami Tolvanen <samitolvanen@google.com> wrote: > > Hi Mark, > > On Wed, May 4, 2022 at 9:18 AM Mark Rutland <mark.rutland@arm.com> wrote: > > I wanted to give this a spin on arm64, but I'm seeing some very odd toolchain > > behaviour. I'm not sure if I've done something wrong, or if I'm just hitting an > > edge-case, but it looks like using -fsanitize=kcfi causes the toolchain to hit > > out-of-memory errors and other issues which look like they could be memory > > corruption. > > Thanks for the detailed bug report! It definitely looks like something > is wrong with the recent switch from std::string to Twine in the Clang > code. I didn't see this issue when compiling the arm64 kernel, but > I'll take a closer look and see if I can reproduce it. I was able to reproduce this by turning off assertions in Clang. It seems to work fine with -DLLVM_ENABLE_ASSERTIONS=ON. I'll go fix. Sami
On Wed, May 04, 2022 at 01:17:25PM -0700, Sami Tolvanen wrote: > On Wed, May 4, 2022 at 9:41 AM Sami Tolvanen <samitolvanen@google.com> wrote: > > > > Hi Mark, > > > > On Wed, May 4, 2022 at 9:18 AM Mark Rutland <mark.rutland@arm.com> wrote: > > > I wanted to give this a spin on arm64, but I'm seeing some very odd toolchain > > > behaviour. I'm not sure if I've done something wrong, or if I'm just hitting an > > > edge-case, but it looks like using -fsanitize=kcfi causes the toolchain to hit > > > out-of-memory errors and other issues which look like they could be memory > > > corruption. > > > > Thanks for the detailed bug report! It definitely looks like something > > is wrong with the recent switch from std::string to Twine in the Clang > > code. I didn't see this issue when compiling the arm64 kernel, but > > I'll take a closer look and see if I can reproduce it. > > I was able to reproduce this by turning off assertions in Clang. It > seems to work fine with -DLLVM_ENABLE_ASSERTIONS=ON. I'll go fix. FWIW, a `-DLLVM_ENABLE_ASSERTIONS=ON` build also seems to work for me when building a kernel with CONFIG_CFI_CLANG=y. It's much slower than a regular Release build, so I'm still waiting for that to finish building a kernel, but it has gotten much further through the build without issues. Thanks, Mark.
On Thu, May 5, 2022 at 5:36 AM Mark Rutland <mark.rutland@arm.com> wrote: > FWIW, a `-DLLVM_ENABLE_ASSERTIONS=ON` build also seems to work for me when > building a kernel with CONFIG_CFI_CLANG=y. It's much slower than a regular > Release build, so I'm still waiting for that to finish building a kernel, but > it has gotten much further through the build without issues. Thanks for confirming. This issue should be fixed here if you want to give it another try: https://github.com/samitolvanen/llvm-project/commits/kcfi Sami
On Thu, May 05, 2022 at 09:00:39AM -0700, Sami Tolvanen wrote: > On Thu, May 5, 2022 at 5:36 AM Mark Rutland <mark.rutland@arm.com> wrote: > > FWIW, a `-DLLVM_ENABLE_ASSERTIONS=ON` build also seems to work for me when > > building a kernel with CONFIG_CFI_CLANG=y. It's much slower than a regular > > Release build, so I'm still waiting for that to finish building a kernel, but > > it has gotten much further through the build without issues. > > Thanks for confirming. This issue should be fixed here if you want to > give it another try: > > https://github.com/samitolvanen/llvm-project/commits/kcfi That works for me, building in Release mode. A defconfig + CFI_CLANG kernel built with that builds and boots clenaly. Thanks! Mark.
© 2016 - 2026 Red Hat, Inc.