From: David Laight <david.laight.linux@gmail.com>
To: Fuad Tabba <tabba@google.com>
Cc: Kees Cook <kees@kernel.org>, Andy Shevchenko <andy@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org,
will@kernel.org
Subject: Re: [PATCH] lib/string: Fix UBSAN misaligned access in sized_strscpy
Date: Wed, 25 Feb 2026 14:40:21 +0000 [thread overview]
Message-ID: <20260225144021.61ba508e@pumpkin> (raw)
In-Reply-To: <CA+EHjTzCFAecmjkX5iYJ99GqCsJhT6T5ONCSFMDh=khNG6MzTA@mail.gmail.com>
On Wed, 25 Feb 2026 08:08:34 +0000
Fuad Tabba <tabba@google.com> wrote:
...
> I also noticed that the read path already expects and handles
> unaligned addresses. If you look at load_unaligned_zeropad() (called
> above the write), it explicitly loads an unaligned word and handles
> potential page-crossing faults. The write path lacked the equivalent
> put_unaligned() wrapper, leaving it exposed to UB.
Not really, the read side is doing reads that might go past the '\0'
that terminates the string.
If they are misaligned they can fault even though the string is
correctly terminated.
OTOH the write side must not write beyond the terminating '\0'
so the memory must always be there.
I didn't look at exactly how the 'word at a time' version terminates.
For strlen() doing it at all is pretty marginal for 32bit.
For strcpy() it may depend on whether the byte writes get merged
it the cpu's store buffer.
On 64bit you have to try quite hard to stop the compiler making
'a right pigs breakfast' of generating the constants; it is pretty
bad on x64-64, mips64 is a lot worse.
On LE with fast 'bit scan' you can quickly determine the number of
partial bytes - so they can be written without re-reading from
memory.
The actual problem with that version of strlen() is that it is
only faster for strings above (about and IIRC) 64 bytes long.
So in the kernel it is pretty much a complete waste of time.
The same is probably true for strscpy().
My guess is that the fastest code uses the 'unrolled once' loop:
do {
if ((dst[len] = src[len]) == 0)
break;
if ((dst[len + 1] = src[len + 1]) == 0) {
len++;
break;
}
} while ((len += 2) < lim);
(Provided it gets compiled reasonably).
Without the writes that was pretty much the best strlen() on the few cpu
I tried it on.
David
prev parent reply other threads:[~2026-02-25 14:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 17:04 [PATCH] lib/string: Fix UBSAN misaligned access in sized_strscpy Fuad Tabba
2026-02-24 17:21 ` Andy Shevchenko
2026-02-24 17:54 ` Fuad Tabba
2026-02-24 23:06 ` David Laight
2026-02-25 8:33 ` Fuad Tabba
2026-02-25 10:11 ` David Laight
2026-02-25 11:09 ` Fuad Tabba
2026-02-24 21:07 ` Kees Cook
2026-02-25 8:08 ` Fuad Tabba
2026-02-25 9:32 ` Andy Shevchenko
2026-02-25 14:40 ` David Laight [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260225144021.61ba508e@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=andy@kernel.org \
--cc=kees@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tabba@google.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox