Commit f627b51a authored by Kees Cook's avatar Kees Cook
Browse files

compiler_types: Provide __no_kstack_erase to disable coverage only on Clang



In order to support Clang's stack depth tracking (for Linux's kstack_erase
feature), the coverage sanitizer needed to be disabled for __init (and
__head) section code. Doing this universally (i.e. for GCC too) created
a number of unexpected problems, ranging from changes to inlining logic
to failures to DCE code on earlier GCC versions.

Since this change is only needed for Clang, specialize it so that GCC
doesn't see the change as it isn't needed there (the GCC implementation
of kstack_erase uses a GCC plugin that removes stack depth tracking
instrumentation from __init sections during a late pass in the IR).

Successfully build and boot tested with GCC 12 and Clang 22.

Fixes: 381a38ea ("init.h: Disable sanitizer coverage for __init and __head")
Reported-by: default avatarkernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202507270258.neWuiXLd-lkp@intel.com/


Reported-by: default avatar <syzbot+5245cb609175fb6e8122@syzkaller.appspotmail.com>
Closes: https://lore.kernel.org/all/6888d004.a00a0220.26d0e1.0004.GAE@google.com/


Reviewed-by: default avatarNathan Chancellor <nathan@kernel.org>
Reviewed-by: default avatarMarco Elver <elver@google.com>
Link: https://lore.kernel.org/r/20250729234055.it.233-kees@kernel.org


Signed-off-by: default avatarKees Cook <kees@kernel.org>
parent 94fd4464
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#if defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 170000
#define __head	__section(".head.text") __no_sanitize_undefined __no_stack_protector
#else
#define __head	__section(".head.text") __no_sanitize_undefined __no_sanitize_coverage
#define __head	__section(".head.text") __no_sanitize_undefined __no_kstack_erase
#endif

struct x86_mapping_info {
+3 −0
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@
#define __no_sanitize_coverage
#endif

/* Only Clang needs to disable the coverage sanitizer for kstack_erase. */
#define __no_kstack_erase	__no_sanitize_coverage

#if __has_feature(shadow_call_stack)
# define __noscs	__attribute__((__no_sanitize__("shadow-call-stack")))
#endif
+4 −0
Original line number Diff line number Diff line
@@ -424,6 +424,10 @@ struct ftrace_likely_data {
# define randomized_struct_fields_end
#endif

#ifndef __no_kstack_erase
# define __no_kstack_erase
#endif

#ifndef __noscs
# define __noscs
#endif
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@
   discard it in modules) */
#define __init		__section(".init.text") __cold __latent_entropy	\
						__noinitretpoline	\
						__no_sanitize_coverage
						__no_kstack_erase
#define __initdata	__section(".init.data")
#define __initconst	__section(".init.rodata")
#define __exitdata	__section(".exit.data")