diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 21:11:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 21:11:45 -0400 |
commit | f9369910a6225b8d4892c3f20ae740a711cd5ace (patch) | |
tree | 8650ff79d7607bceb35509c028400ecf1c317de0 /arch/cris | |
parent | 05f144a0d5c2207a0349348127f996e104ad7404 (diff) | |
parent | 415d04d08fec74b226c92c1fb54ad117c9c6bac4 (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.c | 50 | ||||
-rw-r--r-- | arch/cris/arch-v32/kernel/signal.c | 66 |
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 | */ |
51 | int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, | 51 | int 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(¤t->sighand->siglock); | 54 | siginitset(&blocked, mask); |
56 | current->saved_sigmask = current->blocked; | 55 | return sigsuspend(&blocked); |
57 | siginitset(¤t->blocked, mask); | ||
58 | recalc_sigpending(); | ||
59 | spin_unlock_irq(¤t->sighand->siglock); | ||
60 | current->state = TASK_INTERRUPTIBLE; | ||
61 | schedule(); | ||
62 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
63 | return -ERESTARTNOHAND; | ||
64 | } | 56 | } |
65 | 57 | ||
66 | int sys_sigaction(int sig, const struct old_sigaction __user *act, | 58 | int 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(¤t->sighand->siglock); | 180 | set_current_blocked(&set); |
189 | current->blocked = set; | ||
190 | recalc_sigpending(); | ||
191 | spin_unlock_irq(¤t->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(¤t->sighand->siglock); | 216 | set_current_blocked(&set); |
228 | current->blocked = set; | ||
229 | recalc_sigpending(); | ||
230 | spin_unlock_irq(¤t->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(¤t->sighand->siglock); | 459 | block_sigmask(ka, sig); |
474 | sigorsets(¤t->blocked, ¤t->blocked, | 460 | |
475 | &ka->sa.sa_mask); | ||
476 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
477 | sigaddset(¤t->blocked, sig); | ||
478 | recalc_sigpending(); | ||
479 | spin_unlock_irq(¤t->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 | */ |
61 | int | 61 | int |
62 | sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, | 62 | sys_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(¤t->sighand->siglock); | 65 | siginitset(&blocked, mask); |
67 | current->saved_sigmask = current->blocked; | 66 | return sigsuspend(&blocked); |
68 | siginitset(¤t->blocked, mask); | ||
69 | recalc_sigpending(); | ||
70 | spin_unlock_irq(¤t->sighand->siglock); | ||
71 | current->state = TASK_INTERRUPTIBLE; | ||
72 | schedule(); | ||
73 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
74 | return -ERESTARTNOHAND; | ||
75 | } | 67 | } |
76 | 68 | ||
77 | int | 69 | int |
@@ -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(¤t->sighand->siglock); | 171 | set_current_blocked(&set); |
180 | |||
181 | current->blocked = set; | ||
182 | |||
183 | recalc_sigpending(); | ||
184 | spin_unlock_irq(¤t->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(¤t->sighand->siglock); | 212 | set_current_blocked(&set); |
226 | |||
227 | current->blocked = set; | ||
228 | |||
229 | recalc_sigpending(); | ||
230 | spin_unlock_irq(¤t->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 | ||
365 | give_sigsegv: | 347 | give_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 | ||
452 | give_sigsegv: | 431 | give_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(¤t->sighand->siglock); | ||
520 | sigorsets(¤t->blocked, ¤t->blocked, | ||
521 | &ka->sa.sa_mask); | ||
522 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
523 | sigaddset(¤t->blocked, sig); | ||
524 | recalc_sigpending(); | ||
525 | spin_unlock_irq(¤t->sighand->siglock); | ||
526 | } | ||
527 | 493 | ||
528 | return ret; | 494 | return ret; |
529 | } | 495 | } |