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