• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/parisc/kernel/
1/*    Signal support for 32-bit kernel builds
2 *
3 *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
5 *
6 *    Code was mostly borrowed from kernel/signal.c.
7 *    See kernel/signal.c for additional Copyrights.
8 *
9 *
10 *    This program is free software; you can redistribute it and/or modify
11 *    it under the terms of the GNU General Public License as published by
12 *    the Free Software Foundation; either version 2 of the License, or
13 *    (at your option) any later version.
14 *
15 *    This program is distributed in the hope that it will be useful,
16 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *    GNU General Public License for more details.
19 *
20 *    You should have received a copy of the GNU General Public License
21 *    along with this program; if not, write to the Free Software
22 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#include <linux/compat.h>
26#include <linux/module.h>
27#include <linux/unistd.h>
28#include <linux/init.h>
29#include <linux/sched.h>
30#include <linux/syscalls.h>
31#include <linux/types.h>
32#include <linux/errno.h>
33
34#include <asm/uaccess.h>
35
36#include "signal32.h"
37#include "sys32.h"
38
39#define DEBUG_COMPAT_SIG 0
40#define DEBUG_COMPAT_SIG_LEVEL 2
41
42#if DEBUG_COMPAT_SIG
43#define DBG(LEVEL, ...) \
44	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45	? printk(__VA_ARGS__) : (void) 0)
46#else
47#define DBG(LEVEL, ...)
48#endif
49
50#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51
52inline void
53sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
54{
55	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
56}
57
58inline void
59sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
60{
61	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
62	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
63}
64
65static int
66put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
67{
68	compat_sigset_t s;
69
70	if (sz != sizeof *set) panic("put_sigset32()");
71	sigset_64to32(&s, set);
72
73	return copy_to_user(up, &s, sizeof s);
74}
75
76static int
77get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
78{
79	compat_sigset_t s;
80	int r;
81
82	if (sz != sizeof *set) panic("put_sigset32()");
83
84	if ((r = copy_from_user(&s, up, sz)) == 0) {
85		sigset_32to64(set, &s);
86	}
87
88	return r;
89}
90
91int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
92				    unsigned int sigsetsize)
93{
94	sigset_t old_set, new_set;
95	int ret;
96
97	if (set && get_sigset32(set, &new_set, sigsetsize))
98		return -EFAULT;
99
100	KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
101				 oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
102
103	if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
104		return -EFAULT;
105
106	return ret;
107}
108
109
110int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
111{
112	int ret;
113	sigset_t set;
114
115	KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
116
117	if (!ret && put_sigset32(uset, &set, sigsetsize))
118		return -EFAULT;
119
120	return ret;
121}
122
123long
124sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
125                 size_t sigsetsize)
126{
127	struct k_sigaction32 new_sa32, old_sa32;
128	struct k_sigaction new_sa, old_sa;
129	int ret = -EINVAL;
130
131	if (act) {
132		if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
133			return -EFAULT;
134		new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
135		new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
136		sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
137	}
138
139	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
140
141	if (!ret && oact) {
142		sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
143		old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
144		old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
145		if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
146			return -EFAULT;
147	}
148	return ret;
149}
150
151int
152do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
153{
154	compat_stack_t ss32, oss32;
155	stack_t ss, oss;
156	stack_t *ssp = NULL, *ossp = NULL;
157	int ret;
158
159	if (uss32) {
160		if (copy_from_user(&ss32, uss32, sizeof ss32))
161			return -EFAULT;
162
163		ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
164		ss.ss_flags = ss32.ss_flags;
165		ss.ss_size = ss32.ss_size;
166
167		ssp = &ss;
168	}
169
170	if (uoss32)
171		ossp = &oss;
172
173	KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
174
175	if (!ret && uoss32) {
176		oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
177		oss32.ss_flags = oss.ss_flags;
178		oss32.ss_size = oss.ss_size;
179		if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
180			return -EFAULT;
181	}
182
183	return ret;
184}
185
186long
187restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
188		struct pt_regs *regs)
189{
190	long err = 0;
191	compat_uint_t compat_reg;
192	compat_uint_t compat_regt;
193	int regn;
194
195	/* When loading 32-bit values into 64-bit registers make
196	   sure to clear the upper 32-bits */
197	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
198	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
199	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
200	for(regn=0; regn < 32; regn++){
201		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
202		regs->gr[regn] = compat_reg;
203		/* Load upper half */
204		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
205		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
206		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
207				regn, regs->gr[regn], compat_regt, compat_reg);
208	}
209	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
210	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
211
212	/* Better safe than sorry, pass __get_user two things of
213	   the same size and let gcc do the upward conversion to
214	   64-bits */
215	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
216	/* Load upper half */
217	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
218	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
219	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
220	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
221			&sc->sc_iaoq[0], compat_reg);
222
223	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
224	/* Load upper half */
225	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
226	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
227	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
228	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
229			&sc->sc_iaoq[1],compat_reg);
230	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
231			regs->iaoq[0],regs->iaoq[1]);
232
233	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
234	/* Load the upper half for iasq */
235	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
236	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
237	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
238
239	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
240	/* Load the upper half for iasq */
241	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
242	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
243	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
244	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
245		regs->iasq[0],regs->iasq[1]);
246
247	err |= __get_user(compat_reg, &sc->sc_sar);
248	/* Load the upper half for sar */
249	err |= __get_user(compat_regt, &rf->rf_sar);
250	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
251	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
252	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
253	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
254
255	return err;
256}
257
258/*
259 * Set up the sigcontext structure for this process.
260 * This is not an easy task if the kernel is 64-bit, it will require
261 * that we examine the process personality to determine if we need to
262 * truncate for a 32-bit userspace.
263 */
264long
265setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
266		struct pt_regs *regs, int in_syscall)
267{
268	compat_int_t flags = 0;
269	long err = 0;
270	compat_uint_t compat_reg;
271	compat_uint_t compat_regb;
272	int regn;
273
274	if (on_sig_stack((unsigned long) sc))
275		flags |= PARISC_SC_FLAG_ONSTACK;
276
277	if (in_syscall) {
278
279		DBG(1,"setup_sigcontext32: in_syscall\n");
280
281		flags |= PARISC_SC_FLAG_IN_SYSCALL;
282		/* Truncate gr31 */
283		compat_reg = (compat_uint_t)(regs->gr[31]);
284		/* regs->iaoq is undefined in the syscall return path */
285		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
286		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
287				&sc->sc_iaoq[0], compat_reg);
288
289		/* Store upper half */
290		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
291		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
292		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
293
294
295		compat_reg = (compat_uint_t)(regs->gr[31]+4);
296		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
297		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
298				&sc->sc_iaoq[1], compat_reg);
299		/* Store upper half */
300		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
301		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
302		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
303
304		/* Truncate sr3 */
305		compat_reg = (compat_uint_t)(regs->sr[3]);
306		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
307		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
308
309		/* Store upper half */
310		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
311		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
312		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
313
314		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
315		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
316		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
317			regs->gr[31], regs->gr[31]+4);
318
319	} else {
320
321		compat_reg = (compat_uint_t)(regs->iaoq[0]);
322		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
323		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
324				&sc->sc_iaoq[0], compat_reg);
325		/* Store upper half */
326		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
327		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
328		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
329
330		compat_reg = (compat_uint_t)(regs->iaoq[1]);
331		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
332		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
333				&sc->sc_iaoq[1], compat_reg);
334		/* Store upper half */
335		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
336		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
337		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
338
339
340		compat_reg = (compat_uint_t)(regs->iasq[0]);
341		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
342		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
343				&sc->sc_iasq[0], compat_reg);
344		/* Store upper half */
345		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
346		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
347		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
348
349
350		compat_reg = (compat_uint_t)(regs->iasq[1]);
351		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
352		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
353				&sc->sc_iasq[1], compat_reg);
354		/* Store upper half */
355		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
356		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
357		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
358
359		/* Print out the IAOQ for debugging */
360		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
361			regs->iaoq[0], regs->iaoq[1]);
362	}
363
364	err |= __put_user(flags, &sc->sc_flags);
365
366	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
367
368	for(regn=0; regn < 32; regn++){
369		/* Truncate a general register */
370		compat_reg = (compat_uint_t)(regs->gr[regn]);
371		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
372		/* Store upper half */
373		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
374		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
375
376		/* DEBUG: Write out the "upper / lower" register data */
377		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
378				compat_regb, compat_reg);
379	}
380
381	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
382	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
383		sizeof(regs->fr), sizeof(sc->sc_fr));
384	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
385
386	compat_reg = (compat_uint_t)(regs->sar);
387	err |= __put_user(compat_reg, &sc->sc_sar);
388	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
389	/* Store upper half */
390	compat_reg = (compat_uint_t)(regs->sar >> 32);
391	err |= __put_user(compat_reg, &rf->rf_sar);
392	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
393	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
394
395	return err;
396}
397
398int
399copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
400{
401	compat_uptr_t addr;
402	int err;
403
404	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
405		return -EFAULT;
406
407	err = __get_user(to->si_signo, &from->si_signo);
408	err |= __get_user(to->si_errno, &from->si_errno);
409	err |= __get_user(to->si_code, &from->si_code);
410
411	if (to->si_code < 0)
412		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
413	else {
414		switch (to->si_code >> 16) {
415		      case __SI_CHLD >> 16:
416			err |= __get_user(to->si_utime, &from->si_utime);
417			err |= __get_user(to->si_stime, &from->si_stime);
418			err |= __get_user(to->si_status, &from->si_status);
419		      default:
420			err |= __get_user(to->si_pid, &from->si_pid);
421			err |= __get_user(to->si_uid, &from->si_uid);
422			break;
423		      case __SI_FAULT >> 16:
424			err |= __get_user(addr, &from->si_addr);
425			to->si_addr = compat_ptr(addr);
426			break;
427		      case __SI_POLL >> 16:
428			err |= __get_user(to->si_band, &from->si_band);
429			err |= __get_user(to->si_fd, &from->si_fd);
430			break;
431		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
432		      case __SI_MESGQ >> 16:
433			err |= __get_user(to->si_pid, &from->si_pid);
434			err |= __get_user(to->si_uid, &from->si_uid);
435			err |= __get_user(to->si_int, &from->si_int);
436			break;
437		}
438	}
439	return err;
440}
441
442int
443copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
444{
445	compat_uptr_t addr;
446	compat_int_t val;
447	int err;
448
449	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
450		return -EFAULT;
451
452	/* If you change siginfo_t structure, please be sure
453	   this code is fixed accordingly.
454	   It should never copy any pad contained in the structure
455	   to avoid security leaks, but must copy the generic
456	   3 ints plus the relevant union member.
457	   This routine must convert siginfo from 64bit to 32bit as well
458	   at the same time.  */
459	err = __put_user(from->si_signo, &to->si_signo);
460	err |= __put_user(from->si_errno, &to->si_errno);
461	err |= __put_user((short)from->si_code, &to->si_code);
462	if (from->si_code < 0)
463		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
464	else {
465		switch (from->si_code >> 16) {
466		case __SI_CHLD >> 16:
467			err |= __put_user(from->si_utime, &to->si_utime);
468			err |= __put_user(from->si_stime, &to->si_stime);
469			err |= __put_user(from->si_status, &to->si_status);
470		default:
471			err |= __put_user(from->si_pid, &to->si_pid);
472			err |= __put_user(from->si_uid, &to->si_uid);
473			break;
474		case __SI_FAULT >> 16:
475			addr = ptr_to_compat(from->si_addr);
476			err |= __put_user(addr, &to->si_addr);
477			break;
478		case __SI_POLL >> 16:
479			err |= __put_user(from->si_band, &to->si_band);
480			err |= __put_user(from->si_fd, &to->si_fd);
481			break;
482		case __SI_TIMER >> 16:
483			err |= __put_user(from->si_tid, &to->si_tid);
484			err |= __put_user(from->si_overrun, &to->si_overrun);
485			val = (compat_int_t)from->si_int;
486			err |= __put_user(val, &to->si_int);
487			break;
488		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
489		case __SI_MESGQ >> 16:
490			err |= __put_user(from->si_uid, &to->si_uid);
491			err |= __put_user(from->si_pid, &to->si_pid);
492			val = (compat_int_t)from->si_int;
493			err |= __put_user(val, &to->si_int);
494			break;
495		}
496	}
497	return err;
498}
499
500asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
501	struct compat_siginfo __user *uinfo)
502{
503	siginfo_t info;
504
505	if (copy_siginfo_from_user32(&info, uinfo))
506		return -EFAULT;
507
508	/* Not even root can pretend to send signals from the kernel.
509	   Nor can they impersonate a kill(), which adds source info.  */
510	if (info.si_code >= 0)
511		return -EPERM;
512	info.si_signo = sig;
513
514	/* POSIX.1b doesn't mention process groups.  */
515	return kill_proc_info(sig, &info, pid);
516}
517