aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel
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/sparc/kernel
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/sparc/kernel')
-rw-r--r--arch/sparc/kernel/signal32.c10
-rw-r--r--arch/sparc/kernel/signal_32.c12
-rw-r--r--arch/sparc/kernel/signal_64.c13
-rw-r--r--arch/sparc/kernel/sys_sparc_32.c17
4 files changed, 14 insertions, 38 deletions
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 948700fb9036..bb1513e45f1a 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -215,8 +215,9 @@ void do_sigreturn32(struct pt_regs *regs)
215 (((unsigned long) sf) & 3)) 215 (((unsigned long) sf) & 3))
216 goto segv; 216 goto segv;
217 217
218 get_user(pc, &sf->info.si_regs.pc); 218 if (get_user(pc, &sf->info.si_regs.pc) ||
219 __get_user(npc, &sf->info.si_regs.npc); 219 __get_user(npc, &sf->info.si_regs.npc))
220 goto segv;
220 221
221 if ((pc | npc) & 3) 222 if ((pc | npc) & 3)
222 goto segv; 223 goto segv;
@@ -305,8 +306,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
305 (((unsigned long) sf) & 3)) 306 (((unsigned long) sf) & 3))
306 goto segv; 307 goto segv;
307 308
308 get_user(pc, &sf->regs.pc); 309 if (get_user(pc, &sf->regs.pc) ||
309 __get_user(npc, &sf->regs.npc); 310 __get_user(npc, &sf->regs.npc))
311 goto segv;
310 312
311 if ((pc | npc) & 3) 313 if ((pc | npc) & 3)
312 goto segv; 314 goto segv;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index ac8e66b50f07..2b7e849f7c65 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -64,18 +64,8 @@ struct rt_signal_frame {
64static int _sigpause_common(old_sigset_t set) 64static int _sigpause_common(old_sigset_t set)
65{ 65{
66 sigset_t blocked; 66 sigset_t blocked;
67
68 current->saved_sigmask = current->blocked;
69
70 set &= _BLOCKABLE;
71 siginitset(&blocked, set); 67 siginitset(&blocked, set);
72 set_current_blocked(&blocked); 68 return sigsuspend(&blocked);
73
74 current->state = TASK_INTERRUPTIBLE;
75 schedule();
76 set_thread_flag(TIF_RESTORE_SIGMASK);
77
78 return -ERESTARTNOHAND;
79} 69}
80 70
81asmlinkage int sys_sigsuspend(old_sigset_t set) 71asmlinkage int sys_sigsuspend(old_sigset_t set)
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 48b0f57b65f7..eafaab486b2d 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -242,19 +242,8 @@ struct rt_signal_frame {
242static long _sigpause_common(old_sigset_t set) 242static long _sigpause_common(old_sigset_t set)
243{ 243{
244 sigset_t blocked; 244 sigset_t blocked;
245
246 current->saved_sigmask = current->blocked;
247
248 set &= _BLOCKABLE;
249 siginitset(&blocked, set); 245 siginitset(&blocked, set);
250 set_current_blocked(&blocked); 246 return sigsuspend(&blocked);
251
252 current->state = TASK_INTERRUPTIBLE;
253 schedule();
254
255 set_restore_sigmask();
256
257 return -ERESTARTNOHAND;
258} 247}
259 248
260asmlinkage long sys_sigpause(unsigned int set) 249asmlinkage long sys_sigpause(unsigned int set)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 627e89af1d71..0c9b31b22e07 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -184,10 +184,10 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
184 184
185 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 185 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
186 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 186 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
187 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 187 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
188 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
189 __get_user(mask, &act->sa_mask))
188 return -EFAULT; 190 return -EFAULT;
189 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
190 __get_user(mask, &act->sa_mask);
191 siginitset(&new_ka.sa.sa_mask, mask); 191 siginitset(&new_ka.sa.sa_mask, mask);
192 new_ka.ka_restorer = NULL; 192 new_ka.ka_restorer = NULL;
193 } 193 }
@@ -195,17 +195,12 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act,
195 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 195 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
196 196
197 if (!ret && oact) { 197 if (!ret && oact) {
198 /* In the clone() case we could copy half consistent
199 * state to the user, however this could sleep and
200 * deadlock us if we held the signal lock on SMP. So for
201 * now I take the easy way out and do no locking.
202 */
203 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 198 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
204 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 199 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
205 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 200 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
201 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
202 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
206 return -EFAULT; 203 return -EFAULT;
207 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
208 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
209 } 204 }
210 205
211 return ret; 206 return ret;