Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4c66f83

Browse files
Darksonnojeda
authored andcommittedSep 26, 2024
cfi: encode cfi normalized integers + kasan/gcov bug in Kconfig
There is a bug in the LLVM implementation of KASAN and GCOV that makes these options incompatible with the CFI_ICALL_NORMALIZE_INTEGERS option. The bug has already been fixed in llvm/clang [1] and rustc [2]. However, Kconfig currently has no way to gate features on the LLVM version inside rustc, so we cannot write down a precise `depends on` clause in this case. Instead, a `def_bool` option is defined for whether CFI_ICALL_NORMALIZE_INTEGERS is available, and its default value is set to false when GCOV or KASAN are turned on. End users using a patched clang/rustc can turn on the HAVE_CFI_ICALL_NORMALIZE_INTEGERS option directly to override this. An alternative solution is to inspect a binary created by clang or rustc to see whether the faulty CFI tags are in the binary. This would be a precise check, but it would involve hard-coding the *hashed* version of the CFI tag. This is because there's no way to get clang or rustc to output the unhased version of the CFI tag. Relying on the precise hashing algorithm using by CFI seems too fragile, so I have not pursued this option. Besides, this kind of hack is exactly what lead to the LLVM bug in the first place. If the CFI_ICALL_NORMALIZE_INTEGERS option is used without CONFIG_RUST, then we actually can perform a precise check today: just compare the clang version number. This works since clang and llvm are always updated in lockstep. However, encoding this in Kconfig would give the HAVE_CFI_ICALL_NORMALIZE_INTEGERS option a dependency on CONFIG_RUST, which is not possible as the reverse dependency already exists. HAVE_CFI_ICALL_NORMALIZE_INTEGERS is defined to be a `def_bool` instead of `bool` to avoid asking end users whether they want to turn on the option. Turning it on explicitly is something only experts should do, so making it hard to do so is not an issue. I added a `depends on CFI_CLANG` clause to the new Kconfig option. I'm not sure whether that makes sense or not, but it doesn't seem to make a big difference. In a future kernel release, I would like to add a Kconfig option similar to CLANG_VERSION/RUSTC_VERSION for inspecting the version of the LLVM inside rustc. Once that feature lands, this logic will be replaced with a precise version check. This check is not being introduced here to avoid introducing a new _VERSION constant in a fix. Link: llvm/llvm-project#104826 [1] Link: rust-lang/rust#129373 [2] Fixes: ce4a262 ("cfi: add CONFIG_CFI_ICALL_NORMALIZE_INTEGERS") Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202409231044.4f064459-oliver.sang@intel.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Link: https://lore.kernel.org/r/20240925-cfi-norm-kasan-fix-v1-1-0328985cdf33@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 93e34a0 commit 4c66f83

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed
 

‎arch/Kconfig

+17-1
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ config CFI_CLANG
838838
config CFI_ICALL_NORMALIZE_INTEGERS
839839
bool "Normalize CFI tags for integers"
840840
depends on CFI_CLANG
841-
depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
841+
depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS
842842
help
843843
This option normalizes the CFI tags for integer types so that all
844844
integer types of the same size and signedness receive the same CFI
@@ -851,6 +851,22 @@ config CFI_ICALL_NORMALIZE_INTEGERS
851851

852852
This option is necessary for using CFI with Rust. If unsure, say N.
853853

854+
config HAVE_CFI_ICALL_NORMALIZE_INTEGERS
855+
def_bool !GCOV_KERNEL && !KASAN
856+
depends on CFI_CLANG
857+
depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
858+
help
859+
Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers
860+
currently in use?
861+
862+
This option defaults to false if GCOV or KASAN is enabled, as there is
863+
an LLVM bug that makes normalized integers tags incompatible with
864+
KASAN and GCOV. Kconfig currently does not have the infrastructure to
865+
detect whether your rustc compiler contains the fix for this bug, so
866+
it is assumed that it doesn't. If your compiler has the fix, you can
867+
explicitly enable this option in your config file. The Kconfig logic
868+
needed to detect this will be added in a future kernel release.
869+
854870
config CFI_PERMISSIVE
855871
bool "Use CFI in permissive mode"
856872
depends on CFI_CLANG

‎init/Kconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -1946,7 +1946,7 @@ config RUST
19461946
depends on !GCC_PLUGIN_RANDSTRUCT
19471947
depends on !RANDSTRUCT
19481948
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
1949-
depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers)
1949+
depends on !CFI_CLANG || RUSTC_VERSION >= 107900 && HAVE_CFI_ICALL_NORMALIZE_INTEGERS
19501950
select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG
19511951
depends on !CALL_PADDING || RUSTC_VERSION >= 108100
19521952
depends on !KASAN_SW_TAGS

0 commit comments

Comments
 (0)
Failed to load comments.