ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / s390 / kernel / compat_signal.c
1 /*
2  *  arch/s390/kernel/signal32.c
3  *
4  *  S390 version
5  *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
7  *               Gerhard Tonn (ton@de.ibm.com)                  
8  *
9  *  Copyright (C) 1991, 1992  Linus Torvalds
10  *
11  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
12  */
13
14 #include <linux/config.h>
15 #include <linux/compat.h>
16 #include <linux/sched.h>
17 #include <linux/mm.h>
18 #include <linux/smp.h>
19 #include <linux/smp_lock.h>
20 #include <linux/kernel.h>
21 #include <linux/signal.h>
22 #include <linux/errno.h>
23 #include <linux/wait.h>
24 #include <linux/ptrace.h>
25 #include <linux/unistd.h>
26 #include <linux/stddef.h>
27 #include <linux/tty.h>
28 #include <linux/personality.h>
29 #include <linux/binfmts.h>
30 #include <asm/ucontext.h>
31 #include <asm/uaccess.h>
32 #include <asm/lowcore.h>
33 #include "compat_linux.h"
34 #include "compat_ptrace.h"
35
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37
38 typedef struct 
39 {
40         __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
41         struct sigcontext32 sc;
42         _sigregs32 sregs;
43         __u8 retcode[S390_SYSCALL_SIZE];
44 } sigframe32;
45
46 typedef struct 
47 {
48         __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
49         __u8 retcode[S390_SYSCALL_SIZE];
50         struct siginfo32 info;
51         struct ucontext32 uc;
52 } rt_sigframe32;
53
54 asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
55
56 int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
57 {
58         int err;
59
60         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
61                 return -EFAULT;
62
63         /* If you change siginfo_t structure, please be sure
64            this code is fixed accordingly.
65            It should never copy any pad contained in the structure
66            to avoid security leaks, but must copy the generic
67            3 ints plus the relevant union member.  
68            This routine must convert siginfo from 64bit to 32bit as well
69            at the same time.  */
70         err = __put_user(from->si_signo, &to->si_signo);
71         err |= __put_user(from->si_errno, &to->si_errno);
72         err |= __put_user((short)from->si_code, &to->si_code);
73         if (from->si_code < 0)
74                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
75         else {
76                 switch (from->si_code >> 16) {
77                 case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
78                 case __SI_MESGQ >> 16:
79                         err |= __put_user(from->si_int, &to->si_int);
80                         /* fallthrough */
81                 case __SI_KILL >> 16:
82                         err |= __put_user(from->si_pid, &to->si_pid);
83                         err |= __put_user(from->si_uid, &to->si_uid);
84                         break;
85                 case __SI_CHLD >> 16:
86                         err |= __put_user(from->si_pid, &to->si_pid);
87                         err |= __put_user(from->si_uid, &to->si_uid);
88                         err |= __put_user(from->si_utime, &to->si_utime);
89                         err |= __put_user(from->si_stime, &to->si_stime);
90                         err |= __put_user(from->si_status, &to->si_status);
91                         break;
92                 case __SI_FAULT >> 16:
93                         err |= __put_user((unsigned long) from->si_addr,
94                                           &to->si_addr);
95                         break;
96                 case __SI_POLL >> 16:
97                 case __SI_TIMER >> 16:
98                         err |= __put_user(from->si_band, &to->si_band);
99                         err |= __put_user(from->si_fd, &to->si_fd);
100                         break;
101                 default:
102                         break;
103                 }
104         }
105         return err;
106 }
107
108 /*
109  * Atomically swap in the new signal mask, and wait for a signal.
110  */
111 asmlinkage int
112 sys32_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask)
113 {
114         sigset_t saveset;
115
116         mask &= _BLOCKABLE;
117         spin_lock_irq(&current->sighand->siglock);
118         saveset = current->blocked;
119         siginitset(&current->blocked, mask);
120         recalc_sigpending();
121         spin_unlock_irq(&current->sighand->siglock);
122         regs->gprs[2] = -EINTR;
123
124         while (1) {
125                 set_current_state(TASK_INTERRUPTIBLE);
126                 schedule();
127                 if (do_signal(regs, &saveset))
128                         return -EINTR;
129         }
130 }
131
132 asmlinkage int
133 sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize)
134 {
135         sigset_t saveset, newset;
136         compat_sigset_t set32;
137
138         /* XXX: Don't preclude handling different sized sigset_t's.  */
139         if (sigsetsize != sizeof(sigset_t))
140                 return -EINVAL;
141
142         if (copy_from_user(&set32, unewset, sizeof(set32)))
143                 return -EFAULT;
144         switch (_NSIG_WORDS) {
145         case 4: newset.sig[3] = set32.sig[6] + (((long)set32.sig[7]) << 32);
146         case 3: newset.sig[2] = set32.sig[4] + (((long)set32.sig[5]) << 32);
147         case 2: newset.sig[1] = set32.sig[2] + (((long)set32.sig[3]) << 32);
148         case 1: newset.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32);
149         }
150         sigdelsetmask(&newset, ~_BLOCKABLE);
151
152         spin_lock_irq(&current->sighand->siglock);
153         saveset = current->blocked;
154         current->blocked = newset;
155         recalc_sigpending();
156         spin_unlock_irq(&current->sighand->siglock);
157         regs->gprs[2] = -EINTR;
158
159         while (1) {
160                 set_current_state(TASK_INTERRUPTIBLE);
161                 schedule();
162                 if (do_signal(regs, &saveset))
163                         return -EINTR;
164         }
165 }                                                         
166
167 asmlinkage long
168 sys32_sigaction(int sig, const struct old_sigaction32 *act,
169                  struct old_sigaction32 *oact)
170 {
171         struct k_sigaction new_ka, old_ka;
172         int ret;
173
174         if (act) {
175                 compat_old_sigset_t mask;
176                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
177                     __get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler) ||
178                     __get_user((unsigned long)new_ka.sa.sa_restorer, &act->sa_restorer))
179                         return -EFAULT;
180                 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
181                 __get_user(mask, &act->sa_mask);
182                 siginitset(&new_ka.sa.sa_mask, mask);
183         }
184
185         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
186
187         if (!ret && oact) {
188                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
189                     __put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler) ||
190                     __put_user((unsigned long)old_ka.sa.sa_restorer, &oact->sa_restorer))
191                         return -EFAULT;
192                 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
193                 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
194         }
195
196         return ret;
197 }
198
199 int
200 do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact);
201
202 asmlinkage long 
203 sys32_rt_sigaction(int sig, const struct sigaction32 *act,
204            struct sigaction32 *oact,  size_t sigsetsize)
205 {
206         struct k_sigaction new_ka, old_ka;
207         int ret;
208         compat_sigset_t set32;
209
210         /* XXX: Don't preclude handling different sized sigset_t's.  */
211         if (sigsetsize != sizeof(compat_sigset_t))
212                 return -EINVAL;
213
214         if (act) {
215                 ret = get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler);
216                 ret |= __copy_from_user(&set32, &act->sa_mask,
217                                         sizeof(compat_sigset_t));
218                 switch (_NSIG_WORDS) {
219                 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
220                                 | (((long)set32.sig[7]) << 32);
221                 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
222                                 | (((long)set32.sig[5]) << 32);
223                 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
224                                 | (((long)set32.sig[3]) << 32);
225                 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
226                                 | (((long)set32.sig[1]) << 32);
227                 }
228                 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
229                 
230                 if (ret)
231                         return -EFAULT;
232         }
233
234         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
235
236         if (!ret && oact) {
237                 switch (_NSIG_WORDS) {
238                 case 4:
239                         set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
240                         set32.sig[6] = old_ka.sa.sa_mask.sig[3];
241                 case 3:
242                         set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
243                         set32.sig[4] = old_ka.sa.sa_mask.sig[2];
244                 case 2:
245                         set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
246                         set32.sig[2] = old_ka.sa.sa_mask.sig[1];
247                 case 1:
248                         set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
249                         set32.sig[0] = old_ka.sa.sa_mask.sig[0];
250                 }
251                 ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler);
252                 ret |= __copy_to_user(&oact->sa_mask, &set32,
253                                       sizeof(compat_sigset_t));
254                 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
255         }
256
257         return ret;
258 }
259
260 asmlinkage long
261 sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs)
262 {
263         stack_t kss, koss;
264         int ret, err = 0;
265         mm_segment_t old_fs = get_fs();
266
267         if (uss) {
268                 if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
269                         return -EFAULT;
270                 err |= __get_user((unsigned long) kss.ss_sp, &uss->ss_sp);
271                 err |= __get_user(kss.ss_size, &uss->ss_size);
272                 err |= __get_user(kss.ss_flags, &uss->ss_flags);
273                 if (err)
274                         return -EFAULT;
275         }
276
277         set_fs (KERNEL_DS);
278         ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, regs->gprs[15]);
279         set_fs (old_fs);
280
281         if (!ret && uoss) {
282                 if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
283                         return -EFAULT;
284                 err |= __put_user((unsigned long) koss.ss_sp, &uoss->ss_sp);
285                 err |= __put_user(koss.ss_size, &uoss->ss_size);
286                 err |= __put_user(koss.ss_flags, &uoss->ss_flags);
287                 if (err)
288                         return -EFAULT;
289         }
290         return ret;
291 }
292
293 static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
294 {
295         _s390_regs_common32 regs32;
296         int err, i;
297
298         regs32.psw.mask = PSW32_MASK_MERGE(PSW32_USER_BITS,
299                                            (__u32)(regs->psw.mask >> 32));
300         regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
301         for (i = 0; i < NUM_GPRS; i++)
302                 regs32.gprs[i] = (__u32) regs->gprs[i];
303         save_access_regs(current->thread.acrs);
304         memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
305         err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
306         if (err)
307                 return err;
308         save_fp_regs(&current->thread.fp_regs);
309         /* s390_fp_regs and _s390_fp_regs32 are the same ! */
310         return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
311                               sizeof(_s390_fp_regs32));
312 }
313
314 static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
315 {
316         _s390_regs_common32 regs32;
317         int err, i;
318
319         /* Alwys make any pending restarted system call return -EINTR */
320         current_thread_info()->restart_block.fn = do_no_restart_syscall;
321
322         err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
323         if (err)
324                 return err;
325         regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
326                                         (__u64)regs32.psw.mask << 32);
327         regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
328         for (i = 0; i < NUM_GPRS; i++)
329                 regs->gprs[i] = (__u64) regs32.gprs[i];
330         memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs));
331         restore_access_regs(current->thread.acrs);
332
333         err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
334                                sizeof(_s390_fp_regs32));
335         current->thread.fp_regs.fpc &= FPC_VALID_MASK;
336         if (err)
337                 return err;
338
339         restore_fp_regs(&current->thread.fp_regs);
340         regs->trap = -1;        /* disable syscall checks */
341         return 0;
342 }
343
344 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
345 {
346         sigframe32 *frame = (sigframe32 *)regs->gprs[15];
347         sigset_t set;
348
349         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
350                 goto badframe;
351         if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
352                 goto badframe;
353
354         sigdelsetmask(&set, ~_BLOCKABLE);
355         spin_lock_irq(&current->sighand->siglock);
356         current->blocked = set;
357         recalc_sigpending();
358         spin_unlock_irq(&current->sighand->siglock);
359
360         if (restore_sigregs32(regs, &frame->sregs))
361                 goto badframe;
362
363         return regs->gprs[2];
364
365 badframe:
366         force_sig(SIGSEGV, current);
367         return 0;
368 }       
369
370 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
371 {
372         rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15];
373         sigset_t set;
374         stack_t st;
375         __u32 ss_sp;
376         int err;
377         mm_segment_t old_fs = get_fs();
378
379         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
380                 goto badframe;
381         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
382                 goto badframe;
383
384         sigdelsetmask(&set, ~_BLOCKABLE);
385         spin_lock_irq(&current->sighand->siglock);
386         current->blocked = set;
387         recalc_sigpending();
388         spin_unlock_irq(&current->sighand->siglock);
389
390         if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
391                 goto badframe;
392
393         err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
394         st.ss_sp = (void *) A((unsigned long)ss_sp);
395         err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
396         err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
397         if (err)
398                 goto badframe; 
399
400         /* It is more difficult to avoid calling this function than to
401            call it and ignore errors.  */
402         set_fs (KERNEL_DS);   
403         do_sigaltstack(&st, NULL, regs->gprs[15]);
404         set_fs (old_fs);
405
406         return regs->gprs[2];
407
408 badframe:
409         force_sig(SIGSEGV, current);
410         return 0;
411 }       
412
413 /*
414  * Set up a signal frame.
415  */
416
417
418 /*
419  * Determine which stack to use..
420  */
421 static inline void *
422 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
423 {
424         unsigned long sp;
425
426         /* Default to using normal stack */
427         sp = (unsigned long) A(regs->gprs[15]);
428
429         /* This is the X/Open sanctioned signal stack switching.  */
430         if (ka->sa.sa_flags & SA_ONSTACK) {
431                 if (! on_sig_stack(sp))
432                         sp = current->sas_ss_sp + current->sas_ss_size;
433         }
434
435         /* This is the legacy signal stack switching. */
436         else if (!user_mode(regs) &&
437                  !(ka->sa.sa_flags & SA_RESTORER) &&
438                  ka->sa.sa_restorer) {
439                 sp = (unsigned long) ka->sa.sa_restorer;
440         }
441
442         return (void *)((sp - frame_size) & -8ul);
443 }
444
445 static inline int map_signal(int sig)
446 {
447         if (current_thread_info()->exec_domain
448             && current_thread_info()->exec_domain->signal_invmap
449             && sig < 32)
450                 return current_thread_info()->exec_domain->signal_invmap[sig];
451         else
452                 return sig;
453 }
454
455 static void setup_frame32(int sig, struct k_sigaction *ka,
456                         sigset_t *set, struct pt_regs * regs)
457 {
458         sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32));
459         if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
460                 goto give_sigsegv;
461
462         if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
463                 goto give_sigsegv;
464
465         if (save_sigregs32(regs, &frame->sregs))
466                 goto give_sigsegv;
467         if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
468                 goto give_sigsegv;
469
470         /* Set up to return from userspace.  If provided, use a stub
471            already in userspace.  */
472         if (ka->sa.sa_flags & SA_RESTORER) {
473                 regs->gprs[14] = (__u64) ka->sa.sa_restorer;
474         } else {
475                 regs->gprs[14] = (__u64) frame->retcode;
476                 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
477                                (u16 *)(frame->retcode)))
478                         goto give_sigsegv;
479         }
480
481         /* Set up backchain. */
482         if (__put_user(regs->gprs[15], (unsigned int *) frame))
483                 goto give_sigsegv;
484
485         /* Set up registers for signal handler */
486         regs->gprs[15] = (__u64) frame;
487         regs->psw.addr = (__u64) ka->sa.sa_handler;
488
489         regs->gprs[2] = map_signal(sig);
490         regs->gprs[3] = (__u64) &frame->sc;
491
492         /* We forgot to include these in the sigcontext.
493            To avoid breaking binary compatibility, they are passed as args. */
494         regs->gprs[4] = current->thread.trap_no;
495         regs->gprs[5] = current->thread.prot_addr;
496         return;
497
498 give_sigsegv:
499         if (sig == SIGSEGV)
500                 ka->sa.sa_handler = SIG_DFL;
501         force_sig(SIGSEGV, current);
502 }
503
504 static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
505                            sigset_t *set, struct pt_regs * regs)
506 {
507         int err = 0;
508         rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
509         if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
510                 goto give_sigsegv;
511
512         if (copy_siginfo_to_user32(&frame->info, info))
513                 goto give_sigsegv;
514
515         /* Create the ucontext.  */
516         err |= __put_user(0, &frame->uc.uc_flags);
517         err |= __put_user(0, &frame->uc.uc_link);
518         err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
519         err |= __put_user(sas_ss_flags(regs->gprs[15]),
520                           &frame->uc.uc_stack.ss_flags);
521         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
522         err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
523         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
524         if (err)
525                 goto give_sigsegv;
526
527         /* Set up to return from userspace.  If provided, use a stub
528            already in userspace.  */
529         if (ka->sa.sa_flags & SA_RESTORER) {
530                 regs->gprs[14] = (__u64) ka->sa.sa_restorer;
531         } else {
532                 regs->gprs[14] = (__u64) frame->retcode;
533                 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
534                                   (u16 *)(frame->retcode));
535         }
536
537         /* Set up backchain. */
538         if (__put_user(regs->gprs[15], (unsigned int *) frame))
539                 goto give_sigsegv;
540
541         /* Set up registers for signal handler */
542         regs->gprs[15] = (__u64) frame;
543         regs->psw.addr = (__u64) ka->sa.sa_handler;
544
545         regs->gprs[2] = map_signal(sig);
546         regs->gprs[3] = (__u64) &frame->info;
547         regs->gprs[4] = (__u64) &frame->uc;
548         return;
549
550 give_sigsegv:
551         if (sig == SIGSEGV)
552                 ka->sa.sa_handler = SIG_DFL;
553         force_sig(SIGSEGV, current);
554 }
555
556 /*
557  * OK, we're invoking a handler
558  */     
559
560 void
561 handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
562         struct pt_regs * regs)
563 {
564         struct k_sigaction *ka = &current->sighand->action[sig-1];
565
566         /* Set up the stack frame */
567         if (ka->sa.sa_flags & SA_SIGINFO)
568                 setup_rt_frame32(sig, ka, info, oldset, regs);
569         else
570                 setup_frame32(sig, ka, oldset, regs);
571
572         if (ka->sa.sa_flags & SA_ONESHOT)
573                 ka->sa.sa_handler = SIG_DFL;
574
575         if (!(ka->sa.sa_flags & SA_NODEFER)) {
576                 spin_lock_irq(&current->sighand->siglock);
577                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
578                 sigaddset(&current->blocked,sig);
579                 recalc_sigpending();
580                 spin_unlock_irq(&current->sighand->siglock);
581         }
582 }
583