lib/tests/fortify_kunit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
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].
Reported-by: Nathan Chancellor <nathan@kernel.org>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2075 [1]
Cc: "Jannik Glückert" <jannik.glueckert@gmail.com>
Suggested-by: Nathan Chancellor <nathan@kernel.org>
Fixes: 6ee149f61bcc ("kunit/fortify: Replace "volatile" with OPTIMIZER_HIDE_VAR()")
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: <linux-hardening@vger.kernel.org>
---
lib/tests/fortify_kunit.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/tests/fortify_kunit.c b/lib/tests/fortify_kunit.c
index 29ffc62a71e3..fc9c76f026d6 100644
--- a/lib/tests/fortify_kunit.c
+++ b/lib/tests/fortify_kunit.c
@@ -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);
--
2.34.1
On Sun, Jun 29, 2025 at 1:40 AM Kees Cook <kees@kernel.org> wrote: > 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?
On Tue, Jul 01, 2025 at 03:41:35PM +0200, Jann Horn wrote: > On Sun, Jun 29, 2025 at 1:40 AM Kees Cook <kees@kernel.org> wrote: > > 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. > Do you have a minimal reproducer of what you're talking about? I have not had the time to minimize it, no. -Kees -- Kees Cook
On Tue, Jul 1, 2025 at 9:27 AM Kees Cook <kees@kernel.org> wrote: > On Tue, Jul 01, 2025 at 03:41:35PM +0200, Jann Horn wrote: > > On Sun, Jun 29, 2025 at 1:40 AM Kees Cook <kees@kernel.org> wrote: > > > 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. > > 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. > > > 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
On Tue, Jul 01, 2025 at 10:38:36AM -0700, Bill Wendling wrote: > On Tue, Jul 1, 2025 at 9:27 AM Kees Cook <kees@kernel.org> wrote: > > 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. > OPTIMIZER_HIDE_VAR doesn't have a 'volatile' on it. Could that be it? I tested diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 6f04a1d8c720..eab208a9a6f4 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -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
On Sat, Jun 28, 2025 at 04:40:38PM -0700, Kees Cook wrote: > 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]. > > Reported-by: Nathan Chancellor <nathan@kernel.org> > Closes: https://github.com/ClangBuiltLinux/linux/issues/2075 [1] > Cc: "Jannik Glückert" <jannik.glueckert@gmail.com> > Suggested-by: Nathan Chancellor <nathan@kernel.org> > Fixes: 6ee149f61bcc ("kunit/fortify: Replace "volatile" with OPTIMIZER_HIDE_VAR()") > Signed-off-by: Kees Cook <kees@kernel.org> Reviewed-by: Nathan Chancellor <nathan@kernel.org> > --- > Cc: <linux-hardening@vger.kernel.org> > --- > lib/tests/fortify_kunit.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/lib/tests/fortify_kunit.c b/lib/tests/fortify_kunit.c > index 29ffc62a71e3..fc9c76f026d6 100644 > --- a/lib/tests/fortify_kunit.c > +++ b/lib/tests/fortify_kunit.c > @@ -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); > -- > 2.34.1 >
© 2016 - 2025 Red Hat, Inc.