Skip to contentSkip to conversation

gcov: Disable GCOV_PROFILE_ALL on 32-bit UML with Clang 20/21

PATCH Superseded Kees Cook 2 participants 3 messages Apr 8 – Apr 9

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Kees Cook

author
#0 lore raw

PATCH v2 1/1 gcov: Disable GCOV_PROFILE_ALL on 32-bit UML with Clang 20/21

Clang 20 and 21 miscompute __builtin_object_size() when -fprofile-arcs is active on 32-bit UML targets, which passes incorrect object size calculations for local variables through always_inline copy_to_user() and check_copy_size(), causing spurious compile-time errors:

include/linux/ucopysize.h:52:4: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small

The regression was introduced in LLVM commit 02b8ee281947 ("[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound"), which shipped in Clang 20. It was fixed in LLVM by commit 45b697e610fd ("[MemoryBuiltins] Consider index type size when aggregating gep offsets"), which was backported to the LLVM 22.x release branch.

The bug requires 32-bit UML + GCOV_PROFILE_ALL (which uses -fprofile-arcs), though the exact trigger depends on optimizer decisions influenced by other enabled configs.

Prevent the broken combination by disabling GCOV_PROFILE_ALL on 32-bit UML when using Clang 20.x or 21.x.

---
v2: fixed typo in version comparison: needed < not <= (Sashiko)
v1: https://lore.kernel.org/lkml/[email protected]/
Cc: Peter Oberparleiter <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: <[email protected]>

---
 kernel/gcov/Kconfig | 3 +++
 1 file changed, 3 insertions(+)
kernel/gcov/Kconfig +3 -0
index 04f4ebdc3cf5..56abff785654 100644
@@ -42,6 +42,9 @@ config GCOV_PROFILE_ALL
 	depends on !COMPILE_TEST
 	depends on GCOV_KERNEL
 	depends on ARCH_HAS_GCOV_PROFILE_ALL
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit UML, causing spurious compile-time errors in check_copy_size().
+	depends on !(UML && !64BIT && CC_IS_CLANG && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)
 	default n
 	help
 	This options activates profiling for the entire kernel.
Signature · 1 line
2.34.1
#1 lore raw
Quoted 43 lines · Kees Cook

Clang 20 and 21 miscompute __builtin_object_size() when -fprofile-arcs is active on 32-bit UML targets, which passes incorrect object size calculations for local variables through always_inline copy_to_user() and check_copy_size(), causing spurious compile-time errors:

include/linux/ucopysize.h:52:4: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small

The regression was introduced in LLVM commit 02b8ee281947 ("[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound"), which shipped in Clang 20. It was fixed in LLVM by commit 45b697e610fd ("[MemoryBuiltins] Consider index type size when aggregating gep offsets"), which was backported to the LLVM 22.x release branch.

The bug requires 32-bit UML + GCOV_PROFILE_ALL (which uses -fprofile-arcs), though the exact trigger depends on optimizer decisions influenced by other enabled configs.

Prevent the broken combination by disabling GCOV_PROFILE_ALL on 32-bit UML when using Clang 20.x or 21.x.

---
v2: fixed typo in version comparison: needed < not <= (Sashiko)
v1: https://lore.kernel.org/lkml/[email protected]/
Cc: Peter Oberparleiter <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: <[email protected]>

---
 kernel/gcov/Kconfig | 3 +++
 1 file changed, 3 insertions(+)
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +0 -0
index 04f4ebdc3cf5..56abff785654 100644

kernel/gcov/Kconfi config GCOV_PROFILE_ALL · line 44

Quoted 3 lines
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +0 -0
@@ -42,6 +42,9 @@ config GCOV_PROFILE_ALL
 	depends on !COMPILE_TEST
 	depends on GCOV_KERNEL
 	depends on ARCH_HAS_GCOV_PROFILE_ALL

Would it be better to avoid selecting this symbol in arch/um/Kconfig when we have this condition?

