compat: use scoped user access in get_compat_sigevent()

get_compat_sigevent() does one access_ok() on the user structure and
then reads four fields with __get_user().  Each of those reads enables
and disables user access on its own, so the single range check no longer
buys anything.

Read the fields inside a scoped_user_read_access() instead.

This is part of getting rid of __get_user() and __put_user() entirely.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2026-10-19 19:23:18 -10:00
parent b040da2a00
commit ae78eff333

View File

@ -180,14 +180,18 @@ int get_compat_sigevent(struct sigevent *event,
const struct compat_sigevent __user *u_event)
{
memset(event, 0, sizeof(*event));
return (!access_ok(u_event, sizeof(*u_event)) ||
__get_user(event->sigev_value.sival_int,
&u_event->sigev_value.sival_int) ||
__get_user(event->sigev_signo, &u_event->sigev_signo) ||
__get_user(event->sigev_notify, &u_event->sigev_notify) ||
__get_user(event->sigev_notify_thread_id,
&u_event->sigev_notify_thread_id))
? -EFAULT : 0;
scoped_user_read_access(u_event, Efault) {
unsafe_get_user(event->sigev_value.sival_int,
&u_event->sigev_value.sival_int, Efault);
unsafe_get_user(event->sigev_signo, &u_event->sigev_signo, Efault);
unsafe_get_user(event->sigev_notify, &u_event->sigev_notify, Efault);
unsafe_get_user(event->sigev_notify_thread_id,
&u_event->sigev_notify_thread_id, Efault);
}
return 0;
Efault:
return -EFAULT;
}
long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,