disable __counted_by for clang < 19.1.3
Subsystems (5)
cover disable __counted_by for clang < 19.1.3
Hi Kees,
Bill's PR to disable __counted_by for "whole struct" __bdos cases has now been merged into 19.1.3 [1], so here's the patch to disable __counted_by for clang versions < 19.1.3 in the kernel.
Hopefully in the near future __counted_by for whole struct __bdos can be enabled once again in coordination between the kernel, gcc, and clang. There has been recent progress on this in [2] thanks to Tavian.
Also see previous discussion on the mailing list [3]
Thanks to everyone for moving this issue along. In particular, Bill for his PR to clang/llvm, Kees and Thorsten for reproducers of the two issues, Nathan for Kconfig-ifying this patch, and Miguel for reviewing.
Info for the stable team:
This patch should be backported to kernels >= 6.6 to make sure that those build correctly with the effected clang versions. This patch cherry-picks cleanly onto linux-6.11.y. For linux-6.6.y three prerequiste commits are neded:
16c31dd7fdf6: Compiler Attributes: counted_by: bump min gcc version 2993eb7a8d34: Compiler Attributes: counted_by: fixup clang URL 231dc3f0c936: lkdtm/bugs: Improve warning message for compilers without counted_by support
There are still two merge conflicts even with those prerequistes. Here's the correct resolution:
1. include/linux/compiler_types.h:
use the incoming change until before (but not including) the "Apply __counted_by() when the Endianness matches to increase test coverage." comment
2. lib/overflow_kunit.c:
HEAD is correct
[1] https://github.com/llvm/llvm-project/pull/112786
[2] https://github.com/llvm/llvm-project/pull/112636
[3] https://lore.kernel.org/lkml/[email protected]/T/#m204c09f63c076586a02d194b87dffc7e81b8de7b
Best Regards
Jan
Jan Hendrik Farr (1):
Compiler Attributes: disable __counted_by for clang < 19.1.3
drivers/misc/lkdtm/bugs.c | 2 +- include/linux/compiler_attributes.h | 13 ------------- include/linux/compiler_types.h | 19 +++++++++++++++++++ init/Kconfig | 9 +++++++++ lib/overflow_kunit.c | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-)
Signature · 1 line
2.47.0
PATCH 1/1 Compiler Attributes: disable __counted_by for clang < 19.1.3
This patch disables __counted_by for clang versions < 19.1.3 because of the two issues listed below. It does this by introducing CONFIG_CC_HAS_COUNTED_BY.
1. clang < 19.1.2 has a bug that can lead to __bdos returning 0:
https://github.com/llvm/llvm-project/pull/110497
2. clang < 19.1.3 has a bug that can lead to __bdos being off by 4:
https://github.com/llvm/llvm-project/pull/112636
--- drivers/misc/lkdtm/bugs.c | 2 +- include/linux/compiler_attributes.h | 13 ------------- include/linux/compiler_types.h | 19 +++++++++++++++++++ init/Kconfig | 9 +++++++++ lib/overflow_kunit.c | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-)
drivers/misc/lkdtm/bugs.c +1 -1
@@ -445,7 +445,7 @@ static void lkdtm_FAM_BOUNDS(void)pr_err ("FAIL: survived access of invalid flexible array member index!\n" ); -if (!__has_attribute (__counted_by__)) +if (!IS_ENABLED (CONFIG_CC_HAS_COUNTED_BY ))pr_warn ("This is expected since this %s was built with a compiler that does not support __counted_by\n" , lkdtm_kernel_info);else if (IS_ENABLED (CONFIG_UBSAN_BOUNDS ))
include/linux/compiler_attributes.h +0 -13
@@ -94,19 +94,6 @@# define __copy (symbol)#endif -/* -* Optional: only supported since gcc >= 15 -* Optional: only supported since clang >= 18 -* -* gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 -* clang: https://github.com/llvm/llvm-project/pull/76348 -*/ -#if __has_attribute (__counted_by__) -# define __counted_by (member) __attribute__((__counted_by__(member))) -#else -# define __counted_by (member) -#endif -/* * Optional: not supported by gcc * Optional: only supported since clang >= 14.0
include/linux/compiler_types.h +19 -0
@@ -323,6 +323,25 @@ struct ftrace_likely_data {#define __no_sanitize_or_inline __always_inline#endif +/* +* Optional: only supported since gcc >= 15 +* Optional: only supported since clang >= 18 +* +* gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 +* clang: https://github.com/llvm/llvm-project/pull/76348 +* +* __bdos on clang < 19.1.2 can erroneously return 0: +* https://github.com/llvm/llvm-project/pull/110497 +* +* __bdos on clang < 19.1.3 can be off by 4: +* https://github.com/llvm/llvm-project/pull/112636 +*/ +#ifdef CONFIG_CC_HAS_COUNTED_BY +# define __counted_by (member) __attribute__((__counted_by__(member))) +#else +# define __counted_by (member) +#endif +/* * Apply __counted_by() when the Endianness matches to increase test coverage. */
init/Kconfig +9 -0
@@ -116,6 +116,15 @@ config CC_HAS_ASM_INLINE config CC_HAS_NO_PROFILE_FN_ATTR def_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror) +config CC_HAS_COUNTED_BY + # TODO: when gcc 15 is released remove the build test and add + # a gcc version check + def_bool $(success,echo 'struct flex { int count; int array[] __attribute__((__counted_by__(count))); };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) + # clang needs to be at least 19.1.3 to avoid __bdos miscalculations + # https://github.com/llvm/llvm-project/pull/110497 + # https://github.com/llvm/llvm-project/pull/112636 + depends on !(CC_IS_CLANG && CLANG_VERSION < 190103) + config PAHOLE_VERSION int default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))
lib/overflow_kunit.c +1 -1
@@ -1187,7 +1187,7 @@ static void DEFINE_FLEX_test(struct kunit *test) {/* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */ DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2); -#if __has_attribute (__counted_by__) +#ifdef CONFIG_CC_HAS_COUNTED_BY int expected_raw_size =sizeof (struct foo );#else int expected_raw_size =sizeof (struct foo ) +2 *sizeof (s16);
Signature · 1 line
2.47.0
Re: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
Quoted 11 lines · Jan Hendrik Farr
This patch disables
__counted_byfor clang versions < 19.1.3 because of the two issues listed below. It does this by introducingCONFIG_CC_HAS_COUNTED_BY.1. clang < 19.1.2 has a bug that can lead to
__bdosreturning 0:
https://github.com/llvm/llvm-project/pull/1104972. clang < 19.1.3 has a bug that can lead to
__bdosbeing off by 4:
https://github.com/llvm/llvm-project/pull/112636
Quoted 15 lines
Fixes c8248faf3ca2 ("Compiler Attributes: counted_by: Adjust name and identifier expansion")Cc [email protected] # 6.6.x: 16c31dd7fdf6: Compiler Attributes: counted_by: bump min gcc versionCc [email protected] # 6.6.x: 2993eb7a8d34: Compiler Attributes: counted_by: fixup clang URLCc [email protected] # 6.6.x: 231dc3f0c936: lkdtm/bugs: Improve warning message for compilers without counted_by supportCc [email protected] # 6.6.xReported-by Nathan Chancellor <[email protected]>Reported-by kernel test robot <[email protected]>Link https://lore.kernel.org/all/Zw8iawAF5W2uzGuh@archlinux/T/#m204c09f63c076586a02d194b87dffc7e81b8de7b open hereSuggested-by Nathan Chancellor <[email protected]>Signed-off-by Jan Hendrik Farr <[email protected]>Reviewed-by Nathan Chancellor <[email protected]>Tested-by Nathan Chancellor <[email protected]>Reviewed-by Miguel Ojeda <[email protected]>
Thanks for fixing this and your work on the Clang issues. Feel free to add:
Re: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
In reply to Jan Hendrik FarrQuoted 8 lines · Jan Hendrik Farr
This patch disables
__counted_byfor clang versions < 19.1.3 because of the two issues listed below. It does this by introducingCONFIG_CC_HAS_COUNTED_BY.1. clang < 19.1.2 has a bug that can lead to
__bdosreturning 0:
https://github.com/llvm/llvm-project/pull/110497[...]
Applied to for-next/hardening, thanks!
[1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
https://git.kernel.org/kees/c/f06e108a3dc5
Take care,
Signature · 1 line
Kees Cook
Re: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
In reply to Jan Hendrik FarrQuoted 57 lines · Jan Hendrik Farr
This patch disables
__counted_byfor clang versions < 19.1.3 because of the two issues listed below. It does this by introducingCONFIG_CC_HAS_COUNTED_BY.1. clang < 19.1.2 has a bug that can lead to
__bdosreturning 0:
https://github.com/llvm/llvm-project/pull/1104972. clang < 19.1.3 has a bug that can lead to
__bdosbeing off by 4:
https://github.com/llvm/llvm-project/pull/112636Fixes c8248faf3ca2 ("Compiler Attributes: counted_by: Adjust name and identifier expansion")Cc [email protected] # 6.6.x: 16c31dd7fdf6: Compiler Attributes: counted_by: bump min gcc versionCc [email protected] # 6.6.x: 2993eb7a8d34: Compiler Attributes: counted_by: fixup clang URLCc [email protected] # 6.6.x: 231dc3f0c936: lkdtm/bugs: Improve warning message for compilers without counted_by supportCc [email protected] # 6.6.xReported-by Nathan Chancellor <[email protected]>Reported-by kernel test robot <[email protected]>Link https://lore.kernel.org/all/Zw8iawAF5W2uzGuh@archlinux/T/#m204c09f63c076586a02d194b87dffc7e81b8de7b open hereSuggested-by Nathan Chancellor <[email protected]>Signed-off-by Jan Hendrik Farr <[email protected]>Reviewed-by Nathan Chancellor <[email protected]>Tested-by Nathan Chancellor <[email protected]>Reviewed-by Miguel Ojeda <[email protected]>---
drivers/misc/lkdtm/bugs.c | 2 +- include/linux/compiler_attributes.h | 13 ------------- include/linux/compiler_types.h | 19 +++++++++++++++++++ init/Kconfig | 9 +++++++++ lib/overflow_kunit.c | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-)drivers/misc/lkdtm/bugs.c +1
-1@@ -445,7 +445,7 @@ static void lkdtm_FAM_BOUNDS(void)pr_err ("FAIL: survived access of invalid flexible array member index!\n" ); -if (!__has_attribute (__counted_by__)) +if (!IS_ENABLED (CONFIG_CC_HAS_COUNTED_BY ))pr_warn ("This is expected since this %s was built with a compiler that does not support __counted_by\n" , lkdtm_kernel_info);else if (IS_ENABLED (CONFIG_UBSAN_BOUNDS ))include/linux/compiler_attributes.h +0
-3@@ -94,19 +94,6 @@# define __copy (symbol)#endif -/* -* Optional: only supported since gcc >= 15 -* Optional: only supported since clang >= 18
include/linux/compiler_attributes.h line 109
Quoted 10 lines
include/linux/compiler_attributes.h +0
-10-* -* gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 -* clang: https://github.com/llvm/llvm-project/pull/76348 -*/ -#if __has_attribute (__counted_by__) -# define __counted_by (member) __attribute__((__counted_by__(member))) -#else -# define __counted_by (member) -#endif -
Why is the define of __counted_by moved from here (compiler_attributes.h) to a different location (compiler_types.h) ?
I am asking this because I try to compile an out of tree kernel module with ofed headers. in the ofed header of compiler_types.h there is an added include of types.h:
#include_next <linux/compiler_attributes.h>
#include <linux/types.h>
so what happen is that __counted_by is defined in types.h, and then I get a compilation error:
././include/linux/compiler_types.h:323: error: "__counted_by" redefined [-Werror]
I am not sure yet how this should be fixed.
Thank you,
Dafna
Quoted 69 lines
include/linux/compiler_attributes.h +0
-0/* * Optional: not supported by gcc * Optional: only supported since clang >= 14.0 include/linux/compiler_types.h +19
-0@@ -323,6 +323,25 @@ struct ftrace_likely_data {#define __no_sanitize_or_inline __always_inline#endif +/* +* Optional: only supported since gcc >= 15 +* Optional: only supported since clang >= 18 +* +* gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 +* clang: https://github.com/llvm/llvm-project/pull/76348 +* +* __bdos on clang < 19.1.2 can erroneously return 0: +* https://github.com/llvm/llvm-project/pull/110497 +* +* __bdos on clang < 19.1.3 can be off by 4: +* https://github.com/llvm/llvm-project/pull/112636 +*/ +#ifdef CONFIG_CC_HAS_COUNTED_BY +# define __counted_by (member) __attribute__((__counted_by__(member))) +#else +# define __counted_by (member) +#endif +/* * Apply __counted_by() when the Endianness matches to increase test coverage. */ init/Kconfig +0
-0@@ -116,6 +116,15 @@ config CC_HAS_ASM_INLINEconfig
CC_HAS_NO_PROFILE_FN_ATTRdef_bool $(success,echo '__attribute__((no_profile_instrument_function)) int x();' | $(CC) -x c - -c -o /dev/null -Werror)init/Kconfig +9
-0+config CC_HAS_COUNTED_BY + # TODO: when gcc 15 is released remove the build test and add + # a gcc version check + def_bool $(success,echo 'struct flex { int count; int array[] __attribute__((__counted_by__(count))); };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) + # clang needs to be at least 19.1.3 to avoid __bdos miscalculations + # https://github.com/llvm/llvm-project/pull/110497 + # https://github.com/llvm/llvm-project/pull/112636 + depends on !(CC_IS_CLANG && CLANG_VERSION < 190103) +config
PAHOLE_VERSIONint default $(shell,$(srctree)/scripts/pahole-version.sh $(PAHOLE))lib/overflow_kunit.c +1
-1@@ -1187,7 +1187,7 @@ static void DEFINE_FLEX_test(struct kunit *test) {/* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */ DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2); -#if __has_attribute (__counted_by__) +#ifdef CONFIG_CC_HAS_COUNTED_BY int expected_raw_size =sizeof (struct foo );#else int expected_raw_size =sizeof (struct foo ) +2 *sizeof (s16);Signature · 1 line
2.47.0
Re: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
Quoted 3 lines · Dafna Hirschfeld
Why is the define of
__counted_bymoved from here (compiler_attributes.h) to a different location (compiler_types.h) ?
compiler_attributes.h is supposed to have only things that do not depend on the kernel configuration and so on.
It sounds like those out-of-tree headers should be fixed.
I hope that helps.
Cheers,
Miguel
Sasha Levin
maintainerRe: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
In reply to Jan Hendrik Farr[ Sasha's backport helper bot ]
Hi,
Summary of potential issues:
⚠️ Found matching upstream commit but patch is missing proper reference to it
Found matching upstream commit: f06e108a3dc53c0f5234d18de0bd224753db5019
Note: The patch differs from the upstream commit:
---
1: f06e108a3dc53 < -: ------------- Compiler Attributes: disable __counted_by for clang < 19.1.3 -: ------------- > 1: fc85704c3dae5 Linux 6.15.2
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
Re: [PATCH 1/1] Compiler Attributes: disable __counted_by for clang < 19.1.3
Quoted 13 lines · Sasha Levin
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues:
⚠️ Found matching upstream commit but patch is missing proper reference to itFound matching upstream commit:
f06e108a3dc53c0f5234d18de0bd224753db5019Note: The patch differs from the upstream commit:
---1: f06e108a3dc53 < -: ------------- Compiler Attributes: disable __counted_by for clang < 19.1.3 -: ------------- > 1: fc85704c3dae5 Linux 6.15.2
Quoted 7 lines
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
I guess this patch has been erroneously picked up by the backport helper. This was the patch for upstream that already got into 6.13 and has already been applied to 6.12, 6.11 and backported to 6.6 back in December.
Best Regards
Jan