kernel/gcov/Kconfi config GCOV_PROFILE_ALL · line 47

Quoted 3 lines
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +3 -0
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit UML, causing spurious compile-time errors in check_copy_size().
+	depends on !(UML && !64BIT && CC_IS_CLANG && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)

Given that you have an inclusive range above 0, you could drop the CC_IS_CLANG.

With the suggestion above it would just become:

arch/um/Kconfig +3 -1
index 098cda44db22..d9541d13d9eb 100644
@@ -11,7 +11,9 @@ config UML
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_FORTIFY_SOURCE
-	select ARCH_HAS_GCOV_PROFILE_ALL
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit, causing spurious compile-time errors in check_copy_size().
+	select ARCH_HAS_GCOV_PROFILE_ALL if !(!64BIT && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_STRNCPY_FROM_USER
 	select ARCH_HAS_STRNLEN_USER

--

Cheers,
Nathan

author
#2 lore raw
Quoted 64 lines · Nathan Chancellor
Quoted 43 lines · Kees Cook

Clang 20 and 21 miscompute __builtin_object_size() when -fprofile-arcs is active on 32-bit UML targets, which passes incorrect object size calculations for local variables through always_inline copy_to_user() and check_copy_size(), causing spurious compile-time errors:

include/linux/ucopysize.h:52:4: error: call to '__bad_copy_from' declared with 'error' attribute: copy source size is too small

The regression was introduced in LLVM commit 02b8ee281947 ("[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound"), which shipped in Clang 20. It was fixed in LLVM by commit 45b697e610fd ("[MemoryBuiltins] Consider index type size when aggregating gep offsets"), which was backported to the LLVM 22.x release branch.

The bug requires 32-bit UML + GCOV_PROFILE_ALL (which uses -fprofile-arcs), though the exact trigger depends on optimizer decisions influenced by other enabled configs.

Prevent the broken combination by disabling GCOV_PROFILE_ALL on 32-bit UML when using Clang 20.x or 21.x.

---
v2: fixed typo in version comparison: needed < not <= (Sashiko)
v1: https://lore.kernel.org/lkml/[email protected]/
Cc: Peter Oberparleiter <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: <[email protected]>

---
 kernel/gcov/Kconfig | 3 +++
 1 file changed, 3 insertions(+)
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +0 -0
index 04f4ebdc3cf5..56abff785654 100644

kernel/gcov/Kconfi config GCOV_PROFILE_ALL · line 44

Quoted 3 lines
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +0 -0
@@ -42,6 +42,9 @@ config GCOV_PROFILE_ALL
 	depends on !COMPILE_TEST
 	depends on GCOV_KERNEL
 	depends on ARCH_HAS_GCOV_PROFILE_ALL

Would it be better to avoid selecting this symbol in arch/um/Kconfig when we have this condition?

kernel/gcov/Kconfi config GCOV_PROFILE_ALL · line 47

Quoted 3 lines
kernel/gcov/Kconfi renamed from kernel/gcov/Kconfig +3 -0
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit UML, causing spurious compile-time errors in check_copy_size().
+	depends on !(UML && !64BIT && CC_IS_CLANG && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)

Given that you have an inclusive range above 0, you could drop the CC_IS_CLANG.

With the suggestion above it would just become:

arch/um/Kconfig +0 -0
index 098cda44db22..d9541d13d9eb 100644

arch/um/Kconfig config UML · line 19

Quoted 10 lines
arch/um/Kconfig +3 -1
@@ -11,7 +11,9 @@ config UML
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_FORTIFY_SOURCE
-	select ARCH_HAS_GCOV_PROFILE_ALL
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit, causing spurious compile-time errors in check_copy_size().
+	select ARCH_HAS_GCOV_PROFILE_ALL if !(!64BIT && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_STRNCPY_FROM_USER
 	select ARCH_HAS_STRNLEN_USER

That is a lot nicer; yeah. I will use this and send a v3.

Signature · 1 line
Kees Cook