Commit 04a73247 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] signal-race fixes for s390

  Update s30 for the signal race fix

From: Mikael Pettersson <mikpe@csd.uu.se>

  The signal-race-fixes patch in 2.6.8-rc2-mm1 appears to be a bit broken on
  s390.

  When forcing a SIGSEGV the old code updated "*ka", where ka was a pointer
  to current's k_sigaction for SIGSEGV.  Now "ka_copy" points to a copy of
  that structure, so assigning "*ka_copy" doesn't do what we want.  Instead do
  the assignment via current->...  just like i386 and x86_64 do.

  Furthermore, the SA_ONESHOT handling wasn't deleted.  That is now handled
  by generic code in the kernel.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ffe362b0
...@@ -610,20 +610,15 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -610,20 +610,15 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
*/ */
void void
handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset, handle_signal32(unsigned long sig, struct k_sigaction *ka,
struct pt_regs * regs) siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{ {
struct k_sigaction *ka = &current->sighand->action[sig-1];
/* Set up the stack frame */ /* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame32(sig, ka, info, oldset, regs); setup_rt_frame32(sig, ka, info, oldset, regs);
else else
setup_frame32(sig, ka, oldset, regs); setup_frame32(sig, ka, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) { if (!(ka->sa.sa_flags & SA_NODEFER)) {
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);
......
...@@ -420,20 +420,15 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, ...@@ -420,20 +420,15 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/ */
static void static void
handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, handle_signal(unsigned long sig, struct k_sigaction *ka,
struct pt_regs * regs) siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{ {
struct k_sigaction *ka = &current->sighand->action[sig-1];
/* Set up the stack frame */ /* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO) if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame(sig, ka, info, oldset, regs); setup_rt_frame(sig, ka, info, oldset, regs);
else else
setup_frame(sig, ka, oldset, regs); setup_frame(sig, ka, oldset, regs);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) { if (!(ka->sa.sa_flags & SA_NODEFER)) {
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);
...@@ -457,6 +452,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -457,6 +452,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
unsigned long retval = 0, continue_addr = 0, restart_addr = 0; unsigned long retval = 0, continue_addr = 0, restart_addr = 0;
siginfo_t info; siginfo_t info;
int signr; int signr;
struct k_sigaction ka;
/* /*
* We want the common case to go fast, which * We want the common case to go fast, which
...@@ -490,7 +486,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -490,7 +486,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* Get signal to deliver. When running under ptrace, at this point /* Get signal to deliver. When running under ptrace, at this point
the debugger may change all our registers ... */ the debugger may change all our registers ... */
signr = get_signal_to_deliver(&info, regs, NULL); signr = get_signal_to_deliver(&info, &ka, regs, NULL);
/* Depending on the signal settings we may need to revert the /* Depending on the signal settings we may need to revert the
decision to restart the system call. */ decision to restart the system call. */
...@@ -509,14 +505,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) ...@@ -509,14 +505,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
#ifdef CONFIG_S390_SUPPORT #ifdef CONFIG_S390_SUPPORT
if (test_thread_flag(TIF_31BIT)) { if (test_thread_flag(TIF_31BIT)) {
extern void handle_signal32(unsigned long sig, extern void handle_signal32(unsigned long sig,
struct k_sigaction *ka,
siginfo_t *info, siginfo_t *info,
sigset_t *oldset, sigset_t *oldset,
struct pt_regs *regs); struct pt_regs *regs);
handle_signal32(signr, &info, oldset, regs); handle_signal32(signr, &ka, &info, oldset, regs);
return 1; return 1;
} }
#endif #endif
handle_signal(signr, &info, oldset, regs); handle_signal(signr, &ka, &info, oldset, regs);
return 1; return 1;
} }
......
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