aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-05-31 22:23:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-03-03 23:10:13 -0500
commit72537c48538933fe8982707fbf1ebbd7378b313b (patch)
tree18b4d4424eac14fd8c2268802043a631c9b7f3e2
parentff65503daa2bc060611ebfd5d391bcd4670363f3 (diff)
downloadsignal-72537c48538933fe8982707fbf1ebbd7378b313b.tar.gz
um/x86: merge sigreturn variants
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/x86/um/signal.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index ae7319db18ee36..9aa19c30b18607 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -243,6 +243,25 @@ static int copy_sc_from_user(struct pt_regs *regs,
return 0;
}
+static long do_sigreturn(struct sigcontext __user *sc, sigset_t *set)
+{
+ if (!set)
+ goto segfault;
+
+ set_current_blocked(set);
+
+ if (copy_sc_from_user(&current->thread.regs, sc))
+ goto segfault;
+
+ /* Avoid ERESTART handling */
+ PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
+
+ segfault:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
static int copy_sc_to_user(struct sigcontext __user *to,
struct _fpstate __user *to_fp, struct pt_regs *regs,
unsigned long mask)
@@ -468,28 +487,17 @@ long sys_sigreturn(void)
{
unsigned long sp = PT_REGS_SP(&current->thread.regs);
struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
- sigset_t set;
+ sigset_t set, *p = &set;
struct sigcontext __user *sc = &frame->sc;
unsigned long __user *oldmask = &sc->oldmask;
unsigned long __user *extramask = frame->extramask;
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
- if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
- copy_from_user(&set.sig[1], extramask, sig_size))
- goto segfault;
-
- set_current_blocked(&set);
+ if (copy_from_user(&p->sig[0], oldmask, sizeof(set.sig[0])) ||
+ copy_from_user(&p->sig[1], extramask, sig_size))
+ p = NULL;
- if (copy_sc_from_user(&current->thread.regs, sc))
- goto segfault;
-
- /* Avoid ERESTART handling */
- PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return PT_REGS_SYSCALL_RET(&current->thread.regs);
-
- segfault:
- force_sig(SIGSEGV, current);
- return 0;
+ return do_sigreturn(sc, p);
}
#else
@@ -583,21 +591,10 @@ long sys_rt_sigreturn(void)
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(sp - sizeof(long));
struct ucontext __user *uc = &frame->uc;
- sigset_t set;
-
- if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
- goto segfault;
+ sigset_t set, *p = &set;
- set_current_blocked(&set);
+ if (copy_from_user(p, &uc->uc_sigmask, sizeof(set)))
+ p = NULL;
- if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
- goto segfault;
-
- /* Avoid ERESTART handling */
- PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return PT_REGS_SYSCALL_RET(&current->thread.regs);
-
- segfault:
- force_sig(SIGSEGV, current);
- return 0;
+ return do_sigreturn(&uc->uc_mcontext, p);
}