Linux Audio

Check our new training course

Loading...
v3.5.6
  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, 2006  Ralf Baechle
  8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9 */
 10#include <linux/cache.h>
 11#include <linux/compat.h>
 12#include <linux/sched.h>
 13#include <linux/mm.h>
 14#include <linux/smp.h>
 15#include <linux/kernel.h>
 16#include <linux/signal.h>
 17#include <linux/syscalls.h>
 18#include <linux/errno.h>
 19#include <linux/wait.h>
 20#include <linux/ptrace.h>
 21#include <linux/suspend.h>
 22#include <linux/compiler.h>
 23#include <linux/uaccess.h>
 24
 25#include <asm/abi.h>
 26#include <asm/asm.h>
 27#include <asm/compat-signal.h>
 28#include <linux/bitops.h>
 29#include <asm/cacheflush.h>
 30#include <asm/sim.h>
 31#include <asm/ucontext.h>
 32#include <asm/fpu.h>
 33#include <asm/war.h>
 34#include <asm/vdso.h>
 35#include <asm/dsp.h>
 36
 37#include "signal-common.h"
 38
 39static int (*save_fp_context32)(struct sigcontext32 __user *sc);
 40static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 41
 42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
 43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
 44
 45extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
 46extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
 47
 48/*
 49 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
 50 */
 51#define __NR_O32_restart_syscall        4253
 52
 53/* 32-bit compatibility types */
 54
 55typedef unsigned int __sighandler32_t;
 56typedef void (*vfptr_t)(void);
 57
 58struct sigaction32 {
 59	unsigned int		sa_flags;
 60	__sighandler32_t	sa_handler;
 61	compat_sigset_t		sa_mask;
 62};
 63
 64/* IRIX compatible stack_t  */
 65typedef struct sigaltstack32 {
 66	s32 ss_sp;
 67	compat_size_t ss_size;
 68	int ss_flags;
 69} stack32_t;
 70
 71struct ucontext32 {
 72	u32                 uc_flags;
 73	s32                 uc_link;
 74	stack32_t           uc_stack;
 75	struct sigcontext32 uc_mcontext;
 76	compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 77};
 78
 79struct sigframe32 {
 80	u32 sf_ass[4];		/* argument save space for o32 */
 81	u32 sf_pad[2];		/* Was: signal trampoline */
 82	struct sigcontext32 sf_sc;
 83	compat_sigset_t sf_mask;
 84};
 85
 86struct rt_sigframe32 {
 87	u32 rs_ass[4];			/* argument save space for o32 */
 88	u32 rs_pad[2];			/* Was: signal trampoline */
 89	compat_siginfo_t rs_info;
 90	struct ucontext32 rs_uc;
 91};
 92
 93/*
 94 * sigcontext handlers
 95 */
 96static int protected_save_fp_context32(struct sigcontext32 __user *sc)
 97{
 98	int err;
 99	while (1) {
100		lock_fpu_owner();
101		own_fpu_inatomic(1);
102		err = save_fp_context32(sc); /* this might fail */
103		unlock_fpu_owner();
104		if (likely(!err))
105			break;
106		/* touch the sigcontext and try again */
107		err = __put_user(0, &sc->sc_fpregs[0]) |
108			__put_user(0, &sc->sc_fpregs[31]) |
109			__put_user(0, &sc->sc_fpc_csr);
110		if (err)
111			break;	/* really bad sigcontext */
112	}
113	return err;
114}
115
116static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
117{
118	int err, tmp __maybe_unused;
119	while (1) {
120		lock_fpu_owner();
121		own_fpu_inatomic(0);
122		err = restore_fp_context32(sc); /* this might fail */
123		unlock_fpu_owner();
124		if (likely(!err))
125			break;
126		/* touch the sigcontext and try again */
127		err = __get_user(tmp, &sc->sc_fpregs[0]) |
128			__get_user(tmp, &sc->sc_fpregs[31]) |
129			__get_user(tmp, &sc->sc_fpc_csr);
130		if (err)
131			break;	/* really bad sigcontext */
132	}
133	return err;
134}
135
136static int setup_sigcontext32(struct pt_regs *regs,
137			      struct sigcontext32 __user *sc)
138{
139	int err = 0;
140	int i;
141	u32 used_math;
142
143	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
144
145	err |= __put_user(0, &sc->sc_regs[0]);
146	for (i = 1; i < 32; i++)
147		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
148
149	err |= __put_user(regs->hi, &sc->sc_mdhi);
150	err |= __put_user(regs->lo, &sc->sc_mdlo);
151	if (cpu_has_dsp) {
152		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
153		err |= __put_user(mfhi1(), &sc->sc_hi1);
154		err |= __put_user(mflo1(), &sc->sc_lo1);
155		err |= __put_user(mfhi2(), &sc->sc_hi2);
156		err |= __put_user(mflo2(), &sc->sc_lo2);
157		err |= __put_user(mfhi3(), &sc->sc_hi3);
158		err |= __put_user(mflo3(), &sc->sc_lo3);
159	}
160
161	used_math = !!used_math();
162	err |= __put_user(used_math, &sc->sc_used_math);
 
 
 
163
164	if (used_math) {
165		/*
166		 * Save FPU state to signal context.  Signal handler
167		 * will "inherit" current FPU state.
168		 */
169		err |= protected_save_fp_context32(sc);
170	}
171	return err;
172}
173
174static int
175check_and_restore_fp_context32(struct sigcontext32 __user *sc)
176{
177	int err, sig;
178
179	err = sig = fpcsr_pending(&sc->sc_fpc_csr);
180	if (err > 0)
181		err = 0;
182	err |= protected_restore_fp_context32(sc);
183	return err ?: sig;
184}
185
186static int restore_sigcontext32(struct pt_regs *regs,
187				struct sigcontext32 __user *sc)
188{
189	u32 used_math;
190	int err = 0;
191	s32 treg;
192	int i;
193
194	/* Always make any pending restarted system calls return -EINTR */
195	current_thread_info()->restart_block.fn = do_no_restart_syscall;
196
197	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
198	err |= __get_user(regs->hi, &sc->sc_mdhi);
199	err |= __get_user(regs->lo, &sc->sc_mdlo);
200	if (cpu_has_dsp) {
201		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
202		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
203		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
204		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
205		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
206		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
207		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
208	}
209
210	for (i = 1; i < 32; i++)
211		err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
212
213	err |= __get_user(used_math, &sc->sc_used_math);
214	conditional_used_math(used_math);
215
216	if (used_math) {
217		/* restore fpu context if we have used it before */
218		if (!err)
219			err = check_and_restore_fp_context32(sc);
220	} else {
221		/* signal handler may have used FPU.  Give it up. */
222		lose_fpu(0);
223	}
224
225	return err;
226}
227
228/*
229 *
230 */
231extern void __put_sigset_unknown_nsig(void);
232extern void __get_sigset_unknown_nsig(void);
233
234static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
235{
236	int err = 0;
237
238	if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
239		return -EFAULT;
240
241	switch (_NSIG_WORDS) {
242	default:
243		__put_sigset_unknown_nsig();
244	case 2:
245		err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
246		err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
247	case 1:
248		err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
249		err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
250	}
251
252	return err;
253}
254
255static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
256{
257	int err = 0;
258	unsigned long sig[4];
259
260	if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
261		return -EFAULT;
262
263	switch (_NSIG_WORDS) {
264	default:
265		__get_sigset_unknown_nsig();
266	case 2:
267		err |= __get_user(sig[3], &ubuf->sig[3]);
268		err |= __get_user(sig[2], &ubuf->sig[2]);
269		kbuf->sig[1] = sig[2] | (sig[3] << 32);
270	case 1:
271		err |= __get_user(sig[1], &ubuf->sig[1]);
272		err |= __get_user(sig[0], &ubuf->sig[0]);
273		kbuf->sig[0] = sig[0] | (sig[1] << 32);
274	}
275
276	return err;
277}
278
279/*
280 * Atomically swap in the new signal mask, and wait for a signal.
281 */
282
283asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
284{
285	compat_sigset_t __user *uset;
286	sigset_t newset;
287
288	uset = (compat_sigset_t __user *) regs.regs[4];
289	if (get_sigset(&newset, uset))
290		return -EFAULT;
291	return sigsuspend(&newset);
292}
293
294asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
295{
296	compat_sigset_t __user *uset;
297	sigset_t newset;
298	size_t sigsetsize;
299
300	/* XXX Don't preclude handling different sized sigset_t's.  */
301	sigsetsize = regs.regs[5];
302	if (sigsetsize != sizeof(compat_sigset_t))
303		return -EINVAL;
304
305	uset = (compat_sigset_t __user *) regs.regs[4];
306	if (get_sigset(&newset, uset))
307		return -EFAULT;
308	return sigsuspend(&newset);
309}
310
311SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
312	struct sigaction32 __user *, oact)
313{
314	struct k_sigaction new_ka, old_ka;
315	int ret;
316	int err = 0;
317
318	if (act) {
319		old_sigset_t mask;
320		s32 handler;
321
322		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
323			return -EFAULT;
324		err |= __get_user(handler, &act->sa_handler);
325		new_ka.sa.sa_handler = (void __user *)(s64)handler;
326		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
327		err |= __get_user(mask, &act->sa_mask.sig[0]);
328		if (err)
329			return -EFAULT;
330
331		siginitset(&new_ka.sa.sa_mask, mask);
332	}
333
334	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
335
336	if (!ret && oact) {
337		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
338			return -EFAULT;
339		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
340		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
341		                  &oact->sa_handler);
342		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
343		err |= __put_user(0, &oact->sa_mask.sig[1]);
344		err |= __put_user(0, &oact->sa_mask.sig[2]);
345		err |= __put_user(0, &oact->sa_mask.sig[3]);
346		if (err)
347			return -EFAULT;
348	}
349
350	return ret;
351}
352
353asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
354{
355	const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
356	stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
357	unsigned long usp = regs.regs[29];
358	stack_t kss, koss;
359	int ret, err = 0;
360	mm_segment_t old_fs = get_fs();
361	s32 sp;
362
363	if (uss) {
364		if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
365			return -EFAULT;
366		err |= __get_user(sp, &uss->ss_sp);
367		kss.ss_sp = (void __user *) (long) sp;
368		err |= __get_user(kss.ss_size, &uss->ss_size);
369		err |= __get_user(kss.ss_flags, &uss->ss_flags);
370		if (err)
371			return -EFAULT;
372	}
373
374	set_fs(KERNEL_DS);
375	ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
376			     uoss ? (stack_t __user *)&koss : NULL, usp);
377	set_fs(old_fs);
378
379	if (!ret && uoss) {
380		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
381			return -EFAULT;
382		sp = (int) (unsigned long) koss.ss_sp;
383		err |= __put_user(sp, &uoss->ss_sp);
384		err |= __put_user(koss.ss_size, &uoss->ss_size);
385		err |= __put_user(koss.ss_flags, &uoss->ss_flags);
386		if (err)
387			return -EFAULT;
388	}
389	return ret;
390}
391
392int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
393{
394	int err;
395
396	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
397		return -EFAULT;
398
399	/* If you change siginfo_t structure, please be sure
400	   this code is fixed accordingly.
401	   It should never copy any pad contained in the structure
402	   to avoid security leaks, but must copy the generic
403	   3 ints plus the relevant union member.
404	   This routine must convert siginfo from 64bit to 32bit as well
405	   at the same time.  */
406	err = __put_user(from->si_signo, &to->si_signo);
407	err |= __put_user(from->si_errno, &to->si_errno);
408	err |= __put_user((short)from->si_code, &to->si_code);
409	if (from->si_code < 0)
410		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
411	else {
412		switch (from->si_code >> 16) {
413		case __SI_TIMER >> 16:
414			err |= __put_user(from->si_tid, &to->si_tid);
415			err |= __put_user(from->si_overrun, &to->si_overrun);
416			err |= __put_user(from->si_int, &to->si_int);
417			break;
418		case __SI_CHLD >> 16:
419			err |= __put_user(from->si_utime, &to->si_utime);
420			err |= __put_user(from->si_stime, &to->si_stime);
421			err |= __put_user(from->si_status, &to->si_status);
422		default:
423			err |= __put_user(from->si_pid, &to->si_pid);
424			err |= __put_user(from->si_uid, &to->si_uid);
425			break;
426		case __SI_FAULT >> 16:
427			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
428			break;
429		case __SI_POLL >> 16:
430			err |= __put_user(from->si_band, &to->si_band);
431			err |= __put_user(from->si_fd, &to->si_fd);
432			break;
433		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
434		case __SI_MESGQ >> 16:
435			err |= __put_user(from->si_pid, &to->si_pid);
436			err |= __put_user(from->si_uid, &to->si_uid);
437			err |= __put_user(from->si_int, &to->si_int);
438			break;
439		}
440	}
441	return err;
442}
443
444int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
445{
446	memset(to, 0, sizeof *to);
447
448	if (copy_from_user(to, from, 3*sizeof(int)) ||
449	    copy_from_user(to->_sifields._pad,
450			   from->_sifields._pad, SI_PAD_SIZE32))
451		return -EFAULT;
452
453	return 0;
454}
455
456asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
457{
458	struct sigframe32 __user *frame;
459	sigset_t blocked;
460	int sig;
461
462	frame = (struct sigframe32 __user *) regs.regs[29];
463	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
464		goto badframe;
465	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
466		goto badframe;
467
468	set_current_blocked(&blocked);
469
470	sig = restore_sigcontext32(&regs, &frame->sf_sc);
471	if (sig < 0)
472		goto badframe;
473	else if (sig)
474		force_sig(sig, current);
475
476	/*
477	 * Don't let your children do this ...
478	 */
479	__asm__ __volatile__(
480		"move\t$29, %0\n\t"
481		"j\tsyscall_exit"
482		:/* no outputs */
483		:"r" (&regs));
484	/* Unreached */
485
486badframe:
487	force_sig(SIGSEGV, current);
488}
489
490asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
491{
492	struct rt_sigframe32 __user *frame;
493	mm_segment_t old_fs;
494	sigset_t set;
495	stack_t st;
496	s32 sp;
497	int sig;
498
499	frame = (struct rt_sigframe32 __user *) regs.regs[29];
500	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
501		goto badframe;
502	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
503		goto badframe;
504
505	set_current_blocked(&set);
506
507	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
508	if (sig < 0)
509		goto badframe;
510	else if (sig)
511		force_sig(sig, current);
512
513	/* The ucontext contains a stack32_t, so we must convert!  */
514	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
515		goto badframe;
516	st.ss_sp = (void __user *)(long) sp;
517	if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
518		goto badframe;
519	if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
520		goto badframe;
521
522	/* It is more difficult to avoid calling this function than to
523	   call it and ignore errors.  */
524	old_fs = get_fs();
525	set_fs(KERNEL_DS);
526	do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
527	set_fs(old_fs);
528
529	/*
530	 * Don't let your children do this ...
531	 */
532	__asm__ __volatile__(
533		"move\t$29, %0\n\t"
534		"j\tsyscall_exit"
535		:/* no outputs */
536		:"r" (&regs));
537	/* Unreached */
538
539badframe:
540	force_sig(SIGSEGV, current);
541}
542
543static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
544			  struct pt_regs *regs, int signr, sigset_t *set)
545{
546	struct sigframe32 __user *frame;
547	int err = 0;
548
549	frame = get_sigframe(ka, regs, sizeof(*frame));
550	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
551		goto give_sigsegv;
552
553	err |= setup_sigcontext32(regs, &frame->sf_sc);
554	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
555
556	if (err)
557		goto give_sigsegv;
558
559	/*
560	 * Arguments to signal handler:
561	 *
562	 *   a0 = signal number
563	 *   a1 = 0 (should be cause)
564	 *   a2 = pointer to struct sigcontext
565	 *
566	 * $25 and c0_epc point to the signal handler, $29 points to the
567	 * struct sigframe.
568	 */
569	regs->regs[ 4] = signr;
570	regs->regs[ 5] = 0;
571	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
572	regs->regs[29] = (unsigned long) frame;
573	regs->regs[31] = (unsigned long) sig_return;
574	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
575
576	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
577	       current->comm, current->pid,
578	       frame, regs->cp0_epc, regs->regs[31]);
579
580	return 0;
581
582give_sigsegv:
583	force_sigsegv(signr, current);
584	return -EFAULT;
585}
586
587static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
588			     struct pt_regs *regs, int signr, sigset_t *set,
589			     siginfo_t *info)
590{
591	struct rt_sigframe32 __user *frame;
592	int err = 0;
593	s32 sp;
594
595	frame = get_sigframe(ka, regs, sizeof(*frame));
596	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
597		goto give_sigsegv;
598
599	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
600	err |= copy_siginfo_to_user32(&frame->rs_info, info);
601
602	/* Create the ucontext.  */
603	err |= __put_user(0, &frame->rs_uc.uc_flags);
604	err |= __put_user(0, &frame->rs_uc.uc_link);
605	sp = (int) (long) current->sas_ss_sp;
606	err |= __put_user(sp,
607	                  &frame->rs_uc.uc_stack.ss_sp);
608	err |= __put_user(sas_ss_flags(regs->regs[29]),
609	                  &frame->rs_uc.uc_stack.ss_flags);
610	err |= __put_user(current->sas_ss_size,
611	                  &frame->rs_uc.uc_stack.ss_size);
612	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
613	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
614
615	if (err)
616		goto give_sigsegv;
617
618	/*
619	 * Arguments to signal handler:
620	 *
621	 *   a0 = signal number
622	 *   a1 = 0 (should be cause)
623	 *   a2 = pointer to ucontext
624	 *
625	 * $25 and c0_epc point to the signal handler, $29 points to
626	 * the struct rt_sigframe32.
627	 */
628	regs->regs[ 4] = signr;
629	regs->regs[ 5] = (unsigned long) &frame->rs_info;
630	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
631	regs->regs[29] = (unsigned long) frame;
632	regs->regs[31] = (unsigned long) sig_return;
633	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
634
635	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
636	       current->comm, current->pid,
637	       frame, regs->cp0_epc, regs->regs[31]);
638
639	return 0;
640
641give_sigsegv:
642	force_sigsegv(signr, current);
643	return -EFAULT;
644}
645
646/*
647 * o32 compatibility on 64-bit kernels, without DSP ASE
648 */
649struct mips_abi mips_abi_32 = {
650	.setup_frame	= setup_frame_32,
651	.signal_return_offset =
652		offsetof(struct mips_vdso, o32_signal_trampoline),
653	.setup_rt_frame	= setup_rt_frame_32,
654	.rt_signal_return_offset =
655		offsetof(struct mips_vdso, o32_rt_signal_trampoline),
656	.restart	= __NR_O32_restart_syscall
657};
658
659SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
660	const struct sigaction32 __user *, act,
661	struct sigaction32 __user *, oact, unsigned int, sigsetsize)
662{
663	struct k_sigaction new_sa, old_sa;
664	int ret = -EINVAL;
665
666	/* XXX: Don't preclude handling different sized sigset_t's.  */
667	if (sigsetsize != sizeof(sigset_t))
668		goto out;
669
670	if (act) {
671		s32 handler;
672		int err = 0;
673
674		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
675			return -EFAULT;
676		err |= __get_user(handler, &act->sa_handler);
677		new_sa.sa.sa_handler = (void __user *)(s64)handler;
678		err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
679		err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
680		if (err)
681			return -EFAULT;
682	}
683
684	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
685
686	if (!ret && oact) {
687		int err = 0;
688
689		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
690			return -EFAULT;
691
692		err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
693		                   &oact->sa_handler);
694		err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
695		err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
696		if (err)
697			return -EFAULT;
698	}
699out:
700	return ret;
701}
702
703SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
704	compat_sigset_t __user *, oset, unsigned int, sigsetsize)
705{
706	sigset_t old_set, new_set;
707	int ret;
708	mm_segment_t old_fs = get_fs();
709
710	if (set && get_sigset(&new_set, set))
711		return -EFAULT;
712
713	set_fs(KERNEL_DS);
714	ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
715				 oset ? (sigset_t __user *)&old_set : NULL,
716				 sigsetsize);
717	set_fs(old_fs);
718
719	if (!ret && oset && put_sigset(&old_set, oset))
720		return -EFAULT;
721
722	return ret;
723}
724
725SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
726	unsigned int, sigsetsize)
727{
728	int ret;
729	sigset_t set;
730	mm_segment_t old_fs = get_fs();
731
732	set_fs(KERNEL_DS);
733	ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
734	set_fs(old_fs);
735
736	if (!ret && put_sigset(&set, uset))
737		return -EFAULT;
738
739	return ret;
740}
741
742SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
743	compat_siginfo_t __user *, uinfo)
744{
745	siginfo_t info;
746	int ret;
747	mm_segment_t old_fs = get_fs();
748
749	if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
750	    copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
751		return -EFAULT;
752	set_fs(KERNEL_DS);
753	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
754	set_fs(old_fs);
755	return ret;
756}
757
758SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
759	     compat_siginfo_t __user *, uinfo, int, options,
760	     struct compat_rusage __user *, uru)
761{
762	siginfo_t info;
763	struct rusage ru;
764	long ret;
765	mm_segment_t old_fs = get_fs();
766
767	info.si_signo = 0;
768	set_fs(KERNEL_DS);
769	ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
770			 uru ? (struct rusage __user *) &ru : NULL);
771	set_fs(old_fs);
772
773	if (ret < 0 || info.si_signo == 0)
774		return ret;
775
776	if (uru && (ret = put_compat_rusage(&ru, uru)))
777		return ret;
778
779	BUG_ON(info.si_code & __SI_MASK);
780	info.si_code |= __SI_CHLD;
781	return copy_siginfo_to_user32(uinfo, &info);
782}
783
784static int signal32_init(void)
785{
786	if (cpu_has_fpu) {
787		save_fp_context32 = _save_fp_context32;
788		restore_fp_context32 = _restore_fp_context32;
789	} else {
790		save_fp_context32 = fpu_emulator_save_context32;
791		restore_fp_context32 = fpu_emulator_restore_context32;
792	}
793
794	return 0;
795}
796
797arch_initcall(signal32_init);
v4.6
  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, 2006  Ralf Baechle
  8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9 */
 10#include <linux/cache.h>
 11#include <linux/compat.h>
 12#include <linux/sched.h>
 13#include <linux/mm.h>
 14#include <linux/smp.h>
 15#include <linux/kernel.h>
 16#include <linux/signal.h>
 17#include <linux/syscalls.h>
 18#include <linux/errno.h>
 19#include <linux/wait.h>
 20#include <linux/ptrace.h>
 21#include <linux/suspend.h>
 22#include <linux/compiler.h>
 23#include <linux/uaccess.h>
 24
 25#include <asm/abi.h>
 26#include <asm/asm.h>
 27#include <asm/compat-signal.h>
 28#include <linux/bitops.h>
 29#include <asm/cacheflush.h>
 30#include <asm/sim.h>
 31#include <asm/ucontext.h>
 32#include <asm/fpu.h>
 33#include <asm/war.h>
 
 34#include <asm/dsp.h>
 35
 36#include "signal-common.h"
 37
 
 
 
 
 
 
 
 
 
 38/*
 39 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
 40 */
 41#define __NR_O32_restart_syscall	4253
 42
 43/* 32-bit compatibility types */
 44
 45typedef unsigned int __sighandler32_t;
 46typedef void (*vfptr_t)(void);
 47
 
 
 
 
 
 
 
 
 
 
 
 
 
 48struct ucontext32 {
 49	u32		    uc_flags;
 50	s32		    uc_link;
 51	compat_stack_t      uc_stack;
 52	struct sigcontext32 uc_mcontext;
 53	compat_sigset_t	    uc_sigmask;	  /* mask last for extensibility */
 54};
 55
 56struct sigframe32 {
 57	u32 sf_ass[4];		/* argument save space for o32 */
 58	u32 sf_pad[2];		/* Was: signal trampoline */
 59	struct sigcontext32 sf_sc;
 60	compat_sigset_t sf_mask;
 61};
 62
 63struct rt_sigframe32 {
 64	u32 rs_ass[4];			/* argument save space for o32 */
 65	u32 rs_pad[2];			/* Was: signal trampoline */
 66	compat_siginfo_t rs_info;
 67	struct ucontext32 rs_uc;
 68};
 69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 70static int setup_sigcontext32(struct pt_regs *regs,
 71			      struct sigcontext32 __user *sc)
 72{
 73	int err = 0;
 74	int i;
 
 75
 76	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 77
 78	err |= __put_user(0, &sc->sc_regs[0]);
 79	for (i = 1; i < 32; i++)
 80		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 81
 82	err |= __put_user(regs->hi, &sc->sc_mdhi);
 83	err |= __put_user(regs->lo, &sc->sc_mdlo);
 84	if (cpu_has_dsp) {
 85		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
 86		err |= __put_user(mfhi1(), &sc->sc_hi1);
 87		err |= __put_user(mflo1(), &sc->sc_lo1);
 88		err |= __put_user(mfhi2(), &sc->sc_hi2);
 89		err |= __put_user(mflo2(), &sc->sc_lo2);
 90		err |= __put_user(mfhi3(), &sc->sc_hi3);
 91		err |= __put_user(mflo3(), &sc->sc_lo3);
 92	}
 93
 94	/*
 95	 * Save FPU state to signal context.  Signal handler
 96	 * will "inherit" current FPU state.
 97	 */
 98	err |= protected_save_fp_context(sc);
 99
 
 
 
 
 
 
 
100	return err;
101}
102
 
 
 
 
 
 
 
 
 
 
 
 
103static int restore_sigcontext32(struct pt_regs *regs,
104				struct sigcontext32 __user *sc)
105{
 
106	int err = 0;
107	s32 treg;
108	int i;
109
110	/* Always make any pending restarted system calls return -EINTR */
111	current->restart_block.fn = do_no_restart_syscall;
112
113	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
114	err |= __get_user(regs->hi, &sc->sc_mdhi);
115	err |= __get_user(regs->lo, &sc->sc_mdlo);
116	if (cpu_has_dsp) {
117		err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
118		err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
119		err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
120		err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
121		err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
122		err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
123		err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
124	}
125
126	for (i = 1; i < 32; i++)
127		err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
128
129	return err ?: protected_restore_fp_context(sc);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130}
131
132/*
133 * Atomically swap in the new signal mask, and wait for a signal.
134 */
135
136asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
137{
138	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139}
140
141SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
142	struct compat_sigaction __user *, oact)
143{
144	struct k_sigaction new_ka, old_ka;
145	int ret;
146	int err = 0;
147
148	if (act) {
149		old_sigset_t mask;
150		s32 handler;
151
152		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
153			return -EFAULT;
154		err |= __get_user(handler, &act->sa_handler);
155		new_ka.sa.sa_handler = (void __user *)(s64)handler;
156		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
157		err |= __get_user(mask, &act->sa_mask.sig[0]);
158		if (err)
159			return -EFAULT;
160
161		siginitset(&new_ka.sa.sa_mask, mask);
162	}
163
164	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
165
166	if (!ret && oact) {
167		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
168			return -EFAULT;
169		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
170		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
171				  &oact->sa_handler);
172		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
173		err |= __put_user(0, &oact->sa_mask.sig[1]);
174		err |= __put_user(0, &oact->sa_mask.sig[2]);
175		err |= __put_user(0, &oact->sa_mask.sig[3]);
176		if (err)
177			return -EFAULT;
178	}
179
180	return ret;
181}
182
183int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184{
185	int err;
186
187	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
188		return -EFAULT;
189
190	/* If you change siginfo_t structure, please be sure
191	   this code is fixed accordingly.
192	   It should never copy any pad contained in the structure
193	   to avoid security leaks, but must copy the generic
194	   3 ints plus the relevant union member.
195	   This routine must convert siginfo from 64bit to 32bit as well
196	   at the same time.  */
197	err = __put_user(from->si_signo, &to->si_signo);
198	err |= __put_user(from->si_errno, &to->si_errno);
199	err |= __put_user((short)from->si_code, &to->si_code);
200	if (from->si_code < 0)
201		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
202	else {
203		switch (from->si_code >> 16) {
204		case __SI_TIMER >> 16:
205			err |= __put_user(from->si_tid, &to->si_tid);
206			err |= __put_user(from->si_overrun, &to->si_overrun);
207			err |= __put_user(from->si_int, &to->si_int);
208			break;
209		case __SI_CHLD >> 16:
210			err |= __put_user(from->si_utime, &to->si_utime);
211			err |= __put_user(from->si_stime, &to->si_stime);
212			err |= __put_user(from->si_status, &to->si_status);
213		default:
214			err |= __put_user(from->si_pid, &to->si_pid);
215			err |= __put_user(from->si_uid, &to->si_uid);
216			break;
217		case __SI_FAULT >> 16:
218			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
219			break;
220		case __SI_POLL >> 16:
221			err |= __put_user(from->si_band, &to->si_band);
222			err |= __put_user(from->si_fd, &to->si_fd);
223			break;
224		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
225		case __SI_MESGQ >> 16:
226			err |= __put_user(from->si_pid, &to->si_pid);
227			err |= __put_user(from->si_uid, &to->si_uid);
228			err |= __put_user(from->si_int, &to->si_int);
229			break;
230		}
231	}
232	return err;
233}
234
235int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
236{
 
 
237	if (copy_from_user(to, from, 3*sizeof(int)) ||
238	    copy_from_user(to->_sifields._pad,
239			   from->_sifields._pad, SI_PAD_SIZE32))
240		return -EFAULT;
241
242	return 0;
243}
244
245asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
246{
247	struct sigframe32 __user *frame;
248	sigset_t blocked;
249	int sig;
250
251	frame = (struct sigframe32 __user *) regs.regs[29];
252	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
253		goto badframe;
254	if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
255		goto badframe;
256
257	set_current_blocked(&blocked);
258
259	sig = restore_sigcontext32(&regs, &frame->sf_sc);
260	if (sig < 0)
261		goto badframe;
262	else if (sig)
263		force_sig(sig, current);
264
265	/*
266	 * Don't let your children do this ...
267	 */
268	__asm__ __volatile__(
269		"move\t$29, %0\n\t"
270		"j\tsyscall_exit"
271		:/* no outputs */
272		:"r" (&regs));
273	/* Unreached */
274
275badframe:
276	force_sig(SIGSEGV, current);
277}
278
279asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
280{
281	struct rt_sigframe32 __user *frame;
 
282	sigset_t set;
 
 
283	int sig;
284
285	frame = (struct rt_sigframe32 __user *) regs.regs[29];
286	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
287		goto badframe;
288	if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
289		goto badframe;
290
291	set_current_blocked(&set);
292
293	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
294	if (sig < 0)
295		goto badframe;
296	else if (sig)
297		force_sig(sig, current);
298
299	if (compat_restore_altstack(&frame->rs_uc.uc_stack))
 
 
 
 
300		goto badframe;
 
 
 
 
 
 
 
 
 
301
302	/*
303	 * Don't let your children do this ...
304	 */
305	__asm__ __volatile__(
306		"move\t$29, %0\n\t"
307		"j\tsyscall_exit"
308		:/* no outputs */
309		:"r" (&regs));
310	/* Unreached */
311
312badframe:
313	force_sig(SIGSEGV, current);
314}
315
316static int setup_frame_32(void *sig_return, struct ksignal *ksig,
317			  struct pt_regs *regs, sigset_t *set)
318{
319	struct sigframe32 __user *frame;
320	int err = 0;
321
322	frame = get_sigframe(ksig, regs, sizeof(*frame));
323	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
324		return -EFAULT;
325
326	err |= setup_sigcontext32(regs, &frame->sf_sc);
327	err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
328
329	if (err)
330		return -EFAULT;
331
332	/*
333	 * Arguments to signal handler:
334	 *
335	 *   a0 = signal number
336	 *   a1 = 0 (should be cause)
337	 *   a2 = pointer to struct sigcontext
338	 *
339	 * $25 and c0_epc point to the signal handler, $29 points to the
340	 * struct sigframe.
341	 */
342	regs->regs[ 4] = ksig->sig;
343	regs->regs[ 5] = 0;
344	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
345	regs->regs[29] = (unsigned long) frame;
346	regs->regs[31] = (unsigned long) sig_return;
347	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
348
349	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
350	       current->comm, current->pid,
351	       frame, regs->cp0_epc, regs->regs[31]);
352
353	return 0;
 
 
 
 
354}
355
356static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
357			     struct pt_regs *regs, sigset_t *set)
 
