~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/kernel/signal32.c

Version: ~ [ linux-5.8 ] ~ [ linux-5.7.12 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.55 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.136 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.191 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.232 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.232 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 1991, 1992  Linus Torvalds
  7  * Copyright (C) 1994 - 2000  Ralf Baechle
  8  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9  */
 10 #include <linux/sched.h>
 11 #include <linux/mm.h>
 12 #include <linux/smp.h>
 13 #include <linux/smp_lock.h>
 14 #include <linux/kernel.h>
 15 #include <linux/signal.h>
 16 #include <linux/errno.h>
 17 #include <linux/wait.h>
 18 #include <linux/ptrace.h>
 19 #include <linux/compat.h>
 20 
 21 #include <asm/asm.h>
 22 #include <asm/bitops.h>
 23 #include <asm/pgalloc.h>
 24 #include <asm/sim.h>
 25 #include <asm/uaccess.h>
 26 #include <asm/ucontext.h>
 27 #include <asm/system.h>
 28 #include <asm/fpu.h>
 29 
 30 /*
 31  * Including <asm/unistd.h would give use the 64-bit syscall numbers ...
 32  */
 33 #define __NR_O32_sigreturn              4119
 34 #define __NR_O32_rt_sigreturn           4193
 35 #define __NR_O32_restart_syscall        4253
 36 
 37 #define DEBUG_SIG 0
 38 
 39 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 40 
 41 extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
 42 
 43 extern asmlinkage void do_syscall_trace(void);
 44 
 45 /* 32-bit compatibility types */
 46 
 47 #define _NSIG_BPW32     32
 48 #define _NSIG_WORDS32   (_NSIG / _NSIG_BPW32)
 49 
 50 typedef struct {
 51         unsigned int sig[_NSIG_WORDS32];
 52 } sigset_t32;
 53 
 54 typedef unsigned int __sighandler32_t;
 55 typedef void (*vfptr_t)(void);
 56 
 57 struct sigaction32 {
 58         unsigned int            sa_flags;
 59         __sighandler32_t        sa_handler;
 60         compat_sigset_t         sa_mask;
 61 };
 62 
 63 /* IRIX compatible stack_t  */
 64 typedef struct sigaltstack32 {
 65         s32 ss_sp;
 66         compat_size_t ss_size;
 67         int ss_flags;
 68 } stack32_t;
 69 
 70 struct ucontext32 {
 71         u32                 uc_flags;
 72         s32                 uc_link;
 73         stack32_t           uc_stack;
 74         struct sigcontext32 uc_mcontext;
 75         sigset_t32          uc_sigmask;   /* mask last for extensibility */
 76 };
 77 
 78 extern void __put_sigset_unknown_nsig(void);
 79 extern void __get_sigset_unknown_nsig(void);
 80 
 81 static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf)
 82 {
 83         int err = 0;
 84 
 85         if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
 86                 return -EFAULT;
 87 
 88         switch (_NSIG_WORDS) {
 89         default:
 90                 __put_sigset_unknown_nsig();
 91         case 2:
 92                 err |= __put_user (kbuf->sig[1] >> 32, &ubuf->sig[3]);
 93                 err |= __put_user (kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
 94         case 1:
 95                 err |= __put_user (kbuf->sig[0] >> 32, &ubuf->sig[1]);
 96                 err |= __put_user (kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
 97         }
 98 
 99         return err;
100 }
101 
102 static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf)
103 {
104         int err = 0;
105         unsigned long sig[4];
106 
107         if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
108                 return -EFAULT;
109 
110         switch (_NSIG_WORDS) {
111         default:
112                 __get_sigset_unknown_nsig();
113         case 2:
114                 err |= __get_user (sig[3], &ubuf->sig[3]);
115                 err |= __get_user (sig[2], &ubuf->sig[2]);
116                 kbuf->sig[1] = sig[2] | (sig[3] << 32);
117         case 1:
118                 err |= __get_user (sig[1], &ubuf->sig[1]);
119                 err |= __get_user (sig[0], &ubuf->sig[0]);
120                 kbuf->sig[0] = sig[0] | (sig[1] << 32);
121         }
122 
123         return err;
124 }
125 
126 /*
127  * Atomically swap in the new signal mask, and wait for a signal.
128  */
129 asmlinkage inline int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
130 {
131         compat_sigset_t *uset;
132         sigset_t newset, saveset;
133 
134         save_static(&regs);
135         uset = (compat_sigset_t *) regs.regs[4];
136         if (get_sigset(&newset, uset))
137                 return -EFAULT;
138         sigdelsetmask(&newset, ~_BLOCKABLE);
139 
140         spin_lock_irq(&current->sighand->siglock);
141         saveset = current->blocked;
142         current->blocked = newset;
143         recalc_sigpending();
144         spin_unlock_irq(&current->sighand->siglock);
145 
146         regs.regs[2] = EINTR;
147         regs.regs[7] = 1;
148         while (1) {
149                 current->state = TASK_INTERRUPTIBLE;
150                 schedule();
151                 if (do_signal32(&saveset, &regs))
152                         return -EINTR;
153         }
154 }
155 
156 asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
157 {
158         compat_sigset_t *uset;
159         sigset_t newset, saveset;
160         size_t sigsetsize;
161 
162         save_static(&regs);
163         /* XXX Don't preclude handling different sized sigset_t's.  */
164         sigsetsize = regs.regs[5];
165         if (sigsetsize != sizeof(compat_sigset_t))
166                 return -EINVAL;
167 
168         uset = (compat_sigset_t *) regs.regs[4];
169         if (get_sigset(&newset, uset))
170                 return -EFAULT;
171         sigdelsetmask(&newset, ~_BLOCKABLE);
172 
173         spin_lock_irq(&current->sighand->siglock);
174         saveset = current->blocked;
175         current->blocked = newset;
176         recalc_sigpending();
177         spin_unlock_irq(&current->sighand->siglock);
178 
179         regs.regs[2] = EINTR;
180         regs.regs[7] = 1;
181         while (1) {
182                 current->state = TASK_INTERRUPTIBLE;
183                 schedule();
184                 if (do_signal32(&saveset, &regs))
185                         return -EINTR;
186         }
187 }
188 
189 asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act,
190                                struct sigaction32 *oact)
191 {
192         struct k_sigaction new_ka, old_ka;
193         int ret;
194         int err = 0;
195 
196         if (act) {
197                 old_sigset_t mask;
198 
199                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
200                         return -EFAULT;
201                 err |= __get_user((u32)(u64)new_ka.sa.sa_handler,
202                                   &act->sa_handler);
203                 err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
204                 err |= __get_user(mask, &act->sa_mask.sig[0]);
205                 if (err)
206                         return -EFAULT;
207 
208                 siginitset(&new_ka.sa.sa_mask, mask);
209         }
210 
211         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
212 
213         if (!ret && oact) {
214                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
215                         return -EFAULT;
216                 err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
217                 err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
218                                   &oact->sa_handler);
219                 err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
220                 err |= __put_user(0, &oact->sa_mask.sig[1]);
221                 err |= __put_user(0, &oact->sa_mask.sig[2]);
222                 err |= __put_user(0, &oact->sa_mask.sig[3]);
223                 if (err)
224                         return -EFAULT;
225         }
226 
227         return ret;
228 }
229 
230 asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
231 {
232         const stack32_t *uss = (const stack32_t *) regs.regs[4];
233         stack32_t *uoss = (stack32_t *) regs.regs[5];
234         unsigned long usp = regs.regs[29];
235         stack_t kss, koss;
236         int ret, err = 0;
237         mm_segment_t old_fs = get_fs();
238         s32 sp;
239 
240         if (uss) {
241                 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
242                         return -EFAULT;
243                 err |= __get_user(sp, &uss->ss_sp);
244                 kss.ss_size = (long) sp;
245                 err |= __get_user(kss.ss_size, &uss->ss_size);
246                 err |= __get_user(kss.ss_flags, &uss->ss_flags);
247                 if (err)
248                         return -EFAULT;
249         }
250 
251         set_fs (KERNEL_DS);
252         ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp);
253         set_fs (old_fs);
254 
255         if (!ret && uoss) {
256                 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
257                         return -EFAULT;
258                 sp = (int) (long) koss.ss_sp;
259                 err |= __put_user(sp, &uoss->ss_sp);
260                 err |= __put_user(koss.ss_size, &uoss->ss_size);
261                 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
262                 if (err)
263                         return -EFAULT;
264         }
265         return ret;
266 }
267 
268 static asmlinkage int restore_sigcontext32(struct pt_regs *regs,
269                                            struct sigcontext32 *sc)
270 {
271         int err = 0;
272 
273         err |= __get_user(regs->cp0_epc, &sc->sc_pc);
274         err |= __get_user(regs->hi, &sc->sc_mdhi);
275         err |= __get_user(regs->lo, &sc->sc_mdlo);
276 
277 #define restore_gp_reg(i) do {                                          \
278         err |= __get_user(regs->regs[i], &sc->sc_regs[i]);              \
279 } while(0)
280         restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
281         restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
282         restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
283         restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
284         restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
285         restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
286         restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
287         restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
288         restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
289         restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
290         restore_gp_reg(31);
291 #undef restore_gp_reg
292 
293         err |= __get_user(current->used_math, &sc->sc_used_math);
294 
295         if (current->used_math) {
296                 /* restore fpu context if we have used it before */
297                 own_fpu();
298                 err |= restore_fp_context32(sc);
299         } else {
300                 /* signal handler may have used FPU.  Give it up. */
301                 lose_fpu();
302         }
303 
304         return err;
305 }
306 
307 struct sigframe {
308         u32 sf_ass[4];                  /* argument save space for o32 */
309         u32 sf_code[2];                 /* signal trampoline */
310         struct sigcontext32 sf_sc;
311         sigset_t sf_mask;
312 };
313 
314 struct rt_sigframe32 {
315         u32 rs_ass[4];                  /* argument save space for o32 */
316         u32 rs_code[2];                 /* signal trampoline */
317         struct siginfo32 rs_info;
318         struct ucontext32 rs_uc;
319 };
320 
321 static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
322 {
323         int err;
324 
325         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
326                 return -EFAULT;
327 
328         /* If you change siginfo_t structure, please be sure
329            this code is fixed accordingly.
330            It should never copy any pad contained in the structure
331            to avoid security leaks, but must copy the generic
332            3 ints plus the relevant union member.
333            This routine must convert siginfo from 64bit to 32bit as well
334            at the same time.  */
335         err = __put_user(from->si_signo, &to->si_signo);
336         err |= __put_user(from->si_errno, &to->si_errno);
337         err |= __put_user((short)from->si_code, &to->si_code);
338         if (from->si_code < 0)
339                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
340         else {
341                 switch (from->si_code >> 16) {
342                 case __SI_CHLD >> 16:
343                         err |= __put_user(from->si_utime, &to->si_utime);
344                         err |= __put_user(from->si_stime, &to->si_stime);
345                         err |= __put_user(from->si_status, &to->si_status);
346                 default:
347                         err |= __put_user(from->si_pid, &to->si_pid);
348                         err |= __put_user(from->si_uid, &to->si_uid);
349                         break;
350                 case __SI_FAULT >> 16:
351                         err |= __put_user((long)from->si_addr, &to->si_addr);
352                         break;
353                 case __SI_POLL >> 16:
354                         err |= __put_user(from->si_band, &to->si_band);
355                         err |= __put_user(from->si_fd, &to->si_fd);
356                         break;
357                 /* case __SI_RT: This is not generated by the kernel as of now.  */
358                 }
359         }
360         return err;
361 }
362 
363 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
364 {
365         struct sigframe *frame;
366         sigset_t blocked;
367 
368         frame = (struct sigframe *) regs.regs[29];
369         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
370                 goto badframe;
371         if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
372                 goto badframe;
373 
374         sigdelsetmask(&blocked, ~_BLOCKABLE);
375         spin_lock_irq(&current->sighand->siglock);
376         current->blocked = blocked;
377         recalc_sigpending();
378         spin_unlock_irq(&current->sighand->siglock);
379 
380         if (restore_sigcontext32(&regs, &frame->sf_sc))
381                 goto badframe;
382 
383         /*
384          * Don't let your children do this ...
385          */
386         if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
387                 do_syscall_trace();
388         __asm__ __volatile__(
389                 "move\t$29, %0\n\t"
390                 "j\tsyscall_exit"
391                 :/* no outputs */
392                 :"r" (&regs));
393         /* Unreached */
394 
395 badframe:
396         force_sig(SIGSEGV, current);
397 }
398 
399 asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
400 {
401         struct rt_sigframe32 *frame;
402         sigset_t set;
403         stack_t st;
404         s32 sp;
405 
406         frame = (struct rt_sigframe32 *) regs.regs[29];
407         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
408                 goto badframe;
409         if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
410                 goto badframe;
411 
412         sigdelsetmask(&set, ~_BLOCKABLE);
413         spin_lock_irq(&current->sighand->siglock);
414         current->blocked = set;
415         recalc_sigpending();
416         spin_unlock_irq(&current->sighand->siglock);
417 
418         if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
419                 goto badframe;
420 
421         /* The ucontext contains a stack32_t, so we must convert!  */
422         if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
423                 goto badframe;
424         st.ss_size = (long) sp;
425         if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
426                 goto badframe;
427         if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
428                 goto badframe;
429 
430         /* It is more difficult to avoid calling this function than to
431            call it and ignore errors.  */
432         do_sigaltstack(&st, NULL, regs.regs[29]);
433 
434         /*
435          * Don't let your children do this ...
436          */
437         __asm__ __volatile__(
438                 "move\t$29, %0\n\t"
439                 "j\tsyscall_exit"
440                 :/* no outputs */
441                 :"r" (&regs));
442         /* Unreached */
443 
444 badframe:
445         force_sig(SIGSEGV, current);
446 }
447 
448 static inline int setup_sigcontext32(struct pt_regs *regs,
449                                      struct sigcontext32 *sc)
450 {
451         int err = 0;
452 
453         err |= __put_user(regs->cp0_epc, &sc->sc_pc);
454         err |= __put_user(regs->cp0_status, &sc->sc_status);
455 
456 #define save_gp_reg(i) {                                                \
457         err |= __put_user(regs->regs[i], &sc->sc_regs[i]);              \
458 } while(0)
459         __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
460         save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
461         save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
462         save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
463         save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
464         save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
465         save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
466         save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
467         save_gp_reg(31);
468 #undef save_gp_reg
469 
470         err |= __put_user(regs->hi, &sc->sc_mdhi);
471         err |= __put_user(regs->lo, &sc->sc_mdlo);
472         err |= __put_user(regs->cp0_cause, &sc->sc_cause);
473         err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
474 
475         err |= __put_user(current->used_math, &sc->sc_used_math);
476 
477         if (!current->used_math)
478                 goto out;
479 
480         /* 
481          * Save FPU state to signal context.  Signal handler will "inherit"
482          * current FPU state.
483          */
484         if (!is_fpu_owner()) {
485                 own_fpu();
486                 restore_fp(current);
487         }
488         err |= save_fp_context32(sc);
489 
490 out:
491         return err;
492 }
493 
494 /*
495  * Determine which stack to use..
496  */
497 static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
498                                  size_t frame_size)
499 {
500         unsigned long sp;
501 
502         /* Default to using normal stack */
503         sp = regs->regs[29];
504 
505         /*
506          * FPU emulator may have it's own trampoline active just
507          * above the user stack, 16-bytes before the next lowest
508          * 16 byte boundary.  Try to avoid trashing it.
509          */
510         sp -= 32;
511 
512         /* This is the X/Open sanctioned signal stack switching.  */
513         if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
514                 sp = current->sas_ss_sp + current->sas_ss_size;
515 
516         return (void *)((sp - frame_size) & ALMASK);
517 }
518 
519 static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
520                                int signr, sigset_t *set)
521 {
522         struct sigframe *frame;
523         int err = 0;
524 
525         frame = get_sigframe(ka, regs, sizeof(*frame));
526         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
527                 goto give_sigsegv;
528 
529         /*
530          * Set up the return code ...
531          *
532          *         li      v0, __NR_O32_sigreturn
533          *         syscall
534          */
535         err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0);
536         err |= __put_user(0x0000000c                     , frame->sf_code + 1);
537         flush_cache_sigtramp((unsigned long) frame->sf_code);
538 
539         err |= setup_sigcontext32(regs, &frame->sf_sc);
540         err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
541         if (err)
542                 goto give_sigsegv;
543 
544         /*
545          * Arguments to signal handler:
546          *
547          *   a0 = signal number
548          *   a1 = 0 (should be cause)
549          *   a2 = pointer to struct sigcontext
550          *
551          * $25 and c0_epc point to the signal handler, $29 points to the
552          * struct sigframe.
553          */
554         regs->regs[ 4] = signr;
555         regs->regs[ 5] = 0;
556         regs->regs[ 6] = (unsigned long) &frame->sf_sc;
557         regs->regs[29] = (unsigned long) frame;
558         regs->regs[31] = (unsigned long) frame->sf_code;
559         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
560 
561 #if DEBUG_SIG
562         printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
563                current->comm, current->pid,
564                frame, regs->cp0_epc, frame->sf_code);
565 #endif
566         return;
567 
568 give_sigsegv:
569         if (signr == SIGSEGV)
570                 ka->sa.sa_handler = SIG_DFL;
571         force_sig(SIGSEGV, current);
572 }
573 
574 static inline void setup_rt_frame(struct k_sigaction * ka,
575                                   struct pt_regs *regs, int signr,
576                                   sigset_t *set, siginfo_t *info)
577 {
578         struct rt_sigframe32 *frame;
579         int err = 0;
580         s32 sp;
581 
582         frame = get_sigframe(ka, regs, sizeof(*frame));
583         if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
584                 goto give_sigsegv;
585 
586         /* Set up to return from userspace.  If provided, use a stub already
587            in userspace.  */
588         /*
589          * Set up the return code ...
590          *
591          *         li      v0, __NR_O32_rt_sigreturn
592          *         syscall
593          */
594         err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0);
595         err |= __put_user(0x0000000c                      , frame->rs_code + 1);
596         flush_cache_sigtramp((unsigned long) frame->rs_code);
597 
598         /* Convert (siginfo_t -> siginfo_t32) and copy to user. */
599         err |= copy_siginfo_to_user32(&frame->rs_info, info);
600 
601         /* Create the ucontext.  */
602         err |= __put_user(0, &frame->rs_uc.uc_flags);
603         err |= __put_user(0, &frame->rs_uc.uc_link);
604         sp = (int) (long) current->sas_ss_sp;
605         err |= __put_user(sp,
606                           &frame->rs_uc.uc_stack.ss_sp);
607         err |= __put_user(sas_ss_flags(regs->regs[29]),
608                           &frame->rs_uc.uc_stack.ss_flags);
609         err |= __put_user(current->sas_ss_size,
610                           &frame->rs_uc.uc_stack.ss_size);
611         err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
612         err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
613 
614         if (err)
615                 goto give_sigsegv;
616 
617         /*
618          * Arguments to signal handler:
619          *
620          *   a0 = signal number
621          *   a1 = 0 (should be cause)
622          *   a2 = pointer to ucontext
623          *
624          * $25 and c0_epc point to the signal handler, $29 points to
625          * the struct rt_sigframe32.
626          */
627         regs->regs[ 4] = signr;
628         regs->regs[ 5] = (unsigned long) &frame->rs_info;
629         regs->regs[ 6] = (unsigned long) &frame->rs_uc;
630         regs->regs[29] = (unsigned long) frame;
631         regs->regs[31] = (unsigned long) frame->rs_code;
632         regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
633 
634 #if DEBUG_SIG
635         printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
636                current->comm, current->pid,
637                frame, regs->cp0_epc, frame->rs_code);
638 #endif
639         return;
640 
641 give_sigsegv:
642         if (signr == SIGSEGV)
643                 ka->sa.sa_handler = SIG_DFL;
644         force_sig(SIGSEGV, current);
645 }
646 
647 static inline void handle_signal(unsigned long sig, siginfo_t *info,
648         sigset_t *oldset, struct pt_regs * regs)
649 {
650         struct k_sigaction *ka = &current->sighand->action[sig-1];
651 
652         switch (regs->regs[0]) {
653         case ERESTART_RESTARTBLOCK:
654                 current_thread_info()->restart_block.fn = do_no_restart_syscall;
655         case ERESTARTNOHAND:
656                 regs->regs[2] = EINTR;
657                 break;
658         case ERESTARTSYS:
659                 if(!(ka->sa.sa_flags & SA_RESTART)) {
660                         regs->regs[2] = EINTR;
661                         break;
662                 }
663         /* fallthrough */
664         case ERESTARTNOINTR:            /* Userland will reload $v0.  */
665                 regs->regs[7] = regs->regs[26];
666                 regs->cp0_epc -= 8;
667         }
668 
669         regs->regs[0] = 0;              /* Don't deal with this again.  */
670 
671         if (ka->sa.sa_flags & SA_SIGINFO)
672                 setup_rt_frame(ka, regs, sig, oldset, info);
673         else
674                 setup_frame(ka, regs, sig, oldset);
675 
676         if (ka->sa.sa_flags & SA_ONESHOT)
677                 ka->sa.sa_handler = SIG_DFL;
678         if (!(ka->sa.sa_flags & SA_NODEFER)) {
679                 spin_lock_irq(&current->sighand->siglock);
680                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
681                 sigaddset(&current->blocked,sig);
682                 recalc_sigpending();
683                 spin_unlock_irq(&current->sighand->siglock);
684         }
685 }
686 
687 asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
688 {
689         siginfo_t info;
690         int signr;
691 
692         if (!oldset)
693                 oldset = &current->blocked;
694 
695         signr = get_signal_to_deliver(&info, regs, NULL);
696         if (signr > 0) {
697                 handle_signal(signr, &info, oldset, regs);
698                 return 1;
699         }
700 
701         /*
702          * Who's code doesn't conform to the restartable syscall convention
703          * dies here!!!  The li instruction, a single machine instruction,
704          * must directly be followed by the syscall instruction.
705          */
706         if (regs->regs[0]) {
707                 if (regs->regs[2] == ERESTARTNOHAND ||
708                     regs->regs[2] == ERESTARTSYS ||
709                     regs->regs[2] == ERESTARTNOINTR) {
710                         regs->regs[7] = regs->regs[26];
711                         regs->cp0_epc -= 8;
712                 }
713                 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
714                         regs->regs[2] = __NR_O32_restart_syscall;
715                         regs->cp0_epc -= 4;
716                 }
717         }
718         return 0;
719 }
720 
721 asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
722                                   struct sigaction32 *oact,
723                                   unsigned int sigsetsize)
724 {
725         struct k_sigaction new_sa, old_sa;
726         int ret = -EINVAL;
727 
728         /* XXX: Don't preclude handling different sized sigset_t's.  */
729         if (sigsetsize != sizeof(sigset_t))
730                 goto out;
731 
732         if (act) {
733                 int err = 0;
734 
735                 if (!access_ok(VERIFY_READ, act, sizeof(*act)))
736                         return -EFAULT;
737                 err |= __get_user((u32)(u64)new_sa.sa.sa_handler,
738                                   &act->sa_handler);
739                 err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
740                 err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
741                 if (err)
742                         return -EFAULT;
743         }
744 
745         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
746 
747         if (!ret && oact) {
748                 int err = 0;
749 
750                 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
751                         return -EFAULT;
752 
753                 err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
754                                    &oact->sa_handler);
755                 err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
756                 err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
757                 if (err)
758                         return -EFAULT;
759         }
760 out:
761         return ret;
762 }
763 
764 asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
765                                    size_t sigsetsize);
766 
767 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set,
768         compat_sigset_t *oset, unsigned int sigsetsize)
769 {
770         sigset_t old_set, new_set;
771         int ret;
772         mm_segment_t old_fs = get_fs();
773 
774         if (set && get_sigset(&new_set, set))
775                 return -EFAULT;
776 
777         set_fs (KERNEL_DS);
778         ret = sys_rt_sigprocmask(how, set ? &new_set : NULL,
779                                  oset ? &old_set : NULL, sigsetsize);
780         set_fs (old_fs);
781 
782         if (!ret && oset && put_sigset(&old_set, oset))
783                 return -EFAULT;
784 
785         return ret;
786 }
787 
788 asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
789 
790 asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset,
791         unsigned int sigsetsize)
792 {
793         int ret;
794         sigset_t set;
795         mm_segment_t old_fs = get_fs();
796 
797         set_fs (KERNEL_DS);
798         ret = sys_rt_sigpending(&set, sigsetsize);
799         set_fs (old_fs);
800 
801         if (!ret && put_sigset(&set, uset))
802                 return -EFAULT;
803 
804         return ret;
805 }
806 
807 asmlinkage int sys32_rt_sigtimedwait(compat_sigset_t *uthese,
808         siginfo_t32 *uinfo, struct compat_timespec *uts,
809         compat_time_t sigsetsize)
810 {
811         int ret, sig;
812         sigset_t these;
813         compat_sigset_t these32;
814         struct timespec ts;
815         siginfo_t info;
816         long timeout = 0;
817 
818         /*
819          * As the result of a brainfarting competition a few years ago the
820          * size of sigset_t for the 32-bit kernel was choosen to be 128 bits
821          * but nothing so far is actually using that many, 64 are enough.  So
822          * for now we just drop the high bits.
823          */
824         if (copy_from_user (&these32, uthese, sizeof(compat_old_sigset_t)))
825                 return -EFAULT;
826 
827         switch (_NSIG_WORDS) {
828 #ifdef __MIPSEB__
829         case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
830         case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
831         case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
832         case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
833 #endif
834 #ifdef __MIPSEL__
835         case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32);
836         case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32);
837         case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32);
838         case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32);
839 #endif
840         }
841 
842         /*
843          * Invert the set of allowed signals to get those we
844          * want to block.
845          */
846         sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
847         signotset(&these);
848 
849         if (uts) {
850                 if (get_user (ts.tv_sec, &uts->tv_sec) ||
851                     get_user (ts.tv_nsec, &uts->tv_nsec))
852                         return -EINVAL;
853                 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
854                     || ts.tv_sec < 0)
855                         return -EINVAL;
856         }
857 
858         spin_lock_irq(&current->sighand->siglock);
859         sig = dequeue_signal(current, &these, &info);
860         if (!sig) {
861                 /* None ready -- temporarily unblock those we're interested
862                    in so that we'll be awakened when they arrive.  */
863                 sigset_t oldblocked = current->blocked;
864                 sigandsets(&current->blocked, &current->blocked, &these);
865                 recalc_sigpending();
866                 spin_unlock_irq(&current->sighand->siglock);
867 
868                 timeout = MAX_SCHEDULE_TIMEOUT;
869                 if (uts)
870                         timeout = (timespec_to_jiffies(&ts)
871                                    + (ts.tv_sec || ts.tv_nsec));
872 
873                 current->state = TASK_INTERRUPTIBLE;
874                 timeout = schedule_timeout(timeout);
875 
876                 spin_lock_irq(&current->sighand->siglock);
877                 sig = dequeue_signal(current, &these, &info);
878                 current->blocked = oldblocked;
879                 recalc_sigpending();
880         }
881         spin_unlock_irq(&current->sighand->siglock);
882 
883         if (sig) {
884                 ret = sig;
885                 if (uinfo) {
886                         if (copy_siginfo_to_user32(uinfo, &info))
887                                 ret = -EFAULT;
888                 }
889         } else {
890                 ret = -EAGAIN;
891                 if (timeout)
892                         ret = -EINTR;
893         }
894 
895         return ret;
896 }
897 
898 extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
899 
900 asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
901 {
902         siginfo_t info;
903         int ret;
904         mm_segment_t old_fs = get_fs();
905 
906         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
907             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
908                 return -EFAULT;
909         set_fs (KERNEL_DS);
910         ret = sys_rt_sigqueueinfo(pid, sig, &info);
911         set_fs (old_fs);
912         return ret;
913 }
914 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp