kernel/signal.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index dfcee3888b00..f58f1d574931 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -4161,7 +4161,6 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp, size_t min_ss_size) { struct task_struct *t = current; - int ret = 0; if (oss) { memset(oss, 0, sizeof(stack_t)); @@ -4181,8 +4180,15 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp, return -EPERM; ss_mode = ss_flags & ~SS_FLAG_BITS; - if (unlikely(ss_mode != SS_DISABLE && ss_mode != SS_ONSTACK && - ss_mode != 0)) + + if (ss_mode == SS_DISABLE) { + t->sas_ss_sp = 0; + t->sas_ss_size = 0; + t->sas_ss_flags = ss_flags; + return 0; + } + + if (unlikely(ss_mode != SS_ONSTACK && ss_mode != 0)) return -EINVAL; /* @@ -4194,24 +4200,20 @@ do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp, t->sas_ss_flags == ss_flags) return 0; + /* Is this lock really worth it? */ sigaltstack_lock(); - if (ss_mode == SS_DISABLE) { - ss_size = 0; - ss_sp = NULL; - } else { - if (unlikely(ss_size < min_ss_size)) - ret = -ENOMEM; - if (!sigaltstack_size_valid(ss_size)) - ret = -ENOMEM; - } - if (!ret) { - t->sas_ss_sp = (unsigned long) ss_sp; - t->sas_ss_size = ss_size; - t->sas_ss_flags = ss_flags; + if (unlikely(ss_size < min_ss_size) || + unlikely(sigaltstack_size_valid(ss_size))) { + sigaltstack_unlock(); + return -ENOMEM; } sigaltstack_unlock(); + + t->sas_ss_sp = (unsigned long) ss_sp; + t->sas_ss_size = ss_size; + t->sas_ss_flags = ss_flags; } - return ret; + return 0; } SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)