compiler_types: Provide __no_kstack_erase to disable coverage only on Clang
Subsystems (2)
PATCH v2 1/1 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.
---
v2: correctly split compiler-specific stuff out of compiler_types.h (Miguel)
v1: https://lore.kernel.org/all/[email protected]/
Cc: Linus Torvalds <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Hou Wenlong <[email protected]>
Cc: Kirill A. Shutemov <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Wei Yang <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Christophe Leroy <[email protected]>
--- arch/x86/include/asm/init.h | 2 +- include/linux/compiler-clang.h | 3 +++ include/linux/compiler_types.h | 4 ++++ include/linux/init.h | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-)
arch/x86/include/asm/init.h +1 -1
@@ -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 {
include/linux/compiler-clang.h +3 -0
@@ -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
include/linux/compiler_types.h +4 -0
@@ -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
include/linux/init.h +1 -1
@@ -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")
Signature · 1 line
2.34.1
Quoted 11 lines · Kees Cook
In order to support Clang's stack depth tracking (for Linux's
kstack_erasefeature), 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_eraseuses a GCC plugin that removes stack depth tracking instrumentation from__initsections during a late pass in the IR).
Quoted 8 lines
Successfully build and boot tested with GCC 12 and Clang 22.
Fixes 381a38ea53d2 ("init.h: Disable sanitizer coverage for __init and __head")Reported-by kernel test robot <[email protected]>Reported-by [email protected]Signed-off-by Kees Cook <[email protected]>
Quoted 25 lines
--- arch/x86/include/asm/init.h | 2 +- include/linux/compiler-clang.h | 3 +++ include/linux/compiler_types.h | 4 ++++ include/linux/init.h | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-)arch/x86/include/asm/init.h +1
-1@@ -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 {include/linux/compiler-clang.h +0
-0
include/linux/compiler-clang.h line 92
Quoted 4 lines
include/linux/compiler-clang.h +1
-0@@ -89,6 +89,9 @@#define __no_sanitize_coverage#endif +/* Only Clang needs to disable the coverage sanitizer for kstack_erase. */
IMO, this comment does not add much now that this is separated from the dummy definition of __no_kstack_erase but it's probably not worth changing in a new revision if Linus wants to take this directly.
Quoted 36 lines
include/linux/compiler-clang.h +2
-0+#define __no_kstack_erase __no_sanitize_coverage +#if __has_feature (shadow_call_stack)# define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))#endif include/linux/compiler_types.h +4
-0@@ -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 include/linux/init.h +1
-1@@ -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")Signature · 1 line
2.34.1
Quoted 12 lines · Kees Cook
In order to support Clang's stack depth tracking (for Linux's
kstack_erasefeature), 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_eraseuses a GCC plugin that removes stack depth tracking instrumentation from__initsections during a late pass in the IR).
Quoted 8 lines
Successfully build and boot tested with GCC 12 and Clang 22.
Fixes 381a38ea53d2 ("init.h: Disable sanitizer coverage for __init and __head")Reported-by kernel test robot <[email protected]>Reported-by [email protected]Signed-off-by Kees Cook <[email protected]>
Looks good:
Quoted 89 lines
---
v2: correctly split compiler-specific stuff out ofcompiler_types.h(Miguel)
v1: https://lore.kernel.org/all/[email protected]/
Cc: Linus Torvalds <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Hou Wenlong <[email protected]>
Cc: Kirill A. Shutemov <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Wei Yang <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Christophe Leroy <[email protected]>--- arch/x86/include/asm/init.h | 2 +- include/linux/compiler-clang.h | 3 +++ include/linux/compiler_types.h | 4 ++++ include/linux/init.h | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-)arch/x86/include/asm/init.h +1
-1@@ -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 {include/linux/compiler-clang.h +3
-0@@ -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 include/linux/compiler_types.h +4
-0@@ -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 include/linux/init.h +1
-2@@ -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") --2.34.1
Quoted 11 lines · Kees Cook
In order to support Clang's stack depth tracking (for Linux's
kstack_erasefeature), 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_eraseuses a GCC plugin that removes stack depth tracking instrumentation from__initsections during a late pass in the IR).
Quoted 8 lines
Successfully build and boot tested with GCC 12 and Clang 22.
Fixes 381a38ea53d2 ("init.h: Disable sanitizer coverage for __init and __head")Reported-by kernel test robot <[email protected]>Reported-by [email protected]Signed-off-by Kees Cook <[email protected]>
I've now sent the PR that includes this fix:
https://lore.kernel.org/lkml/202507291728.51BAA26@keescook/
Thank you everyone for suffering through the mess I made! :P
-Kees
Signature · 1 line
Kees Cook