From: David Laight <david.laight.linux@gmail.com>
To: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-sound@vger.kernel.org,
Herve Codina <herve.codina@bootlin.com>,
Mark Brown <broonie@kernel.org>
Subject: Re: [PATCH] ALSA: pcm: Convert multiple {get/put}_user to user_access_begin/user_access_end()
Date: Wed, 11 Jun 2025 22:37:10 +0100 [thread overview]
Message-ID: <20250611223710.254780d8@pumpkin> (raw)
In-Reply-To: <051e9722-44ad-4547-af5d-3e42c8cfe8d9@csgroup.eu>
On Wed, 11 Jun 2025 15:48:30 +0200
Christophe Leroy <christophe.leroy@csgroup.eu> wrote:
> Le 10/06/2025 à 21:53, David Laight a écrit :
> > On Sat, 7 Jun 2025 13:37:42 +0200
> > Christophe Leroy <christophe.leroy@csgroup.eu> wrote:
> >
> >> With user access protection (Called SMAP on x86 or KUAP on powerpc)
> >> each and every call to get_user() or put_user() performs heavy
> >> operations to unlock and lock kernel access to userspace.
> >>
> >> To avoid that, perform user accesses by blocks using
> >> user_access_begin/user_access_end() and unsafe_get_user()/
> >> unsafe_put_user() and alike.
> >
> > Did you consider using masked_user_access_begin() ?
> > It removes a conditional branch and lfence as well.
>
> Thanks, was not aware of that new function, allthought I remember some
> discussion about masked user access.
>
> Looks like this is specific to x86 at the time being.
I think it is two architectures.
But mostly requires a guard page between user and kernel and 'cmov'
if you want to avoid speculation 'issues' (and 'round tuits').
> I would have
> expected that to be transparent to the consumer. Allthought looking at
> strncpy_from_user() I understand the benefit of keeping it separate.
>
> However is it worth the effort and the ugliness of having to do (copied
> from fs/select.c):
>
> if (can_do_masked_user_access())
> from = masked_user_access_begin(from);
> else if (!user_read_access_begin(from, sizeof(*from)))
> return -EFAULT;
I proposed (uaccess: Simplify code pattern for masked user copies):
+#ifdef masked_user_access_begin
+#define masked_user_read_access_begin(from, size) \
+ ((*(from) = masked_user_access_begin(*(from))), 1)
+#define masked_user_write_access_begin(from, size) \
+ ((*(from) = masked_user_access_begin(*(from))), 1)
+#else
+#define masked_user_read_access_begin(from, size) \
+ user_read_access_begin(*(from), size)
+#define masked_user_write_access_begin(from, size) \
+ user_write_access_begin(*(from), size)
+#endif
Which allows the simple change
- if (!user_read_access_begin(from, sizeof(*from)))
+ if (!masked_user_read_access_begin(&from, sizeof(*from)))
return -EFAULT;
unsafe_get_user(xxx, &from->xxx, Efault);
But Linus said:
> I really dislike the use of "pass pointer to simple variable you are
> going to change" interfaces which is why I didn't do it this way.
But, in this case, you absolutely need the 'user pointer' updated.
So need to make it hard to code otherwise.
Note that it is best if masked_user_access_begin() returns the base
address of the guard page for kernel addresses (which amd64 now does)
rather than ~0.
Otherwise it is pretty imperative that the first access be to offset 0.
David
>
> In addition I would expect a masked_user_read_access_begin() and a
> masked_write_access_begin(). It looks odd (and would be wrong on
> powerpc) to not be able to differentiate between read and write in the
> begin yet using user_read_access_end() at the end, ref get_sigset_argpack()
>
> Christophe
prev parent reply other threads:[~2025-06-11 21:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-07 11:37 [PATCH] ALSA: pcm: Convert multiple {get/put}_user to user_access_begin/user_access_end() Christophe Leroy
2025-06-07 13:57 ` kernel test robot
2025-06-10 19:53 ` David Laight
2025-06-11 13:48 ` Christophe Leroy
2025-06-11 21:37 ` 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=20250611223710.254780d8@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=broonie@kernel.org \
--cc=christophe.leroy@csgroup.eu \
--cc=herve.codina@bootlin.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
/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.