projects/linux·commit b040da2a

signal: use scoped user access in __save_altstack()

b040da2a · Linus Torvalds <[email protected]> · 2026-10-19 19:23:16 -10:00

__save_altstack() and __compat_save_altstack() write three fields with
__put_user(), relying on the caller having done access_ok() on the whole
signal frame.  Each of those writes enables and disables user access on
its own, so that check saves nothing.

x86 and powerpc already avoid these functions by using
unsafe_save_altstack() inside their own user access regions.  Use the
same helpers here, inside a scoped_user_write_access(), so that every
other architecture gets a single range check and a single user access
region too.  None of those callers is itself inside a user access
region, so nothing nests.

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

Signed-off-by: Linus Torvalds <[email protected]>
Commit
b040da2a0046ae64eeeed256b4465f231d5ee6de
Parents
5c859015

Changes

1 files changed · +12 −12

FileStatusAddDelContent
kernel/signal.cmodified+12−12View file

kernel/signal.c

View file
diff --git a/kernel/signal.c b/kernel/signal.c
index fb719fa..fa652f7 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -4539,11 +4539,12 @@ int restore_altstack(const stack_t __user *uss)
int __save_altstack(stack_t __user *uss, unsigned long sp)
{
- struct task_struct *t = current;
- int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) |
- __put_user(t->sas_ss_flags, &uss->ss_flags) |
- __put_user(t->sas_ss_size, &uss->ss_size);
- return err;
+ scoped_user_write_access(uss, Efault)
+ unsafe_save_altstack(uss, sp, Efault);
+ return 0;
+
+Efault:
+ return -EFAULT;
}
#ifdef CONFIG_COMPAT
@@ -4592,13 +4593,12 @@ int compat_restore_altstack(const compat_stack_t __user *uss)
int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
{
- int err;
- struct task_struct *t = current;
- err = __put_user(ptr_to_compat((void __user *)t->sas_ss_sp),
- &uss->ss_sp) |
- __put_user(t->sas_ss_flags, &uss->ss_flags) |
- __put_user(t->sas_ss_size, &uss->ss_size);
- return err;
+ scoped_user_write_access(uss, Efault)
+ unsafe_compat_save_altstack(uss, sp, Efault);
+ return 0;
+
+Efault:
+ return -EFAULT;
}
#endif