Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
signal32.c
Go to the documentation of this file.
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)
69  return -EINVAL;
70  sigset_64to32(&s, set);
71 
72  return copy_to_user(up, &s, sizeof s);
73 }
74 
75 static int
76 get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
77 {
78  compat_sigset_t s;
79  int r;
80 
81  if (sz != sizeof *set)
82  return -EINVAL;
83 
84  if ((r = copy_from_user(&s, up, sz)) == 0) {
85  sigset_32to64(set, &s);
86  }
87 
88  return r;
89 }
90 
91 int 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 
110 int 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 
123 long
124 sys32_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 
151 int
152 do_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 
186 long
187 restore_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  /* XXX: BE WARNED FR's are 64-BIT! */
211  err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
212 
213  /* Better safe than sorry, pass __get_user two things of
214  the same size and let gcc do the upward conversion to
215  64-bits */
216  err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
217  /* Load upper half */
218  err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
219  regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
220  DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
221  DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
222  &sc->sc_iaoq[0], compat_reg);
223 
224  err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
225  /* Load upper half */
226  err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
227  regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
228  DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
229  DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
230  &sc->sc_iaoq[1],compat_reg);
231  DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
232  regs->iaoq[0],regs->iaoq[1]);
233 
234  err |= __get_user(compat_reg, &sc->sc_iasq[0]);
235  /* Load the upper half for iasq */
236  err |= __get_user(compat_regt, &rf->rf_iasq[0]);
237  regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
238  DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
239 
240  err |= __get_user(compat_reg, &sc->sc_iasq[1]);
241  /* Load the upper half for iasq */
242  err |= __get_user(compat_regt, &rf->rf_iasq[1]);
243  regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
244  DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
245  DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
246  regs->iasq[0],regs->iasq[1]);
247 
248  err |= __get_user(compat_reg, &sc->sc_sar);
249  /* Load the upper half for sar */
250  err |= __get_user(compat_regt, &rf->rf_sar);
251  regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
252  DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
253  DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
254  DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
255 
256  return err;
257 }
258 
259 /*
260  * Set up the sigcontext structure for this process.
261  * This is not an easy task if the kernel is 64-bit, it will require
262  * that we examine the process personality to determine if we need to
263  * truncate for a 32-bit userspace.
264  */
265 long
266 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
267  struct pt_regs *regs, int in_syscall)
268 {
269  compat_int_t flags = 0;
270  long err = 0;
271  compat_uint_t compat_reg;
272  compat_uint_t compat_regb;
273  int regn;
274 
275  if (on_sig_stack((unsigned long) sc))
276  flags |= PARISC_SC_FLAG_ONSTACK;
277 
278  if (in_syscall) {
279 
280  DBG(1,"setup_sigcontext32: in_syscall\n");
281 
282  flags |= PARISC_SC_FLAG_IN_SYSCALL;
283  /* Truncate gr31 */
284  compat_reg = (compat_uint_t)(regs->gr[31]);
285  /* regs->iaoq is undefined in the syscall return path */
286  err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
287  DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
288  &sc->sc_iaoq[0], compat_reg);
289 
290  /* Store upper half */
291  compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
292  err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
293  DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
294 
295 
296  compat_reg = (compat_uint_t)(regs->gr[31]+4);
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->gr[31]+4) >> 32);
302  err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
303  DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
304 
305  /* Truncate sr3 */
306  compat_reg = (compat_uint_t)(regs->sr[3]);
307  err |= __put_user(compat_reg, &sc->sc_iasq[0]);
308  err |= __put_user(compat_reg, &sc->sc_iasq[1]);
309 
310  /* Store upper half */
311  compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
312  err |= __put_user(compat_reg, &rf->rf_iasq[0]);
313  err |= __put_user(compat_reg, &rf->rf_iasq[1]);
314 
315  DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
316  DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
317  DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
318  regs->gr[31], regs->gr[31]+4);
319 
320  } else {
321 
322  compat_reg = (compat_uint_t)(regs->iaoq[0]);
323  err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
324  DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
325  &sc->sc_iaoq[0], compat_reg);
326  /* Store upper half */
327  compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
328  err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
329  DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
330 
331  compat_reg = (compat_uint_t)(regs->iaoq[1]);
332  err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
333  DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
334  &sc->sc_iaoq[1], compat_reg);
335  /* Store upper half */
336  compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
337  err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
338  DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
339 
340 
341  compat_reg = (compat_uint_t)(regs->iasq[0]);
342  err |= __put_user(compat_reg, &sc->sc_iasq[0]);
343  DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
344  &sc->sc_iasq[0], compat_reg);
345  /* Store upper half */
346  compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
347  err |= __put_user(compat_reg, &rf->rf_iasq[0]);
348  DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
349 
350 
351  compat_reg = (compat_uint_t)(regs->iasq[1]);
352  err |= __put_user(compat_reg, &sc->sc_iasq[1]);
353  DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
354  &sc->sc_iasq[1], compat_reg);
355  /* Store upper half */
356  compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
357  err |= __put_user(compat_reg, &rf->rf_iasq[1]);
358  DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
359 
360  /* Print out the IAOQ for debugging */
361  DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
362  regs->iaoq[0], regs->iaoq[1]);
363  }
364 
365  err |= __put_user(flags, &sc->sc_flags);
366 
367  DBG(1,"setup_sigcontext32: Truncating general registers.\n");
368 
369  for(regn=0; regn < 32; regn++){
370  /* Truncate a general register */
371  compat_reg = (compat_uint_t)(regs->gr[regn]);
372  err |= __put_user(compat_reg, &sc->sc_gr[regn]);
373  /* Store upper half */
374  compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
375  err |= __put_user(compat_regb, &rf->rf_gr[regn]);
376 
377  /* DEBUG: Write out the "upper / lower" register data */
378  DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
379  compat_regb, compat_reg);
380  }
381 
382  /* Copy the floating point registers (same size)
383  XXX: BE WARNED FR's are 64-BIT! */
384  DBG(1,"setup_sigcontext32: Copying from regs to sc, "
385  "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
386  sizeof(regs->fr), sizeof(sc->sc_fr));
387  err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
388 
389  compat_reg = (compat_uint_t)(regs->sar);
390  err |= __put_user(compat_reg, &sc->sc_sar);
391  DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
392  /* Store upper half */
393  compat_reg = (compat_uint_t)(regs->sar >> 32);
394  err |= __put_user(compat_reg, &rf->rf_sar);
395  DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
396  DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
397 
398  return err;
399 }
400 
401 int
403 {
405  int err;
406 
407  if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
408  return -EFAULT;
409 
410  err = __get_user(to->si_signo, &from->si_signo);
411  err |= __get_user(to->si_errno, &from->si_errno);
412  err |= __get_user(to->si_code, &from->si_code);
413 
414  if (to->si_code < 0)
415  err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
416  else {
417  switch (to->si_code >> 16) {
418  case __SI_CHLD >> 16:
419  err |= __get_user(to->si_utime, &from->si_utime);
420  err |= __get_user(to->si_stime, &from->si_stime);
421  err |= __get_user(to->si_status, &from->si_status);
422  default:
423  err |= __get_user(to->si_pid, &from->si_pid);
424  err |= __get_user(to->si_uid, &from->si_uid);
425  break;
426  case __SI_FAULT >> 16:
427  err |= __get_user(addr, &from->si_addr);
428  to->si_addr = compat_ptr(addr);
429  break;
430  case __SI_POLL >> 16:
431  err |= __get_user(to->si_band, &from->si_band);
432  err |= __get_user(to->si_fd, &from->si_fd);
433  break;
434  case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
435  case __SI_MESGQ >> 16:
436  err |= __get_user(to->si_pid, &from->si_pid);
437  err |= __get_user(to->si_uid, &from->si_uid);
438  err |= __get_user(to->si_int, &from->si_int);
439  break;
440  }
441  }
442  return err;
443 }
444 
445 int
447 {
450  int err;
451 
452  if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
453  return -EFAULT;
454 
455  /* If you change siginfo_t structure, please be sure
456  this code is fixed accordingly.
457  It should never copy any pad contained in the structure
458  to avoid security leaks, but must copy the generic
459  3 ints plus the relevant union member.
460  This routine must convert siginfo from 64bit to 32bit as well
461  at the same time. */
462  err = __put_user(from->si_signo, &to->si_signo);
463  err |= __put_user(from->si_errno, &to->si_errno);
464  err |= __put_user((short)from->si_code, &to->si_code);
465  if (from->si_code < 0)
466  err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
467  else {
468  switch (from->si_code >> 16) {
469  case __SI_CHLD >> 16:
470  err |= __put_user(from->si_utime, &to->si_utime);
471  err |= __put_user(from->si_stime, &to->si_stime);
472  err |= __put_user(from->si_status, &to->si_status);
473  default:
474  err |= __put_user(from->si_pid, &to->si_pid);
475  err |= __put_user(from->si_uid, &to->si_uid);
476  break;
477  case __SI_FAULT >> 16:
478  addr = ptr_to_compat(from->si_addr);
479  err |= __put_user(addr, &to->si_addr);
480  break;
481  case __SI_POLL >> 16:
482  err |= __put_user(from->si_band, &to->si_band);
483  err |= __put_user(from->si_fd, &to->si_fd);
484  break;
485  case __SI_TIMER >> 16:
486  err |= __put_user(from->si_tid, &to->si_tid);
487  err |= __put_user(from->si_overrun, &to->si_overrun);
488  val = (compat_int_t)from->si_int;
489  err |= __put_user(val, &to->si_int);
490  break;
491  case __SI_RT >> 16: /* Not generated by the kernel as of now. */
492  case __SI_MESGQ >> 16:
493  err |= __put_user(from->si_uid, &to->si_uid);
494  err |= __put_user(from->si_pid, &to->si_pid);
495  val = (compat_int_t)from->si_int;
496  err |= __put_user(val, &to->si_int);
497  break;
498  }
499  }
500  return err;
501 }
502 
504  struct compat_siginfo __user *uinfo)
505 {
506  siginfo_t info;
507 
508  if (copy_siginfo_from_user32(&info, uinfo))
509  return -EFAULT;
510 
511  /* Not even root can pretend to send signals from the kernel.
512  Nor can they impersonate a kill(), which adds source info. */
513  if (info.si_code >= 0)
514  return -EPERM;
515  info.si_signo = sig;
516 
517  /* POSIX.1b doesn't mention process groups. */
518  return kill_proc_info(sig, &info, pid);
519 }
520