diff --git a/include/uapi/linux/signal.h b/include/uapi/linux/signal.h index e1bd50c29ded..7c73165d11ce 100644 --- a/include/uapi/linux/signal.h +++ b/include/uapi/linux/signal.h @@ -7,4 +7,7 @@ #define SS_ONSTACK 1 #define SS_DISABLE 2 +/* mask for all SS_xxx flags */ +#define SS_FLAG_BITS 0 + #endif /* _UAPI_LINUX_SIGNAL_H */ diff --git a/kernel/signal.c b/kernel/signal.c index aa9bf00749c1..b1c6eb4df2a8 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3104,7 +3104,8 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s if (uss) { void __user *ss_sp; size_t ss_size; - int ss_flags; + unsigned ss_flags; + int ss_mode; error = -EFAULT; if (!access_ok(VERIFY_READ, uss, sizeof(*uss))) @@ -3119,18 +3120,13 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s if (on_sig_stack(sp)) goto out; + ss_mode = ss_flags & ~SS_FLAG_BITS; error = -EINVAL; - /* - * Note - this code used to test ss_flags incorrectly: - * old code may have been written using ss_flags==0 - * to mean ss_flags==SS_ONSTACK (as this was the only - * way that worked) - this fix preserves that older - * mechanism. - */ - if (ss_flags != SS_DISABLE && ss_flags != SS_ONSTACK && ss_flags != 0) + if (ss_mode != SS_DISABLE && ss_mode != SS_ONSTACK && + ss_mode != 0) goto out; - if (ss_flags == SS_DISABLE) { + if (ss_mode == SS_DISABLE) { ss_size = 0; ss_sp = NULL; } else {