]> git.karo-electronics.de Git - linux-beck.git/blob - arch/parisc/kernel/signal32.c
parisc: switch to generic sigaltstack
[linux-beck.git] / 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)
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 long
152 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
153                 struct pt_regs *regs)
154 {
155         long err = 0;
156         compat_uint_t compat_reg;
157         compat_uint_t compat_regt;
158         int regn;
159         
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);
173         }
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));
177                 
178         /* Better safe than sorry, pass __get_user two things of
179            the same size and let gcc do the upward conversion to 
180            64-bits */           
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);
188
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]);           
198                 
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);
204         
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]);           
212
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]);
220         
221         return err;
222 }
223
224 /*
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.
229  */
230 long
231 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
232                 struct pt_regs *regs, int in_syscall)            
233 {
234         compat_int_t flags = 0;
235         long err = 0;
236         compat_uint_t compat_reg;
237         compat_uint_t compat_regb;
238         int regn;
239         
240         if (on_sig_stack((unsigned long) sc))
241                 flags |= PARISC_SC_FLAG_ONSTACK;
242         
243         if (in_syscall) {
244                 
245                 DBG(1,"setup_sigcontext32: in_syscall\n");
246                 
247                 flags |= PARISC_SC_FLAG_IN_SYSCALL;
248                 /* Truncate gr31 */
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);
254                 
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);
259                 
260                 
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);
269                 
270                 /* Truncate sr3 */
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]);         
274                 
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]);         
279                 
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);
284                 
285         } else {
286                 
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);
295                 
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);
304                 
305                 
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);
314                 
315                 
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);
324
325                 /* Print out the IAOQ for debugging */          
326                 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
327                         regs->iaoq[0], regs->iaoq[1]);
328         }
329
330         err |= __put_user(flags, &sc->sc_flags);
331         
332         DBG(1,"setup_sigcontext32: Truncating general registers.\n");
333         
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]);
341
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);
345         }
346         
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));
353
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]);
362
363         return err;
364 }
365
366 int
367 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
368 {
369         compat_uptr_t addr;
370         int err;
371
372         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
373                 return -EFAULT;
374
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);
378
379         if (to->si_code < 0)
380                 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
381         else {
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);
387                       default:
388                         err |= __get_user(to->si_pid, &from->si_pid);
389                         err |= __get_user(to->si_uid, &from->si_uid);
390                         break;
391                       case __SI_FAULT >> 16:
392                         err |= __get_user(addr, &from->si_addr);
393                         to->si_addr = compat_ptr(addr);
394                         break;
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);
398                         break;
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);
404                         break;
405                 }
406         }
407         return err;
408 }
409
410 int
411 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
412 {
413         compat_uptr_t addr;
414         compat_int_t val;
415         int err;
416
417         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
418                 return -EFAULT;
419
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
426            at the same time.  */
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);
432         else {
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);
438                 default:
439                         err |= __put_user(from->si_pid, &to->si_pid);
440                         err |= __put_user(from->si_uid, &to->si_uid);
441                         break;
442                 case __SI_FAULT >> 16:
443                         addr = ptr_to_compat(from->si_addr);
444                         err |= __put_user(addr, &to->si_addr);
445                         break;
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);
449                         break;
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);
455                         break;
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);
462                         break;
463                 }
464         }
465         return err;
466 }
467
468 asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
469         struct compat_siginfo __user *uinfo)
470 {
471         siginfo_t info;
472
473         if (copy_siginfo_from_user32(&info, uinfo))
474                 return -EFAULT;
475
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)
479                 return -EPERM;
480         info.si_signo = sig;
481
482         /* POSIX.1b doesn't mention process groups.  */
483         return kill_proc_info(sig, &info, pid);
484 }
485