1 /* Signal support for 32-bit kernel builds
3 * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 * Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
6 * Code was mostly borrowed from kernel/signal.c.
7 * See kernel/signal.c for additional Copyrights.
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.
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.
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
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>
34 #include <asm/uaccess.h>
39 #define DEBUG_COMPAT_SIG 0
40 #define DEBUG_COMPAT_SIG_LEVEL 2
43 #define DBG(LEVEL, ...) \
44 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45 ? printk(__VA_ARGS__) : (void) 0)
47 #define DBG(LEVEL, ...)
51 sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
53 s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
57 sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
59 s32->sig[0] = s64->sig[0] & 0xffffffffUL;
60 s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
64 put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
68 if (sz != sizeof *set)
70 sigset_64to32(&s, set);
72 return copy_to_user(up, &s, sizeof s);
76 get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
81 if (sz != sizeof *set)
84 if ((r = copy_from_user(&s, up, sz)) == 0) {
85 sigset_32to64(set, &s);
91 int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
92 unsigned int sigsetsize)
94 sigset_t old_set, new_set;
97 if (set && get_sigset32(set, &new_set, sigsetsize))
100 KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
101 oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
103 if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
110 int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
115 KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
117 if (!ret && put_sigset32(uset, &set, sigsetsize))
124 sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
127 struct k_sigaction32 new_sa32, old_sa32;
128 struct k_sigaction new_sa, old_sa;
132 if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
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);
139 ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
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))
152 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
153 struct pt_regs *regs)
156 compat_uint_t compat_reg;
157 compat_uint_t compat_regt;
160 /* When loading 32-bit values into 64-bit registers make
161 sure to clear the upper 32-bits */
162 DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
163 DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
164 DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
165 for(regn=0; regn < 32; regn++){
166 err |= __get_user(compat_reg,&sc->sc_gr[regn]);
167 regs->gr[regn] = compat_reg;
168 /* Load upper half */
169 err |= __get_user(compat_regt,&rf->rf_gr[regn]);
170 regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
171 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
172 regn, regs->gr[regn], compat_regt, compat_reg);
174 DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
175 /* XXX: BE WARNED FR's are 64-BIT! */
176 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
178 /* Better safe than sorry, pass __get_user two things of
179 the same size and let gcc do the upward conversion to
181 err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
182 /* Load upper half */
183 err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
184 regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
185 DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
186 DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
187 &sc->sc_iaoq[0], compat_reg);
189 err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
190 /* Load upper half */
191 err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
192 regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
193 DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
194 DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
195 &sc->sc_iaoq[1],compat_reg);
196 DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
197 regs->iaoq[0],regs->iaoq[1]);
199 err |= __get_user(compat_reg, &sc->sc_iasq[0]);
200 /* Load the upper half for iasq */
201 err |= __get_user(compat_regt, &rf->rf_iasq[0]);
202 regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
203 DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
205 err |= __get_user(compat_reg, &sc->sc_iasq[1]);
206 /* Load the upper half for iasq */
207 err |= __get_user(compat_regt, &rf->rf_iasq[1]);
208 regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
209 DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
210 DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
211 regs->iasq[0],regs->iasq[1]);
213 err |= __get_user(compat_reg, &sc->sc_sar);
214 /* Load the upper half for sar */
215 err |= __get_user(compat_regt, &rf->rf_sar);
216 regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
217 DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
218 DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
219 DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
225 * Set up the sigcontext structure for this process.
226 * This is not an easy task if the kernel is 64-bit, it will require
227 * that we examine the process personality to determine if we need to
228 * truncate for a 32-bit userspace.
231 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
232 struct pt_regs *regs, int in_syscall)
234 compat_int_t flags = 0;
236 compat_uint_t compat_reg;
237 compat_uint_t compat_regb;
240 if (on_sig_stack((unsigned long) sc))
241 flags |= PARISC_SC_FLAG_ONSTACK;
245 DBG(1,"setup_sigcontext32: in_syscall\n");
247 flags |= PARISC_SC_FLAG_IN_SYSCALL;
249 compat_reg = (compat_uint_t)(regs->gr[31]);
250 /* regs->iaoq is undefined in the syscall return path */
251 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
252 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
253 &sc->sc_iaoq[0], compat_reg);
255 /* Store upper half */
256 compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
257 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
258 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
261 compat_reg = (compat_uint_t)(regs->gr[31]+4);
262 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
263 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
264 &sc->sc_iaoq[1], compat_reg);
265 /* Store upper half */
266 compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
267 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
268 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
271 compat_reg = (compat_uint_t)(regs->sr[3]);
272 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
273 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
275 /* Store upper half */
276 compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
277 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
278 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
280 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
281 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
282 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
283 regs->gr[31], regs->gr[31]+4);
287 compat_reg = (compat_uint_t)(regs->iaoq[0]);
288 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
289 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
290 &sc->sc_iaoq[0], compat_reg);
291 /* Store upper half */
292 compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
293 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
294 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
296 compat_reg = (compat_uint_t)(regs->iaoq[1]);
297 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
298 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
299 &sc->sc_iaoq[1], compat_reg);
300 /* Store upper half */
301 compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
302 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
303 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
306 compat_reg = (compat_uint_t)(regs->iasq[0]);
307 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
308 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
309 &sc->sc_iasq[0], compat_reg);
310 /* Store upper half */
311 compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
312 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
313 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
316 compat_reg = (compat_uint_t)(regs->iasq[1]);
317 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
318 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
319 &sc->sc_iasq[1], compat_reg);
320 /* Store upper half */
321 compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
322 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
323 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
325 /* Print out the IAOQ for debugging */
326 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
327 regs->iaoq[0], regs->iaoq[1]);
330 err |= __put_user(flags, &sc->sc_flags);
332 DBG(1,"setup_sigcontext32: Truncating general registers.\n");
334 for(regn=0; regn < 32; regn++){
335 /* Truncate a general register */
336 compat_reg = (compat_uint_t)(regs->gr[regn]);
337 err |= __put_user(compat_reg, &sc->sc_gr[regn]);
338 /* Store upper half */
339 compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
340 err |= __put_user(compat_regb, &rf->rf_gr[regn]);
342 /* DEBUG: Write out the "upper / lower" register data */
343 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
344 compat_regb, compat_reg);
347 /* Copy the floating point registers (same size)
348 XXX: BE WARNED FR's are 64-BIT! */
349 DBG(1,"setup_sigcontext32: Copying from regs to sc, "
350 "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
351 sizeof(regs->fr), sizeof(sc->sc_fr));
352 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
354 compat_reg = (compat_uint_t)(regs->sar);
355 err |= __put_user(compat_reg, &sc->sc_sar);
356 DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
357 /* Store upper half */
358 compat_reg = (compat_uint_t)(regs->sar >> 32);
359 err |= __put_user(compat_reg, &rf->rf_sar);
360 DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
361 DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
367 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
372 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
375 err = __get_user(to->si_signo, &from->si_signo);
376 err |= __get_user(to->si_errno, &from->si_errno);
377 err |= __get_user(to->si_code, &from->si_code);
380 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
382 switch (to->si_code >> 16) {
383 case __SI_CHLD >> 16:
384 err |= __get_user(to->si_utime, &from->si_utime);
385 err |= __get_user(to->si_stime, &from->si_stime);
386 err |= __get_user(to->si_status, &from->si_status);
388 err |= __get_user(to->si_pid, &from->si_pid);
389 err |= __get_user(to->si_uid, &from->si_uid);
391 case __SI_FAULT >> 16:
392 err |= __get_user(addr, &from->si_addr);
393 to->si_addr = compat_ptr(addr);
395 case __SI_POLL >> 16:
396 err |= __get_user(to->si_band, &from->si_band);
397 err |= __get_user(to->si_fd, &from->si_fd);
399 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
400 case __SI_MESGQ >> 16:
401 err |= __get_user(to->si_pid, &from->si_pid);
402 err |= __get_user(to->si_uid, &from->si_uid);
403 err |= __get_user(to->si_int, &from->si_int);
411 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
417 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
420 /* If you change siginfo_t structure, please be sure
421 this code is fixed accordingly.
422 It should never copy any pad contained in the structure
423 to avoid security leaks, but must copy the generic
424 3 ints plus the relevant union member.
425 This routine must convert siginfo from 64bit to 32bit as well
427 err = __put_user(from->si_signo, &to->si_signo);
428 err |= __put_user(from->si_errno, &to->si_errno);
429 err |= __put_user((short)from->si_code, &to->si_code);
430 if (from->si_code < 0)
431 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
433 switch (from->si_code >> 16) {
434 case __SI_CHLD >> 16:
435 err |= __put_user(from->si_utime, &to->si_utime);
436 err |= __put_user(from->si_stime, &to->si_stime);
437 err |= __put_user(from->si_status, &to->si_status);
439 err |= __put_user(from->si_pid, &to->si_pid);
440 err |= __put_user(from->si_uid, &to->si_uid);
442 case __SI_FAULT >> 16:
443 addr = ptr_to_compat(from->si_addr);
444 err |= __put_user(addr, &to->si_addr);
446 case __SI_POLL >> 16:
447 err |= __put_user(from->si_band, &to->si_band);
448 err |= __put_user(from->si_fd, &to->si_fd);
450 case __SI_TIMER >> 16:
451 err |= __put_user(from->si_tid, &to->si_tid);
452 err |= __put_user(from->si_overrun, &to->si_overrun);
453 val = (compat_int_t)from->si_int;
454 err |= __put_user(val, &to->si_int);
456 case __SI_RT >> 16: /* Not generated by the kernel as of now. */
457 case __SI_MESGQ >> 16:
458 err |= __put_user(from->si_uid, &to->si_uid);
459 err |= __put_user(from->si_pid, &to->si_pid);
460 val = (compat_int_t)from->si_int;
461 err |= __put_user(val, &to->si_int);
468 asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
469 struct compat_siginfo __user *uinfo)
473 if (copy_siginfo_from_user32(&info, uinfo))
476 /* Not even root can pretend to send signals from the kernel.
477 Nor can they impersonate a kill(), which adds source info. */
478 if (info.si_code >= 0)
482 /* POSIX.1b doesn't mention process groups. */
483 return kill_proc_info(sig, &info, pid);