Commit 85695322 authored by David S. Miller's avatar David S. Miller Committed by Linus Torvalds

[PATCH] signal handling race fixes: sparc and sparc64

Ok, here are the sparc64 and sparc32 versions.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e320343c
...@@ -1036,8 +1036,6 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, ...@@ -1036,8 +1036,6 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
else else
setup_frame(&ka->sa, regs, signr, oldset, info); setup_frame(&ka->sa, regs, signr, oldset, info);
} }
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NOMASK)) { if (!(ka->sa.sa_flags & SA_NOMASK)) {
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
...@@ -1077,6 +1075,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1077,6 +1075,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
{ {
siginfo_t info; siginfo_t info;
struct sparc_deliver_cookie cookie; struct sparc_deliver_cookie cookie;
struct k_sigaction ka;
int signr; int signr;
/* /*
...@@ -1096,15 +1095,12 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -1096,15 +1095,12 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (!oldset) if (!oldset)
oldset = &current->blocked; oldset = &current->blocked;
signr = get_signal_to_deliver(&info, regs, &cookie); signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
if (signr > 0) { if (signr > 0) {
struct k_sigaction *ka;
ka = &current->sighand->action[signr-1];
if (cookie.restart_syscall) if (cookie.restart_syscall)
syscall_restart(cookie.orig_i0, regs, &ka->sa); syscall_restart(cookie.orig_i0, regs, &ka.sa);
handle_signal(signr, ka, &info, oldset, regs, svr4_signal); handle_signal(signr, &ka, &info, oldset,
regs, svr4_signal);
return 1; return 1;
} }
if (cookie.restart_syscall && if (cookie.restart_syscall &&
......
...@@ -574,8 +574,6 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, ...@@ -574,8 +574,6 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
{ {
setup_rt_frame(ka, regs, signr, oldset, setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NOMASK)) { if (!(ka->sa.sa_flags & SA_NOMASK)) {
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
...@@ -615,6 +613,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -615,6 +613,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
{ {
siginfo_t info; siginfo_t info;
struct signal_deliver_cookie cookie; struct signal_deliver_cookie cookie;
struct k_sigaction ka;
int signr; int signr;
cookie.restart_syscall = restart_syscall; cookie.restart_syscall = restart_syscall;
...@@ -632,15 +631,11 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs, ...@@ -632,15 +631,11 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
} }
#endif #endif
signr = get_signal_to_deliver(&info, regs, &cookie); signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
if (signr > 0) { if (signr > 0) {
struct k_sigaction *ka;
ka = &current->sighand->action[signr-1];
if (cookie.restart_syscall) if (cookie.restart_syscall)
syscall_restart(orig_i0, regs, &ka->sa); syscall_restart(orig_i0, regs, &ka.sa);
handle_signal(signr, ka, &info, oldset, regs); handle_signal(signr, &ka, &info, oldset, regs);
return 1; return 1;
} }
if (cookie.restart_syscall && if (cookie.restart_syscall &&
......
...@@ -1227,8 +1227,6 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, ...@@ -1227,8 +1227,6 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
else else
setup_frame32(&ka->sa, regs, signr, oldset, info); setup_frame32(&ka->sa, regs, signr, oldset, info);
} }
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NOMASK)) { if (!(ka->sa.sa_flags & SA_NOMASK)) {
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
...@@ -1268,21 +1266,19 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs, ...@@ -1268,21 +1266,19 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
{ {
siginfo_t info; siginfo_t info;
struct signal_deliver_cookie cookie; struct signal_deliver_cookie cookie;
struct k_sigaction ka;
int signr; int signr;
int svr4_signal = current->personality == PER_SVR4; int svr4_signal = current->personality == PER_SVR4;
cookie.restart_syscall = restart_syscall; cookie.restart_syscall = restart_syscall;
cookie.orig_i0 = orig_i0; cookie.orig_i0 = orig_i0;
signr = get_signal_to_deliver(&info, regs, &cookie); signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
if (signr > 0) { if (signr > 0) {
struct k_sigaction *ka;
ka = &current->sighand->action[signr-1];
if (cookie.restart_syscall) if (cookie.restart_syscall)
syscall_restart32(orig_i0, regs, &ka->sa); syscall_restart32(orig_i0, regs, &ka.sa);
handle_signal32(signr, ka, &info, oldset, regs, svr4_signal); handle_signal32(signr, &ka, &info, oldset,
regs, svr4_signal);
return 1; return 1;
} }
if (cookie.restart_syscall && if (cookie.restart_syscall &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment