diff options
Diffstat (limited to 'arch/sh/kernel/signal_32.c')
-rw-r--r-- | arch/sh/kernel/signal_32.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 5901fba3176..cb4172c8af7 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c | |||
@@ -53,23 +53,11 @@ struct fdpic_func_descriptor { | |||
53 | * Atomically swap in the new signal mask, and wait for a signal. | 53 | * Atomically swap in the new signal mask, and wait for a signal. |
54 | */ | 54 | */ |
55 | asmlinkage int | 55 | asmlinkage int |
56 | sys_sigsuspend(old_sigset_t mask, | 56 | sys_sigsuspend(old_sigset_t mask) |
57 | unsigned long r5, unsigned long r6, unsigned long r7, | ||
58 | struct pt_regs __regs) | ||
59 | { | 57 | { |
60 | sigset_t blocked; | 58 | sigset_t blocked; |
61 | |||
62 | current->saved_sigmask = current->blocked; | ||
63 | |||
64 | mask &= _BLOCKABLE; | ||
65 | siginitset(&blocked, mask); | 59 | siginitset(&blocked, mask); |
66 | set_current_blocked(&blocked); | 60 | return sigsuspend(&blocked); |
67 | |||
68 | current->state = TASK_INTERRUPTIBLE; | ||
69 | schedule(); | ||
70 | set_restore_sigmask(); | ||
71 | |||
72 | return -ERESTARTNOHAND; | ||
73 | } | 61 | } |
74 | 62 | ||
75 | asmlinkage int | 63 | asmlinkage int |
@@ -83,10 +71,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
83 | old_sigset_t mask; | 71 | old_sigset_t mask; |
84 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 72 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
85 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 73 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
86 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | 74 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || |
75 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
76 | __get_user(mask, &act->sa_mask)) | ||
87 | return -EFAULT; | 77 | return -EFAULT; |
88 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
89 | __get_user(mask, &act->sa_mask); | ||
90 | siginitset(&new_ka.sa.sa_mask, mask); | 78 | siginitset(&new_ka.sa.sa_mask, mask); |
91 | } | 79 | } |
92 | 80 | ||
@@ -95,10 +83,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
95 | if (!ret && oact) { | 83 | if (!ret && oact) { |
96 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 84 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
97 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 85 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
98 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | 86 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || |
87 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
88 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
99 | return -EFAULT; | 89 | return -EFAULT; |
100 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
101 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
102 | } | 90 | } |
103 | 91 | ||
104 | return ret; | 92 | return ret; |
@@ -162,12 +150,11 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc, | |||
162 | if (!(boot_cpu_data.flags & CPU_HAS_FPU)) | 150 | if (!(boot_cpu_data.flags & CPU_HAS_FPU)) |
163 | return 0; | 151 | return 0; |
164 | 152 | ||
165 | if (!used_math()) { | 153 | if (!used_math()) |
166 | __put_user(0, &sc->sc_ownedfp); | 154 | return __put_user(0, &sc->sc_ownedfp); |
167 | return 0; | ||
168 | } | ||
169 | 155 | ||
170 | __put_user(1, &sc->sc_ownedfp); | 156 | if (__put_user(1, &sc->sc_ownedfp)) |
157 | return -EFAULT; | ||
171 | 158 | ||
172 | /* This will cause a "finit" to be triggered by the next | 159 | /* This will cause a "finit" to be triggered by the next |
173 | attempted FPU operation by the 'current' process. | 160 | attempted FPU operation by the 'current' process. |
@@ -207,7 +194,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p | |||
207 | regs->sr |= SR_FD; /* Release FPU */ | 194 | regs->sr |= SR_FD; /* Release FPU */ |
208 | clear_fpu(tsk, regs); | 195 | clear_fpu(tsk, regs); |
209 | clear_used_math(); | 196 | clear_used_math(); |
210 | __get_user (owned_fp, &sc->sc_ownedfp); | 197 | err |= __get_user (owned_fp, &sc->sc_ownedfp); |
211 | if (owned_fp) | 198 | if (owned_fp) |
212 | err |= restore_sigcontext_fpu(sc); | 199 | err |= restore_sigcontext_fpu(sc); |
213 | } | 200 | } |
@@ -398,11 +385,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, | |||
398 | struct fdpic_func_descriptor __user *funcptr = | 385 | struct fdpic_func_descriptor __user *funcptr = |
399 | (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; | 386 | (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; |
400 | 387 | ||
401 | __get_user(regs->pc, &funcptr->text); | 388 | err |= __get_user(regs->pc, &funcptr->text); |
402 | __get_user(regs->regs[12], &funcptr->GOT); | 389 | err |= __get_user(regs->regs[12], &funcptr->GOT); |
403 | } else | 390 | } else |
404 | regs->pc = (unsigned long)ka->sa.sa_handler; | 391 | regs->pc = (unsigned long)ka->sa.sa_handler; |
405 | 392 | ||
393 | if (err) | ||
394 | goto give_sigsegv; | ||
395 | |||
406 | set_fs(USER_DS); | 396 | set_fs(USER_DS); |
407 | 397 | ||
408 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", | 398 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", |
@@ -482,11 +472,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
482 | struct fdpic_func_descriptor __user *funcptr = | 472 | struct fdpic_func_descriptor __user *funcptr = |
483 | (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; | 473 | (struct fdpic_func_descriptor __user *)ka->sa.sa_handler; |
484 | 474 | ||
485 | __get_user(regs->pc, &funcptr->text); | 475 | err |= __get_user(regs->pc, &funcptr->text); |
486 | __get_user(regs->regs[12], &funcptr->GOT); | 476 | err |= __get_user(regs->regs[12], &funcptr->GOT); |
487 | } else | 477 | } else |
488 | regs->pc = (unsigned long)ka->sa.sa_handler; | 478 | regs->pc = (unsigned long)ka->sa.sa_handler; |
489 | 479 | ||
480 | if (err) | ||
481 | goto give_sigsegv; | ||
482 | |||
490 | set_fs(USER_DS); | 483 | set_fs(USER_DS); |
491 | 484 | ||
492 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", | 485 | pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", |