On Wed, May 13, 2020 at 03:58:30PM +0200, Marco Elver wrote: > On Wed, 13 May 2020 at 15:24, Peter Zijlstra wrote: > > > > On Wed, May 13, 2020 at 03:15:55PM +0200, Marco Elver wrote: > > > So far so good, except: both __no_sanitize_or_inline and > > > __no_kcsan_or_inline *do* avoid KCSAN instrumenting plain accesses, it > > > just doesn't avoid explicit kcsan_check calls, like those in > > > READ/WRITE_ONCE if KCSAN is enabled for the compilation unit. That's > > > just because macros won't be redefined just for __no_sanitize > > > functions. Similarly, READ_ONCE_NOCHECK does work as expected, and its > > > access is unchecked. > > > > > > This will have the expected result: > > > __no_sanitize_or_inline void foo(void) { x++; } // no data races reported > > > > > > This will not work as expected: > > > __no_sanitize_or_inline void foo(void) { READ_ONCE(x); } // data > > > races are reported > > > > > > All this could be fixed if GCC devs would finally take my patch to > > > make -fsanitize=thread distinguish volatile [1], but then we have to > > > wait ~years for the new compilers to reach us. So please don't hold > > > your breath for this one any time soon. > > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-April/544452.html > > > > Right, but that does not address the much larger issue of the attribute > > vs inline tranwreck :/ > > Could you check if Clang is equally broken for you? I think GCC and > Clang have differing behaviour on this. No idea what it takes to fix > GCC though. So I have some good and some maybe not so good news. Given the patch below (on top of tglx's entry-v5-the-rest tag); I did find that I could actually build alternative.o for gcc-{8,9,10} and indeed clang-10. Any earlier gcc (I tried, 5,6,7) does not build: ../arch/x86/include/asm/ptrace.h:126:28: error: inlining failed in call to always_inline ‘user_mode’: function attribute mismatch I dumped the poke_int3_handler output using objdump, find the attached files. It looks like clang-10 doesn't want to turn UBSAN off :/ The GCC files look OK, no funny calls in those. (the config has KASAN/UBSAN on, it looks like KCSAN and KASAN are mutually exclusive) --- diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 77c83833d91e..06d8db612efc 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -990,7 +990,7 @@ static __always_inline int patch_cmp(const void *key, const void *elt) return 0; } -int noinstr poke_int3_handler(struct pt_regs *regs) +int noinstr __no_kcsan __no_sanitize_address __no_sanitize_undefined poke_int3_handler(struct pt_regs *regs) { struct bp_patching_desc *desc; struct text_poke_loc *tp; diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index 2cb42d8bdedc..5e83aada6553 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -15,6 +15,13 @@ /* all clang versions usable with the kernel support KASAN ABI version 5 */ #define KASAN_ABI_VERSION 5 +#if __has_feature(undefined_sanitizer) +#define __no_sanitize_undefined \ + __attribute__((no_sanitize("undefined"))) +#else +#define __no_sanitize_undefined +#endif + #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) /* Emulate GCC's __SANITIZE_ADDRESS__ flag */ #define __SANITIZE_ADDRESS__ diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 7dd4e0349ef3..8196a121a78e 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -138,6 +138,12 @@ #define KASAN_ABI_VERSION 3 #endif +#if __has_attribute(__no_sanitize_undefined__) +#define __no_sanitize_undefined __attribute__((no_sanitize_undefined)) +#else +#define __no_sanitize_undefined +#endif + #if __has_attribute(__no_sanitize_address__) #define __no_sanitize_address __attribute__((no_sanitize_address)) #else