CFI: asan.module_ctor is missing a type hash
samitolvanen opened this issue · 9 comments
From Mark Rutland:
Looks like CFI && KASAN is borked on both arm64 and x86; the implicitly-generated asan.module_ctor functions aren't given a type hash by the compiler, so when those get invoked by do_ctors() the calls fail
The asan.module_ctor
function is created in the asan
LLVM pass using createSanitizerCtor
. Since this happens outside of Clang, it's a bit awkward to generate a type hash for the function at this point.
The reason we didn't have this problem earlier was that do_ctors
is an __init
function and CFI was disabled for it. I'm leaning towards simply marking the function __nocfi
instead of hardcoding a type hash for these functions or hacking something together in LLVM to compute a hash. Thoughts?
Perhaps setting the types in LLVM is reasonable after all, as we'd have to deal with module constructors as well otherwise. Here's an alternative solution: https://reviews.llvm.org/D138945
The remaining issue with CFI+KASAN is that asan.module_ctor
still won't have a type hash in object files that were not compiled with -fsanitize=kcfi
. With x86/arm64 defconfigs, it looks like only the constructor in kernel/cfi.o
trips KASAN, but I don't see any reason we couldn't now enable CFI also for kernel/cfi.c
.
CFI+KASAN still fails on x86 because asan.module_ctor
doesn't have the same patchable-function-prefix
as the other functions, and KCFI assumes all functions have the same number of prefix nops, as discussed in #1744.
https://reviews.llvm.org/rGfd5e26270660 fixes the patchable-function-prefix
issue on x86.
However... when x86 implemented FineIBT, they also added CFI hash randomization, which is still broken with KASAN. This is because even though objtool is run against vmlinux.o
to build the .cfi_sites
section that contains hash locations, there are two additional object files linked into the final vmlinux
binary that both contain asan.module_ctor
constructors: .vmlinux.export.o
and init/version-timestamp.o
. Since objtool didn't see these files, any type hashes in them are not in .cfi_sites
, and thus they won't get randomized, which leads to a CFI failure as soon as do_ctors
calls them.
cfi=norand
can be used to work around this issue, but I suspect we should just disable KASAN for these files. Or perhaps make sure objtool processes them too?