diff --git a/include/linux/compat.h b/include/linux/compat.h index d8535a430caf..fab35daf8759 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -67,6 +67,9 @@ typedef struct compat_sigaltstack { compat_size_t ss_size; } compat_stack_t; #endif +#ifndef COMPAT_MINSIGSTKSZ +#define COMPAT_MINSIGSTKSZ MINSIGSTKSZ +#endif #define compat_jiffies_to_clock_t(x) \ (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) diff --git a/kernel/signal.c b/kernel/signal.c index 424306163edc..049929a5f4ce 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3116,7 +3116,8 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) } static int -do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp) +do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp, + size_t min_ss_size) { stack_t oss; int error; @@ -3155,9 +3156,8 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s ss_size = 0; ss_sp = NULL; } else { - error = -ENOMEM; - if (ss_size < MINSIGSTKSZ) - goto out; + if (unlikely(ss_size < min_ss_size)) + return -ENOMEM; } current->sas_ss_sp = (unsigned long) ss_sp; @@ -3180,12 +3180,14 @@ out: } SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss) { - return do_sigaltstack(uss, uoss, current_user_stack_pointer()); + return do_sigaltstack(uss, uoss, current_user_stack_pointer(), + MINSIGSTKSZ); } int restore_altstack(const stack_t __user *uss) { - int err = do_sigaltstack(uss, NULL, current_user_stack_pointer()); + int err = do_sigaltstack(uss, NULL, current_user_stack_pointer(), + MINSIGSTKSZ); /* squash all but EFAULT for now */ return err == -EFAULT ? err : 0; } @@ -3226,7 +3228,8 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack, set_fs(KERNEL_DS); ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL), (stack_t __force __user *) &uoss, - compat_user_stack_pointer()); + compat_user_stack_pointer(), + COMPAT_MINSIGSTKSZ); set_fs(seg); if (ret >= 0 && uoss_ptr) { if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(compat_stack_t)) ||