aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 21:11:45 -0400
commitf9369910a6225b8d4892c3f20ae740a711cd5ace (patch)
tree8650ff79d7607bceb35509c028400ecf1c317de0 /arch/cris
parent05f144a0d5c2207a0349348127f996e104ad7404 (diff)
parent415d04d08fec74b226c92c1fb54ad117c9c6bac4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull first series of signal handling cleanups from Al Viro: "This is just the first part of the queue (about a half of it); assorted fixes all over the place in signal handling. This one ends with all sigsuspend() implementations switched to generic one (->saved_sigmask-based). With this, a bunch of assorted old buglets are fixed and most of the missing bits of NOTIFY_RESUME hookup are in place. Two more fixes sit in arm and um trees respectively, and there's a couple of broken ones that need obvious fixes - parisc and avr32 check TIF_NOTIFY_RESUME only on one of two codepaths; fixes for that will happen in the next series" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (55 commits) unicore32: if there's no handler we need to restore sigmask, syscall or no syscall xtensa: add handling of TIF_NOTIFY_RESUME microblaze: drop 'oldset' argument of do_notify_resume() microblaze: handle TIF_NOTIFY_RESUME score: add handling of NOTIFY_RESUME to do_notify_resume() m68k: add TIF_NOTIFY_RESUME and handle it. sparc: kill ancient comment in sparc_sigaction() h8300: missing checks of __get_user()/__put_user() return values frv: missing checks of __get_user()/__put_user() return values cris: missing checks of __get_user()/__put_user() return values powerpc: missing checks of __get_user()/__put_user() return values sh: missing checks of __get_user()/__put_user() return values sparc: missing checks of __get_user()/__put_user() return values avr32: struct old_sigaction is never used m32r: struct old_sigaction is never used xtensa: xtensa_sigaction doesn't exist alpha: tidy signal delivery up score: don't open-code force_sigsegv() cris: don't open-code force_sigsegv() blackfin: don't open-code force_sigsegv() ...
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/arch-v10/kernel/signal.c50
-rw-r--r--arch/cris/arch-v32/kernel/signal.c66
2 files changed, 31 insertions, 85 deletions
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 289c584ba499..e16f8f297f61 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -48,19 +48,11 @@ void do_signal(int canrestart, struct pt_regs *regs);
48 * dummy arguments to be able to reach the regs argument. (Note that this 48 * dummy arguments to be able to reach the regs argument. (Note that this
49 * arrangement relies on old_sigset_t occupying one register.) 49 * arrangement relies on old_sigset_t occupying one register.)
50 */ 50 */
51int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 51int sys_sigsuspend(old_sigset_t mask)
52 long srp, struct pt_regs *regs)
53{ 52{
54 mask &= _BLOCKABLE; 53 sigset_t blocked;
55 spin_lock_irq(&current->sighand->siglock); 54 siginitset(&blocked, mask);
56 current->saved_sigmask = current->blocked; 55 return sigsuspend(&blocked);
57 siginitset(&current->blocked, mask);
58 recalc_sigpending();
59 spin_unlock_irq(&current->sighand->siglock);
60 current->state = TASK_INTERRUPTIBLE;
61 schedule();
62 set_thread_flag(TIF_RESTORE_SIGMASK);
63 return -ERESTARTNOHAND;
64} 56}
65 57
66int sys_sigaction(int sig, const struct old_sigaction __user *act, 58int sys_sigaction(int sig, const struct old_sigaction __user *act,
@@ -73,10 +65,10 @@ int sys_sigaction(int sig, const struct old_sigaction __user *act,
73 old_sigset_t mask; 65 old_sigset_t mask;
74 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 66 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
75 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 67 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
76 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 68 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
69 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
70 __get_user(mask, &act->sa_mask))
77 return -EFAULT; 71 return -EFAULT;
78 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
79 __get_user(mask, &act->sa_mask);
80 siginitset(&new_ka.sa.sa_mask, mask); 72 siginitset(&new_ka.sa.sa_mask, mask);
81 } 73 }
82 74
@@ -85,10 +77,10 @@ int sys_sigaction(int sig, const struct old_sigaction __user *act,
85 if (!ret && oact) { 77 if (!ret && oact) {
86 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 78 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
87 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 79 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
88 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 80 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
81 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
82 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
89 return -EFAULT; 83 return -EFAULT;
90 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
91 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
92 } 84 }
93 85
94 return ret; 86 return ret;
@@ -185,10 +177,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
185 goto badframe; 177 goto badframe;
186 178
187 sigdelsetmask(&set, ~_BLOCKABLE); 179 sigdelsetmask(&set, ~_BLOCKABLE);
188 spin_lock_irq(&current->sighand->siglock); 180 set_current_blocked(&set);
189 current->blocked = set;
190 recalc_sigpending();
191 spin_unlock_irq(&current->sighand->siglock);
192 181
193 if (restore_sigcontext(regs, &frame->sc)) 182 if (restore_sigcontext(regs, &frame->sc))
194 goto badframe; 183 goto badframe;
@@ -224,10 +213,7 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
224 goto badframe; 213 goto badframe;
225 214
226 sigdelsetmask(&set, ~_BLOCKABLE); 215 sigdelsetmask(&set, ~_BLOCKABLE);
227 spin_lock_irq(&current->sighand->siglock); 216 set_current_blocked(&set);
228 current->blocked = set;
229 recalc_sigpending();
230 spin_unlock_irq(&current->sighand->siglock);
231 217
232 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 218 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
233 goto badframe; 219 goto badframe;
@@ -469,15 +455,9 @@ static inline int handle_signal(int canrestart, unsigned long sig,
469 else 455 else
470 ret = setup_frame(sig, ka, oldset, regs); 456 ret = setup_frame(sig, ka, oldset, regs);
471 457
472 if (ret == 0) { 458 if (ret == 0)
473 spin_lock_irq(&current->sighand->siglock); 459 block_sigmask(ka, sig);
474 sigorsets(&current->blocked, &current->blocked, 460
475 &ka->sa.sa_mask);
476 if (!(ka->sa.sa_flags & SA_NODEFER))
477 sigaddset(&current->blocked, sig);
478 recalc_sigpending();
479 spin_unlock_irq(&current->sighand->siglock);
480 }
481 return ret; 461 return ret;
482} 462}
483 463
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index ce4ab1a5552c..b338d8fc0c12 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -59,19 +59,11 @@ void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
59 * dummy arguments to be able to reach the regs argument. 59 * dummy arguments to be able to reach the regs argument.
60 */ 60 */
61int 61int
62sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 62sys_sigsuspend(old_sigset_t mask)
63 long srp, struct pt_regs *regs)
64{ 63{
65 mask &= _BLOCKABLE; 64 sigset_t blocked;
66 spin_lock_irq(&current->sighand->siglock); 65 siginitset(&blocked, mask);
67 current->saved_sigmask = current->blocked; 66 return sigsuspend(&blocked);
68 siginitset(&current->blocked, mask);
69 recalc_sigpending();
70 spin_unlock_irq(&current->sighand->siglock);
71 current->state = TASK_INTERRUPTIBLE;
72 schedule();
73 set_thread_flag(TIF_RESTORE_SIGMASK);
74 return -ERESTARTNOHAND;
75} 67}
76 68
77int 69int
@@ -87,11 +79,11 @@ sys_sigaction(int signal, const struct old_sigaction *act,
87 79
88 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 80 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
89 __get_user(newk.sa.sa_handler, &act->sa_handler) || 81 __get_user(newk.sa.sa_handler, &act->sa_handler) ||
90 __get_user(newk.sa.sa_restorer, &act->sa_restorer)) 82 __get_user(newk.sa.sa_restorer, &act->sa_restorer) ||
83 __get_user(newk.sa.sa_flags, &act->sa_flags) ||
84 __get_user(mask, &act->sa_mask))
91 return -EFAULT; 85 return -EFAULT;
92 86
93 __get_user(newk.sa.sa_flags, &act->sa_flags);
94 __get_user(mask, &act->sa_mask);
95 siginitset(&newk.sa.sa_mask, mask); 87 siginitset(&newk.sa.sa_mask, mask);
96 } 88 }
97 89
@@ -100,11 +92,11 @@ sys_sigaction(int signal, const struct old_sigaction *act,
100 if (!retval && oact) { 92 if (!retval && oact) {
101 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 93 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
102 __put_user(oldk.sa.sa_handler, &oact->sa_handler) || 94 __put_user(oldk.sa.sa_handler, &oact->sa_handler) ||
103 __put_user(oldk.sa.sa_restorer, &oact->sa_restorer)) 95 __put_user(oldk.sa.sa_restorer, &oact->sa_restorer) ||
96 __put_user(oldk.sa.sa_flags, &oact->sa_flags) ||
97 __put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask))
104 return -EFAULT; 98 return -EFAULT;
105 99
106 __put_user(oldk.sa.sa_flags, &oact->sa_flags);
107 __put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask);
108 } 100 }
109 101
110 return retval; 102 return retval;
@@ -176,12 +168,7 @@ sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
176 goto badframe; 168 goto badframe;
177 169
178 sigdelsetmask(&set, ~_BLOCKABLE); 170 sigdelsetmask(&set, ~_BLOCKABLE);
179 spin_lock_irq(&current->sighand->siglock); 171 set_current_blocked(&set);
180
181 current->blocked = set;
182
183 recalc_sigpending();
184 spin_unlock_irq(&current->sighand->siglock);
185 172
186 if (restore_sigcontext(regs, &frame->sc)) 173 if (restore_sigcontext(regs, &frame->sc))
187 goto badframe; 174 goto badframe;
@@ -222,12 +209,7 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
222 goto badframe; 209 goto badframe;
223 210
224 sigdelsetmask(&set, ~_BLOCKABLE); 211 sigdelsetmask(&set, ~_BLOCKABLE);
225 spin_lock_irq(&current->sighand->siglock); 212 set_current_blocked(&set);
226
227 current->blocked = set;
228
229 recalc_sigpending();
230 spin_unlock_irq(&current->sighand->siglock);
231 213
232 if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) 214 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
233 goto badframe; 215 goto badframe;
@@ -363,10 +345,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
363 return 0; 345 return 0;
364 346
365give_sigsegv: 347give_sigsegv:
366 if (sig == SIGSEGV) 348 force_sigsegv(sig, current);
367 ka->sa.sa_handler = SIG_DFL;
368
369 force_sig(SIGSEGV, current);
370 return -EFAULT; 349 return -EFAULT;
371} 350}
372 351
@@ -450,10 +429,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
450 return 0; 429 return 0;
451 430
452give_sigsegv: 431give_sigsegv:
453 if (sig == SIGSEGV) 432 force_sigsegv(sig, current);
454 ka->sa.sa_handler = SIG_DFL;
455
456 force_sig(SIGSEGV, current);
457 return -EFAULT; 433 return -EFAULT;
458} 434}
459 435
@@ -512,18 +488,8 @@ handle_signal(int canrestart, unsigned long sig,
512 else 488 else
513 ret = setup_frame(sig, ka, oldset, regs); 489 ret = setup_frame(sig, ka, oldset, regs);
514 490
515 if (ka->sa.sa_flags & SA_ONESHOT) 491 if (ret == 0)
516 ka->sa.sa_handler = SIG_DFL; 492 block_sigmask(ka, sig);
517
518 if (ret == 0) {
519 spin_lock_irq(&current->sighand->siglock);
520 sigorsets(&current->blocked, &current->blocked,
521 &ka->sa.sa_mask);
522 if (!(ka->sa.sa_flags & SA_NODEFER))
523 sigaddset(&current->blocked, sig);
524 recalc_sigpending();
525 spin_unlock_irq(&current->sighand->siglock);
526 }
527 493
528 return ret; 494 return ret;
529} 495}