358{
359	struct rt_sigframe32 __user *frame;
360	int err = 0;
 
361
362	frame = get_sigframe(ksig, regs, sizeof(*frame));
363	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
364		return -EFAULT;
365
366	/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
367	err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
368
369	/* Create the ucontext.	 */
370	err |= __put_user(0, &frame->rs_uc.uc_flags);
371	err |= __put_user(0, &frame->rs_uc.uc_link);
372	err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
 
 
 
 
 
 
373	err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
374	err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
375
376	if (err)
377		return -EFAULT;
378
379	/*
380	 * Arguments to signal handler:
381	 *
382	 *   a0 = signal number
383	 *   a1 = 0 (should be cause)
384	 *   a2 = pointer to ucontext
385	 *
386	 * $25 and c0_epc point to the signal handler, $29 points to
387	 * the struct rt_sigframe32.
388	 */
389	regs->regs[ 4] = ksig->sig;
390	regs->regs[ 5] = (unsigned long) &frame->rs_info;
391	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
392	regs->regs[29] = (unsigned long) frame;
393	regs->regs[31] = (unsigned long) sig_return;
394	regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
395
396	DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
397	       current->comm, current->pid,
398	       frame, regs->cp0_epc, regs->regs[31]);
399
400	return 0;
 
 
 
 
401}
402
403/*
404 * o32 compatibility on 64-bit kernels, without DSP ASE
405 */
406struct mips_abi mips_abi_32 = {
407	.setup_frame	= setup_frame_32,
408	.setup_rt_frame = setup_rt_frame_32,
409	.restart	= __NR_O32_restart_syscall,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
411	.off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
412	.off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
413	.off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
 
 
 
 
 
 
414
415	.vdso		= &vdso_image_o32,
416};