Re: [PATCH next 2/3] fortify: Optimise strnlen()

Kees Cook
2026-03-31T15:56:59Z

On Tue, Mar 31, 2026 at 03:55:41PM +0100, David Laight wrote:
> On Tue, 31 Mar 2026 11:14:28 +0100
> David Laight <david.laight.linux@gmail.com> wrote:
>
> > On Mon, 30 Mar 2026 23:36:07 -0700
> > Kees Cook <kees@kernel.org> wrote:
> >
> > > On Mon, Mar 30, 2026 at 02:20:02PM +0100, david.laight.linux@gmail.com wrote:
> > > > From: David Laight <david.laight.linux@gmail.com>
> > > >
> > > > If the string is constant there is no need to call __real_strlen()
> > > > even when maxlen is a variable - just return the smaller value.
> > > >
> > > > If the size of the string variable is unknown fortify_panic() can't be
> > > > called, change the condition so that the compiler can optimise it away.
> > > >
> > > > Change __compiletime_strlen(p) to return a 'non-constant' value
> > > > for non-constant strings (the same as __builtin_strlen()).
> > > > Simplify since it is only necessary to check that the size is constant
> > > > and that the last character is '\0'.
> > > > Explain why it is different from __builtin_strlen().
> > > > Update the kunit tests to match.
> > >
> > > See also
> > > commit d07c0acb4f41 ("fortify: Fix __compiletime_strlen() under UBSAN_BOUNDS_LOCAL")
> > >
> > > -Kees
> ...

Your series does pass all the wacky corner case tests that got added
over the years, though I need to go through older GCC and Clang releases
to double-check. I've pushed a branch to kernel.org for 0day testing:
https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/log/?h=dev/v7.0-rc2/fortify-strlen

> > That really means you can only use __builtin_strlen().
> > Which means you'll get a compile-time error from:
> > char foo[3] = "foo";
> > __builtin_strlen(foo);
> > rather the 'not a constant' when checking strscpy(tgt, foo, 3);
> > At a guess that never happens except in the tests.
>
> I wrote this change a while ago, I tried using __builtin_strlen()
> but got a compile error in the tests.
>
> However I've just built an x86-64 allmodconfig kernel on top of
> my patches with:
> #define __compiletime_strlen(p) __builtin_strlen()
> so something must have changed since then (probably related to the
> __nonstring changes).
>
> So the actual fix for the above is to use __builtin_strlen().
> IIRC it also detects a few more strings being constant.

Hrm, the "no NUL in the string" case is a weird one, but yeah, probably
hit by the __nonstring work.

Can you write up new test cases to validate what you're after? I can
update the branch I pushed.

-Kees

--
Kees Cook