linux-loongson/include/linux/compiler-clang.h
Kees Cook f627b51aaa 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: 381a38ea53 ("init.h: Disable sanitizer coverage for __init and __head")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202507270258.neWuiXLd-lkp@intel.com/
Reported-by: syzbot+5245cb609175fb6e8122@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6888d004.a00a0220.26d0e1.0004.GAE@google.com/
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Marco Elver <elver@google.com>
Link: https://lore.kernel.org/r/20250729234055.it.233-kees@kernel.org
Signed-off-by: Kees Cook <kees@kernel.org>
2025-07-29 17:19:35 -07:00

142 lines
4.5 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_COMPILER_TYPES_H
#error "Please do not include <linux/compiler-clang.h> directly, include <linux/compiler.h> instead."
#endif
/* Compiler specific definitions for Clang compiler */
/*
* Clang prior to 17 is being silly and considers many __cleanup() variables
* as unused (because they are, their sole purpose is to go out of scope).
*
* https://github.com/llvm/llvm-project/commit/877210faa447f4cc7db87812f8ed80e398fedd61
*/
#undef __cleanup
#define __cleanup(func) __maybe_unused __attribute__((__cleanup__(func)))
/* all clang versions usable with the kernel support KASAN ABI version 5 */
#define KASAN_ABI_VERSION 5
/*
* Note: Checking __has_feature(*_sanitizer) is only true if the feature is
* enabled. Therefore it is not required to additionally check defined(CONFIG_*)
* to avoid adding redundant attributes in other configurations.
*/
#if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer)
/* Emulate GCC's __SANITIZE_ADDRESS__ flag */
#define __SANITIZE_ADDRESS__
#define __no_sanitize_address \
__attribute__((no_sanitize("address", "hwaddress")))
#else
#define __no_sanitize_address
#endif
#if __has_feature(thread_sanitizer)
/* emulate gcc's __SANITIZE_THREAD__ flag */
#define __SANITIZE_THREAD__
#define __no_sanitize_thread \
__attribute__((no_sanitize("thread")))
#else
#define __no_sanitize_thread
#endif
#if defined(CONFIG_ARCH_USE_BUILTIN_BSWAP)
#define __HAVE_BUILTIN_BSWAP32__
#define __HAVE_BUILTIN_BSWAP64__
#define __HAVE_BUILTIN_BSWAP16__
#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
#if __has_feature(undefined_behavior_sanitizer)
/* GCC does not have __SANITIZE_UNDEFINED__ */
#define __no_sanitize_undefined \
__attribute__((no_sanitize("undefined")))
#else
#define __no_sanitize_undefined
#endif
#if __has_feature(memory_sanitizer)
#define __SANITIZE_MEMORY__
/*
* Unlike other sanitizers, KMSAN still inserts code into functions marked with
* no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation
* provides the behavior consistent with other __no_sanitize_ attributes,
* guaranteeing that __no_sanitize_memory functions remain uninstrumented.
*/
#define __no_sanitize_memory __disable_sanitizer_instrumentation
/*
* The __no_kmsan_checks attribute ensures that a function does not produce
* false positive reports by:
* - initializing all local variables and memory stores in this function;
* - skipping all shadow checks;
* - passing initialized arguments to this function's callees.
*/
#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory")))
#else
#define __no_sanitize_memory
#define __no_kmsan_checks
#endif
/*
* Support for __has_feature(coverage_sanitizer) was added in Clang 13 together
* with no_sanitize("coverage"). Prior versions of Clang support coverage
* instrumentation, but cannot be queried for support by the preprocessor.
*/
#if __has_feature(coverage_sanitizer)
#define __no_sanitize_coverage __attribute__((no_sanitize("coverage")))
#else
#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
#if __has_feature(kcfi)
/* Disable CFI checking inside a function. */
#define __nocfi __attribute__((__no_sanitize__("kcfi")))
#endif
/*
* Turn individual warnings and errors on and off locally, depending
* on version.
*/
#define __diag_clang(version, severity, s) \
__diag_clang_ ## version(__diag_clang_ ## severity s)
/* Severity used in pragma directives */
#define __diag_clang_ignore ignored
#define __diag_clang_warn warning
#define __diag_clang_error error
#define __diag_str1(s) #s
#define __diag_str(s) __diag_str1(s)
#define __diag(s) _Pragma(__diag_str(clang diagnostic s))
#define __diag_clang_13(s) __diag(s)
#define __diag_ignore_all(option, comment) \
__diag_clang(13, ignore, option)
/*
* clang has horrible behavior with "g" or "rm" constraints for asm
* inputs, turning them into something worse than "m". Avoid using
* constraints with multiple possible uses (but "ir" seems to be ok):
*
* https://github.com/llvm/llvm-project/issues/20571
*/
#define ASM_INPUT_G "ir"
#define ASM_INPUT_RM "r"
/*
* Declare compiler support for __typeof_unqual__() operator.
*
* Bindgen uses LLVM even if our C compiler is GCC, so we cannot
* rely on the auto-detected CONFIG_CC_HAS_TYPEOF_UNQUAL.
*/
#define CC_HAS_TYPEOF_UNQUAL (__clang_major__ >= 19)