Message ID | Y1AZr01X1wvg5Klu@dev-arch.thelio-3990X (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | -Wmacro-redefined in include/linux/fortify-string.h | expand |
On Wed, Oct 19, 2022 at 8:37 AM Nathan Chancellor <nathan@kernel.org> wrote: > > Hi all, > > I am seeing the following set of warnings when building an x86_64 > configuration that has CONFIG_FORTIFY_SOURCE=y and CONFIG_KMSAN=y: I was also looking into this issue recently, because people start running into it: https://github.com/google/kmsan/issues/89 I have a solution that redefines __underlying_memXXX to __msan_memXXX under __SANITIZE_MEMORY__ in fortify-string.h and skips `#define memXXX __msan_memXXX` in string_64.h, making KMSAN kinda work with FORTIFY_SOURCE. Dunno if that's necessary though: KMSAN is a debugging tool anyway, and supporting it in fortify-string.h sounds excessive. So I'm fine with disabling FORTIFY_STRING under KMSAN, unless someone objects. > In file included from scripts/mod/devicetable-offsets.c:3: > In file included from ./include/linux/mod_devicetable.h:13: > In file included from ./include/linux/uuid.h:12: > In file included from ./include/linux/string.h:253: > ./include/linux/fortify-string.h:496:9: error: 'memcpy' macro redefined [-Werror,-Wmacro-redefined] > #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ > ^ > ./arch/x86/include/asm/string_64.h:17:9: note: previous definition is here > #define memcpy __msan_memcpy > ^ > In file included from scripts/mod/devicetable-offsets.c:3: > In file included from ./include/linux/mod_devicetable.h:13: > In file included from ./include/linux/uuid.h:12: > In file included from ./include/linux/string.h:253: > ./include/linux/fortify-string.h:500:9: error: 'memmove' macro redefined [-Werror,-Wmacro-redefined] > #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \ > ^ > ./arch/x86/include/asm/string_64.h:73:9: note: previous definition is here > #define memmove __msan_memmove > ^ > 2 errors generated. > > I can see that commit ff901d80fff6 ("x86: kmsan: use __msan_ string > functions where possible.") appears to include a fix up for this warning > with memset() but not memcpy() or memmove(). If I apply a similar fix up > like so: > > diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h > index 4029fe368a4f..718ee17b31e3 100644 > --- a/include/linux/fortify-string.h > +++ b/include/linux/fortify-string.h > @@ -493,6 +493,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, > * __struct_size() vs __member_size() must be captured here to avoid > * evaluating argument side-effects further into the macro layers. > */ > +#ifndef CONFIG_KMSAN > #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ > __struct_size(p), __struct_size(q), \ > __member_size(p), __member_size(q), \ > @@ -501,6 +502,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, > __struct_size(p), __struct_size(q), \ > __member_size(p), __member_size(q), \ > memmove) > +#endif > > extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); > __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) > > Then the instances of -Wmacro-redefined disappear but the fortify tests > no longer pass for somewhat obvious reasons: > > warning: unsafe memcpy() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memcpy.c > warning: unsafe memmove() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memmove.c > warning: unsafe memcpy() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memcpy.c > warning: unsafe memmove() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memmove.c > warning: unsafe memcpy() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memcpy.c > warning: unsafe memmove() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memmove.c > warning: unsafe memset() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memset.c > warning: unsafe memcpy() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memcpy.c > warning: unsafe memmove() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memmove.c > warning: unsafe memset() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memset.c > > Should CONFIG_KMSAN depend on CONFIG_FORTIFY_SOURCE=n like so? It seems > like the two features are incompatible if I am reading ff901d80fff6 > correctly. > > diff --git a/lib/Kconfig.kmsan b/lib/Kconfig.kmsan > index b2489dd6503f..6a681621e3c5 100644 > --- a/lib/Kconfig.kmsan > +++ b/lib/Kconfig.kmsan > @@ -11,7 +11,7 @@ config HAVE_KMSAN_COMPILER > config KMSAN > bool "KMSAN: detector of uninitialized values use" > depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER > - depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN > + depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN && !FORTIFY_SOURCE > select STACKDEPOT > select STACKDEPOT_ALWAYS_INIT > help > > or is there a different obvious fix that I am missing? > > Cheers, > Nathan -- Alexander Potapenko Software Engineer Google Germany GmbH Erika-Mann-Straße, 33 80636 München Geschäftsführer: Paul Manicle, Liana Sebastian Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg
On Wed, Oct 19, 2022 at 08:37:19AM -0700, Nathan Chancellor wrote: > I am seeing the following set of warnings when building an x86_64 > configuration that has CONFIG_FORTIFY_SOURCE=y and CONFIG_KMSAN=y: > > In file included from scripts/mod/devicetable-offsets.c:3: > In file included from ./include/linux/mod_devicetable.h:13: > In file included from ./include/linux/uuid.h:12: > In file included from ./include/linux/string.h:253: > ./include/linux/fortify-string.h:496:9: error: 'memcpy' macro redefined [-Werror,-Wmacro-redefined] > #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ > ^ > ./arch/x86/include/asm/string_64.h:17:9: note: previous definition is here > #define memcpy __msan_memcpy > ^ > In file included from scripts/mod/devicetable-offsets.c:3: > In file included from ./include/linux/mod_devicetable.h:13: > In file included from ./include/linux/uuid.h:12: > In file included from ./include/linux/string.h:253: > ./include/linux/fortify-string.h:500:9: error: 'memmove' macro redefined [-Werror,-Wmacro-redefined] > #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \ > ^ > ./arch/x86/include/asm/string_64.h:73:9: note: previous definition is here > #define memmove __msan_memmove > ^ > 2 errors generated. > > I can see that commit ff901d80fff6 ("x86: kmsan: use __msan_ string > functions where possible.") appears to include a fix up for this warning > with memset() but not memcpy() or memmove(). If I apply a similar fix up > like so: > > diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h > index 4029fe368a4f..718ee17b31e3 100644 > --- a/include/linux/fortify-string.h > +++ b/include/linux/fortify-string.h > @@ -493,6 +493,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, > * __struct_size() vs __member_size() must be captured here to avoid > * evaluating argument side-effects further into the macro layers. > */ > +#ifndef CONFIG_KMSAN > #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ > __struct_size(p), __struct_size(q), \ > __member_size(p), __member_size(q), \ > @@ -501,6 +502,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, > __struct_size(p), __struct_size(q), \ > __member_size(p), __member_size(q), \ > memmove) > +#endif > > extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); > __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) > > Then the instances of -Wmacro-redefined disappear but the fortify tests > no longer pass for somewhat obvious reasons: > > warning: unsafe memcpy() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memcpy.c > warning: unsafe memmove() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memmove.c > warning: unsafe memcpy() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memcpy.c > warning: unsafe memmove() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memmove.c > warning: unsafe memcpy() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memcpy.c > warning: unsafe memmove() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memmove.c > warning: unsafe memset() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memset.c > warning: unsafe memcpy() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memcpy.c > warning: unsafe memmove() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memmove.c > warning: unsafe memset() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memset.c > > Should CONFIG_KMSAN depend on CONFIG_FORTIFY_SOURCE=n like so? It seems > like the two features are incompatible if I am reading ff901d80fff6 > correctly. > > diff --git a/lib/Kconfig.kmsan b/lib/Kconfig.kmsan > index b2489dd6503f..6a681621e3c5 100644 > --- a/lib/Kconfig.kmsan > +++ b/lib/Kconfig.kmsan > @@ -11,7 +11,7 @@ config HAVE_KMSAN_COMPILER > config KMSAN > bool "KMSAN: detector of uninitialized values use" > depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER > - depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN > + depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN && !FORTIFY_SOURCE > select STACKDEPOT > select STACKDEPOT_ALWAYS_INIT > help > > or is there a different obvious fix that I am missing? Hm, why can't KMSAN use the same thing KASAN does, and compose correctly with FORTIFY? (i.e. redefine the "__underlaying_mem*" macros?)
On Wed, Oct 19, 2022 at 09:48:27AM -0700, Alexander Potapenko wrote: > On Wed, Oct 19, 2022 at 8:37 AM Nathan Chancellor <nathan@kernel.org> wrote: > > > > Hi all, > > > > I am seeing the following set of warnings when building an x86_64 > > configuration that has CONFIG_FORTIFY_SOURCE=y and CONFIG_KMSAN=y: > > I was also looking into this issue recently, because people start > running into it: https://github.com/google/kmsan/issues/89 > > I have a solution that redefines __underlying_memXXX to __msan_memXXX > under __SANITIZE_MEMORY__ in fortify-string.h and skips `#define > memXXX __msan_memXXX` in string_64.h, making KMSAN kinda work with > FORTIFY_SOURCE. Oh good! > Dunno if that's necessary though: KMSAN is a debugging tool anyway, > and supporting it in fortify-string.h sounds excessive. I'd much prefer letting them still work together.
diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 4029fe368a4f..718ee17b31e3 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -493,6 +493,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, * __struct_size() vs __member_size() must be captured here to avoid * evaluating argument side-effects further into the macro layers. */ +#ifndef CONFIG_KMSAN #define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \ __struct_size(p), __struct_size(q), \ __member_size(p), __member_size(q), \ @@ -501,6 +502,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, __struct_size(p), __struct_size(q), \ __member_size(p), __member_size(q), \ memmove) +#endif extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan); __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size) Then the instances of -Wmacro-redefined disappear but the fortify tests no longer pass for somewhat obvious reasons: warning: unsafe memcpy() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memcpy.c warning: unsafe memmove() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memmove.c warning: unsafe memcpy() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memcpy.c warning: unsafe memmove() usage lacked '__read_overflow2_field' symbol in lib/test_fortify/read_overflow2_field-memmove.c warning: unsafe memcpy() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memcpy.c warning: unsafe memmove() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memmove.c warning: unsafe memset() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memset.c warning: unsafe memcpy() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memcpy.c warning: unsafe memmove() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memmove.c warning: unsafe memset() usage lacked '__write_overflow_field' symbol in lib/test_fortify/write_overflow_field-memset.c Should CONFIG_KMSAN depend on CONFIG_FORTIFY_SOURCE=n like so? It seems like the two features are incompatible if I am reading ff901d80fff6 correctly. diff --git a/lib/Kconfig.kmsan b/lib/Kconfig.kmsan index b2489dd6503f..6a681621e3c5 100644 --- a/lib/Kconfig.kmsan +++ b/lib/Kconfig.kmsan @@ -11,7 +11,7 @@ config HAVE_KMSAN_COMPILER config KMSAN bool "KMSAN: detector of uninitialized values use" depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER - depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN + depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN && !FORTIFY_SOURCE select STACKDEPOT select STACKDEPOT_ALWAYS_INIT help