mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
The sigaltstack(2) system call fails with -ENOMEM if the new alternative signal stack is found to be smaller than SIGMINSTKSZ. On architectures such as arm64, where the native value for SIGMINSTKSZ is larger than the compat value, this can result in an unexpected error being reported to a compat task. See, for example: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=904385 This patch fixes the problem by extending do_sigaltstack to take the minimum signal stack size as an additional parameter, allowing the native and compat system call entry code to pass in their respective values. COMPAT_SIGMINSTKSZ is just defined as SIGMINSTKSZ if it has not been defined by the architecture. Cc: Arnd Bergmann <[email protected]> Cc: Dominik Brodowski <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Al Viro <[email protected]> Cc: Oleg Nesterov <[email protected]> Reported-by: Steve McIntyre <[email protected]> Tested-by: Steve McIntyre <[email protected]> Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Catalin Marinas <[email protected]>
This commit is contained in:
parent
03630b3b76
commit
22839869f2
2 changed files with 12 additions and 5 deletions
|
|
@ -3460,7 +3460,8 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
|
|||
}
|
||||
|
||||
static int
|
||||
do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp)
|
||||
do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp,
|
||||
size_t min_ss_size)
|
||||
{
|
||||
struct task_struct *t = current;
|
||||
|
||||
|
|
@ -3490,7 +3491,7 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp)
|
|||
ss_size = 0;
|
||||
ss_sp = NULL;
|
||||
} else {
|
||||
if (unlikely(ss_size < MINSIGSTKSZ))
|
||||
if (unlikely(ss_size < min_ss_size))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
@ -3508,7 +3509,8 @@ SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
|
|||
if (uss && copy_from_user(&new, uss, sizeof(stack_t)))
|
||||
return -EFAULT;
|
||||
err = do_sigaltstack(uss ? &new : NULL, uoss ? &old : NULL,
|
||||
current_user_stack_pointer());
|
||||
current_user_stack_pointer(),
|
||||
MINSIGSTKSZ);
|
||||
if (!err && uoss && copy_to_user(uoss, &old, sizeof(stack_t)))
|
||||
err = -EFAULT;
|
||||
return err;
|
||||
|
|
@ -3519,7 +3521,8 @@ int restore_altstack(const stack_t __user *uss)
|
|||
stack_t new;
|
||||
if (copy_from_user(&new, uss, sizeof(stack_t)))
|
||||
return -EFAULT;
|
||||
(void)do_sigaltstack(&new, NULL, current_user_stack_pointer());
|
||||
(void)do_sigaltstack(&new, NULL, current_user_stack_pointer(),
|
||||
MINSIGSTKSZ);
|
||||
/* squash all but EFAULT for now */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3553,7 +3556,8 @@ static int do_compat_sigaltstack(const compat_stack_t __user *uss_ptr,
|
|||
uss.ss_size = uss32.ss_size;
|
||||
}
|
||||
ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss,
|
||||
compat_user_stack_pointer());
|
||||
compat_user_stack_pointer(),
|
||||
COMPAT_MINSIGSTKSZ);
|
||||
if (ret >= 0 && uoss_ptr) {
|
||||
compat_stack_t old;
|
||||
memset(&old, 0, sizeof(old));
|
||||
|
|
|
|||
Loading…
Reference in a new issue