]> Pileus Git - ~andy/linux/blob - arch/parisc/kernel/signal32.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
[~andy/linux] / arch / parisc / kernel / signal32.c
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