From: Catalin Marinas <catalin.marinas@arm.com>
To: Peter Collingbourne <pcc@google.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
Andrew Morton <akpm@linux-foundation.org>,
Kees Cook <kees@kernel.org>, Andy Shevchenko <andy@kernel.org>,
Andrey Konovalov <andreyknvl@gmail.com>,
Mark Rutland <mark.rutland@arm.com>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, stable@vger.kernel.org
Subject: Re: [PATCH v4 1/2] string: Add load_unaligned_zeropad() code path to sized_strscpy()
Date: Wed, 2 Apr 2025 21:10:41 +0100 [thread overview]
Message-ID: <Z-2ZwThH-7rkQW86@arm.com> (raw)
In-Reply-To: <20250329000338.1031289-2-pcc@google.com>
On Fri, Mar 28, 2025 at 05:03:36PM -0700, Peter Collingbourne wrote:
> diff --git a/lib/string.c b/lib/string.c
> index eb4486ed40d25..b632c71df1a50 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -119,6 +119,7 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count)
> if (count == 0 || WARN_ON_ONCE(count > INT_MAX))
> return -E2BIG;
>
> +#ifndef CONFIG_DCACHE_WORD_ACCESS
> #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
> /*
> * If src is unaligned, don't cross a page boundary,
> @@ -133,12 +134,14 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count)
> /* If src or dest is unaligned, don't do word-at-a-time. */
> if (((long) dest | (long) src) & (sizeof(long) - 1))
> max = 0;
> +#endif
> #endif
>
> /*
> - * read_word_at_a_time() below may read uninitialized bytes after the
> - * trailing zero and use them in comparisons. Disable this optimization
> - * under KMSAN to prevent false positive reports.
> + * load_unaligned_zeropad() or read_word_at_a_time() below may read
> + * uninitialized bytes after the trailing zero and use them in
> + * comparisons. Disable this optimization under KMSAN to prevent
> + * false positive reports.
> */
> if (IS_ENABLED(CONFIG_KMSAN))
> max = 0;
> @@ -146,7 +149,11 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count)
> while (max >= sizeof(unsigned long)) {
> unsigned long c, data;
>
> +#ifdef CONFIG_DCACHE_WORD_ACCESS
> + c = load_unaligned_zeropad(src+res);
> +#else
> c = read_word_at_a_time(src+res);
> +#endif
> if (has_zero(c, &data, &constants)) {
> data = prep_zero_mask(c, data, &constants);
> data = create_zero_mask(data);
Kees mentioned the scenario where this crosses the page boundary and we
pad the source with zeros. It's probably fine but there are 70+ cases
where the strscpy() return value is checked, I only looked at a couple.
Could we at least preserve the behaviour with regards to page boundaries
and keep the existing 'max' limiting logic? If I read the code
correctly, a fall back to reading one byte at a time from an unmapped
page would panic. We also get this behaviour if src[0] is reading from
an invalid address, though for arm64 the panic would be in
ex_handler_load_unaligned_zeropad() when count >= 8.
Reading across tag granule (but not across page boundary) and causing a
tag check fault would result in padding but we can live with this and
only architectures that do MTE-style tag checking would get the new
behaviour.
What I haven't checked is whether a tag check fault in
ex_handler_load_unaligned_zeropad() would confuse the KASAN logic for
MTE (it would be a second tag check fault while processing the first).
At a quick look, it seems ok but it might be worth checking.
--
Catalin
next prev parent reply other threads:[~2025-04-02 20:12 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-29 0:03 [PATCH v4 0/2] string: Add load_unaligned_zeropad() code path to sized_strscpy() Peter Collingbourne
2025-03-29 0:03 ` [PATCH v4 1/2] " Peter Collingbourne
2025-04-02 20:10 ` Catalin Marinas [this message]
2025-04-03 0:08 ` Peter Collingbourne
2025-04-03 9:46 ` Catalin Marinas
2025-04-03 21:15 ` David Laight
2025-03-29 0:03 ` [PATCH v4 2/2] kasan: Add strscpy() test to trigger tag fault on arm64 Peter Collingbourne
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=Z-2ZwThH-7rkQW86@arm.com \
--to=catalin.marinas@arm.com \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=andy@kernel.org \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=kees@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=pcc@google.com \
--cc=stable@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.