Skip to contentSkip to conversation

kunit/fortify: Add back "volatile" for sizeof() constants

PATCH In review Kees Cook 4 participants 6 messages Jun 28, 2025 – Jul 2, 2025

Subsystems (2)
lore
Share & tools
lore

Kees Cook

author maintainer
#0 lore raw

PATCH 1/1 kunit/fortify: Add back "volatile" for sizeof() constants

It seems the Clang can see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof. Adding "volatile" back to these variables solves this false positive without reintroducing the issues that originally led to switching to OPTIMIZER_HIDE_VAR in the first place[1].

Cc "Jannik Glückert" <[email protected]>
Fixes 6ee149f61bcc ("kunit/fortify: Replace "volatile" with OPTIMIZER_HIDE_VAR()")

---
Cc: <[email protected]>

---
 lib/tests/fortify_kunit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
lib/tests/fortify_kunit.c +2 -2
index 29ffc62a71e3..fc9c76f026d6 100644
@@ -1003,8 +1003,8 @@ static void fortify_test_memcmp(struct kunit *test)
 {
 	char one[] = "My mind is going ...";
 	char two[] = "My mind is going ... I can feel it.";
-	size_t one_len = sizeof(one) - 1;
-	size_t two_len = sizeof(two) - 1;
+	volatile size_t one_len = sizeof(one) - 1;
+	volatile size_t two_len = sizeof(two) - 1;
 
 	OPTIMIZER_HIDE_VAR(one_len);
 	OPTIMIZER_HIDE_VAR(two_len);
Signature · 1 line
2.34.1
Reviewed-by on v1 1/1
#1 lore raw
Quoted 11 lines · Kees Cook

It seems the Clang can see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof. Adding "volatile" back to these variables solves this false positive without reintroducing the issues that originally led to switching to OPTIMIZER_HIDE_VAR in the first place[1].

Cc "Jannik Glückert" <[email protected]>
Fixes 6ee149f61bcc ("kunit/fortify: Replace "volatile" with OPTIMIZER_HIDE_VAR()")
Quoted 24 lines

---
Cc: <[email protected]>

---
 lib/tests/fortify_kunit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
lib/tests/fortify_kunit.c +2 -2
index 29ffc62a71e3..fc9c76f026d6 100644
@@ -1003,8 +1003,8 @@ static void fortify_test_memcmp(struct kunit *test)
 {
 	char one[] = "My mind is going ...";
 	char two[] = "My mind is going ... I can feel it.";
-	size_t one_len = sizeof(one) - 1;
-	size_t two_len = sizeof(two) - 1;
+	volatile size_t one_len = sizeof(one) - 1;
+	volatile size_t two_len = sizeof(two) - 1;
 
 	OPTIMIZER_HIDE_VAR(one_len);
 	OPTIMIZER_HIDE_VAR(two_len);
Signature · 1 line
2.34.1
#2 lore raw
In reply to Kees Cook
Quoted 2 lines · Kees Cook

It seems the Clang can see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof.

Wait, what? That sounds extremely implausible/broken to me.

https://godbolt.org/z/ndeP5chcb also suggests that clang does not generally "see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof".

Do you have a minimal reproducer of what you're talking about?

author maintainer
#3 lore raw
Quoted 9 lines · Jann Horn
Quoted 2 lines · Kees Cook

It seems the Clang can see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof.

Wait, what? That sounds extremely implausible/broken to me.

https://godbolt.org/z/ndeP5chcb also suggests that clang does not generally "see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof".

I agree -- something is very unstable about this case, and it's been very frustrating to pin down.

Quoted 1 line

Do you have a minimal reproducer of what you're talking about?

I have not had the time to minimize it, no.

-Kees

Signature · 1 line
Kees Cook
#4 lore raw
Quoted 7 lines · Kees Cook
Quoted 6 lines · Jann Horn
Quoted 2 lines · Kees Cook

It seems the Clang can see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof.

Wait, what? That sounds extremely implausible/broken to me.

Agreed. 'sizeof' should be calculated by the front-end.

Quoted 11 lines
Quoted 3 lines

https://godbolt.org/z/ndeP5chcb also suggests that clang does not generally "see through OPTIMIZER_HIDE_VAR when the constant is coming from sizeof".

I agree -- something is very unstable about this case, and it's been very frustrating to pin down.

Quoted 1 line

Do you have a minimal reproducer of what you're talking about?

I have not had the time to minimize it, no.

OPTIMIZER_HIDE_VAR doesn't have a 'volatile' on it. Could that be it?

As a side note, the current definition:

__asm__ ("" : "=r" (var) : "0" (var))

seems like

__asm__ ("" : "+r" (var))

with extra steps.

-bw

#5 lore raw
Quoted 2 lines · Bill Wendling
Quoted 1 line · Kees Cook

I have not had the time to minimize it, no.

I can try to extract this into a minimal reproducer next week if nothing major crops up over the long weekend.

Quoted 1 line

OPTIMIZER_HIDE_VAR doesn't have a 'volatile' on it. Could that be it?

I tested

include/linux/compiler.h +1 -1
index 6f04a1d8c720..eab208a9a6f4 100644
@@ -160,7 +160,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 #ifndef OPTIMIZER_HIDE_VAR
 /* Make the optimizer believe the variable can be manipulated arbitrarily. */
 #define OPTIMIZER_HIDE_VAR(var)						\
-	__asm__ ("" : "=r" (var) : "0" (var))
+	__asm__ volatile("" : "=r" (var) : "0" (var))
 #endif
 
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)

but that did not resolve the error.

Cheers,
Nathan