compiler_types: Provide __no_kstack_erase to disable coverage only on Clang
PATCH 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).
Successful build and boot tested with GCC 12 and Clang 22.
---
Cc: Linus Torvalds <[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: Miguel Ojeda <[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_types.h | 7 +++++++ include/linux/init.h | 2 +- 3 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_types.h +7 -0
@@ -378,6 +378,13 @@ struct ftrace_likely_data {# define __signed_wrap#endif +/* GCC does not like splitting sanitizer coverage across section inlines */ +#ifdef CC_IS_CLANG +#define __no_kstack_erase __no_sanitize_coverage +#else +#define __no_kstack_erase +#endif +/* Section for code which can't be instrumented at all */ #define __noinstr_section (section) \ noinline notrace __attribute((__section__(section))) \
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 66 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).Successful 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]>---
Cc: Linus Torvalds <[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: Miguel Ojeda <[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_types.h | 7 +++++++ include/linux/init.h | 2 +- 3 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_types.h +0
-0
include/linux/compiler_types.h struct ftrace_likely_data { · line 386
Quoted 9 lines
include/linux/compiler_types.h +6
-0@@ -378,6 +378,13 @@ struct ftrace_likely_data {# define __signed_wrap#endif +/* GCC does not like splitting sanitizer coverage across section inlines */ +#ifdef CC_IS_CLANG +#define __no_kstack_erase __no_sanitize_coverage +#else +#define __no_kstack_erase +#endif
I think this belongs into compiler-clang.h, we've typically refrained from ifdef CC_IS_CLANG/GCC in the generic headers.
See __nocfi for an example, where compiler_types.h provides a default empty definition, and compiler-clang.h provides a non-empty definition.
Quoted 6 lines · Marco Elver
I think this belongs into
compiler-clang.h, we've typically refrained from ifdef CC_IS_CLANG/GCC in the generic headers.
See__nocfifor an example, wherecompiler_types.hprovides a default empty definition, andcompiler-clang.hprovides a non-empty definition.
Yeah, I think that would be a lot cleaner and matches the other things like this.
Linus
Quoted 70 lines · Marco Elver
Quoted 69 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).Successful 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]>---
Cc: Linus Torvalds <[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: Miguel Ojeda <[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_types.h | 7 +++++++ include/linux/init.h | 2 +- 3 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_types.h +0
-0@@ -378,6 +378,13 @@ struct ftrace_likely_data {# define __signed_wrap#endif
Quoted 12 lines
include/linux/compiler_types.h struct ftrace_likely_data { · line 386
Quoted 6 lines
include/linux/compiler_types.h +6
-0+/* GCC does not like splitting sanitizer coverage across section inlines */ +#ifdef CC_IS_CLANG +#define __no_kstack_erase __no_sanitize_coverage +#else +#define __no_kstack_erase +#endif I think this belongs into
compiler-clang.h, we've typically refrained from ifdef CC_IS_CLANG/GCC in the generic headers.
See__nocfifor an example, wherecompiler_types.hprovides a default empty definition, andcompiler-clang.hprovides a non-empty definition.
Oh, good point. I will rearrange this to use the #ifndef style handling!
Signature · 1 line
Kees Cook