]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/ia32/ia32_signal.c
x86 signals: lift flags diddling code
[linux-2.6-omap-h63xx.git] / arch / x86 / ia32 / ia32_signal.c
1 /*
2  *  linux/arch/x86_64/ia32/ia32_signal.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *
6  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7  *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
8  *  2000-12-*   x86-64 compatibility mode signal handling by Andi Kleen
9  */
10
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/compat.h>
23 #include <linux/binfmts.h>
24 #include <asm/ucontext.h>
25 #include <asm/uaccess.h>
26 #include <asm/i387.h>
27 #include <asm/ia32.h>
28 #include <asm/ptrace.h>
29 #include <asm/ia32_unistd.h>
30 #include <asm/user32.h>
31 #include <asm/sigcontext32.h>
32 #include <asm/proto.h>
33 #include <asm/vdso.h>
34
35 #define DEBUG_SIG 0
36
37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38
39 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
40 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
41
42 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
43 {
44         int err;
45
46         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
47                 return -EFAULT;
48
49         /* If you change siginfo_t structure, please make sure that
50            this code is fixed accordingly.
51            It should never copy any pad contained in the structure
52            to avoid security leaks, but must copy the generic
53            3 ints plus the relevant union member.  */
54         err = __put_user(from->si_signo, &to->si_signo);
55         err |= __put_user(from->si_errno, &to->si_errno);
56         err |= __put_user((short)from->si_code, &to->si_code);
57
58         if (from->si_code < 0) {
59                 err |= __put_user(from->si_pid, &to->si_pid);
60                 err |= __put_user(from->si_uid, &to->si_uid);
61                 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
62         } else {
63                 /*
64                  * First 32bits of unions are always present:
65                  * si_pid === si_band === si_tid === si_addr(LS half)
66                  */
67                 err |= __put_user(from->_sifields._pad[0],
68                                   &to->_sifields._pad[0]);
69                 switch (from->si_code >> 16) {
70                 case __SI_FAULT >> 16:
71                         break;
72                 case __SI_CHLD >> 16:
73                         err |= __put_user(from->si_utime, &to->si_utime);
74                         err |= __put_user(from->si_stime, &to->si_stime);
75                         err |= __put_user(from->si_status, &to->si_status);
76                         /* FALL THROUGH */
77                 default:
78                 case __SI_KILL >> 16:
79                         err |= __put_user(from->si_uid, &to->si_uid);
80                         break;
81                 case __SI_POLL >> 16:
82                         err |= __put_user(from->si_fd, &to->si_fd);
83                         break;
84                 case __SI_TIMER >> 16:
85                         err |= __put_user(from->si_overrun, &to->si_overrun);
86                         err |= __put_user(ptr_to_compat(from->si_ptr),
87                                           &to->si_ptr);
88                         break;
89                          /* This is not generated by the kernel as of now.  */
90                 case __SI_RT >> 16:
91                 case __SI_MESGQ >> 16:
92                         err |= __put_user(from->si_uid, &to->si_uid);
93                         err |= __put_user(from->si_int, &to->si_int);
94                         break;
95                 }
96         }
97         return err;
98 }
99
100 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
101 {
102         int err;
103         u32 ptr32;
104
105         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
106                 return -EFAULT;
107
108         err = __get_user(to->si_signo, &from->si_signo);
109         err |= __get_user(to->si_errno, &from->si_errno);
110         err |= __get_user(to->si_code, &from->si_code);
111
112         err |= __get_user(to->si_pid, &from->si_pid);
113         err |= __get_user(to->si_uid, &from->si_uid);
114         err |= __get_user(ptr32, &from->si_ptr);
115         to->si_ptr = compat_ptr(ptr32);
116
117         return err;
118 }
119
120 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
121 {
122         mask &= _BLOCKABLE;
123         spin_lock_irq(&current->sighand->siglock);
124         current->saved_sigmask = current->blocked;
125         siginitset(&current->blocked, mask);
126         recalc_sigpending();
127         spin_unlock_irq(&current->sighand->siglock);
128
129         current->state = TASK_INTERRUPTIBLE;
130         schedule();
131         set_thread_flag(TIF_RESTORE_SIGMASK);
132         return -ERESTARTNOHAND;
133 }
134
135 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
136                                   stack_ia32_t __user *uoss_ptr,
137                                   struct pt_regs *regs)
138 {
139         stack_t uss, uoss;
140         int ret;
141         mm_segment_t seg;
142
143         if (uss_ptr) {
144                 u32 ptr;
145
146                 memset(&uss, 0, sizeof(stack_t));
147                 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
148                             __get_user(ptr, &uss_ptr->ss_sp) ||
149                             __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
150                             __get_user(uss.ss_size, &uss_ptr->ss_size))
151                         return -EFAULT;
152                 uss.ss_sp = compat_ptr(ptr);
153         }
154         seg = get_fs();
155         set_fs(KERNEL_DS);
156         ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
157         set_fs(seg);
158         if (ret >= 0 && uoss_ptr)  {
159                 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
160                     __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
161                     __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
162                     __put_user(uoss.ss_size, &uoss_ptr->ss_size))
163                         ret = -EFAULT;
164         }
165         return ret;
166 }
167
168 /*
169  * Do a signal return; undo the signal stack.
170  */
171
172 struct sigframe
173 {
174         u32 pretcode;
175         int sig;
176         struct sigcontext_ia32 sc;
177         struct _fpstate_ia32 fpstate;
178         unsigned int extramask[_COMPAT_NSIG_WORDS-1];
179         char retcode[8];
180 };
181
182 struct rt_sigframe
183 {
184         u32 pretcode;
185         int sig;
186         u32 pinfo;
187         u32 puc;
188         compat_siginfo_t info;
189         struct ucontext_ia32 uc;
190         struct _fpstate_ia32 fpstate;
191         char retcode[8];
192 };
193
194 #define COPY(x)         {               \
195         unsigned int reg;               \
196         err |= __get_user(reg, &sc->x); \
197         regs->x = reg;                  \
198 }
199
200 #define RELOAD_SEG(seg,mask)                                            \
201         { unsigned int cur;                                             \
202           unsigned short pre;                                           \
203           err |= __get_user(pre, &sc->seg);                             \
204           asm volatile("movl %%" #seg ",%0" : "=r" (cur));              \
205           pre |= mask;                                                  \
206           if (pre != cur) loadsegment(seg, pre); }
207
208 static int ia32_restore_sigcontext(struct pt_regs *regs,
209                                    struct sigcontext_ia32 __user *sc,
210                                    unsigned int *peax)
211 {
212         unsigned int tmpflags, gs, oldgs, err = 0;
213         struct _fpstate_ia32 __user *buf;
214         u32 tmp;
215
216         /* Always make any pending restarted system calls return -EINTR */
217         current_thread_info()->restart_block.fn = do_no_restart_syscall;
218
219 #if DEBUG_SIG
220         printk(KERN_DEBUG "SIG restore_sigcontext: "
221                "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
222                sc, sc->err, sc->ip, sc->cs, sc->flags);
223 #endif
224
225         /*
226          * Reload fs and gs if they have changed in the signal
227          * handler.  This does not handle long fs/gs base changes in
228          * the handler, but does not clobber them at least in the
229          * normal case.
230          */
231         err |= __get_user(gs, &sc->gs);
232         gs |= 3;
233         asm("movl %%gs,%0" : "=r" (oldgs));
234         if (gs != oldgs)
235                 load_gs_index(gs);
236
237         RELOAD_SEG(fs, 3);
238         RELOAD_SEG(ds, 3);
239         RELOAD_SEG(es, 3);
240
241         COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
242         COPY(dx); COPY(cx); COPY(ip);
243         /* Don't touch extended registers */
244
245         err |= __get_user(regs->cs, &sc->cs);
246         regs->cs |= 3;
247         err |= __get_user(regs->ss, &sc->ss);
248         regs->ss |= 3;
249
250         err |= __get_user(tmpflags, &sc->flags);
251         regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
252         /* disable syscall checks */
253         regs->orig_ax = -1;
254
255         err |= __get_user(tmp, &sc->fpstate);
256         buf = compat_ptr(tmp);
257         if (buf) {
258                 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
259                         goto badframe;
260                 err |= restore_i387_ia32(buf);
261         } else {
262                 struct task_struct *me = current;
263
264                 if (used_math()) {
265                         clear_fpu(me);
266                         clear_used_math();
267                 }
268         }
269
270         err |= __get_user(tmp, &sc->ax);
271         *peax = tmp;
272
273         return err;
274
275 badframe:
276         return 1;
277 }
278
279 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
280 {
281         struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
282         sigset_t set;
283         unsigned int ax;
284
285         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
286                 goto badframe;
287         if (__get_user(set.sig[0], &frame->sc.oldmask)
288             || (_COMPAT_NSIG_WORDS > 1
289                 && __copy_from_user((((char *) &set.sig) + 4),
290                                     &frame->extramask,
291                                     sizeof(frame->extramask))))
292                 goto badframe;
293
294         sigdelsetmask(&set, ~_BLOCKABLE);
295         spin_lock_irq(&current->sighand->siglock);
296         current->blocked = set;
297         recalc_sigpending();
298         spin_unlock_irq(&current->sighand->siglock);
299
300         if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
301                 goto badframe;
302         return ax;
303
304 badframe:
305         signal_fault(regs, frame, "32bit sigreturn");
306         return 0;
307 }
308
309 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
310 {
311         struct rt_sigframe __user *frame;
312         sigset_t set;
313         unsigned int ax;
314         struct pt_regs tregs;
315
316         frame = (struct rt_sigframe __user *)(regs->sp - 4);
317
318         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
319                 goto badframe;
320         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
321                 goto badframe;
322
323         sigdelsetmask(&set, ~_BLOCKABLE);
324         spin_lock_irq(&current->sighand->siglock);
325         current->blocked = set;
326         recalc_sigpending();
327         spin_unlock_irq(&current->sighand->siglock);
328
329         if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
330                 goto badframe;
331
332         tregs = *regs;
333         if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
334                 goto badframe;
335
336         return ax;
337
338 badframe:
339         signal_fault(regs, frame, "32bit rt sigreturn");
340         return 0;
341 }
342
343 /*
344  * Set up a signal frame.
345  */
346
347 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
348                                  struct _fpstate_ia32 __user *fpstate,
349                                  struct pt_regs *regs, unsigned int mask)
350 {
351         int tmp, err = 0;
352
353         tmp = 0;
354         __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
355         err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
356         __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
357         err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
358         __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
359         err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
360         __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
361         err |= __put_user(tmp, (unsigned int __user *)&sc->es);
362
363         err |= __put_user((u32)regs->di, &sc->di);
364         err |= __put_user((u32)regs->si, &sc->si);
365         err |= __put_user((u32)regs->bp, &sc->bp);
366         err |= __put_user((u32)regs->sp, &sc->sp);
367         err |= __put_user((u32)regs->bx, &sc->bx);
368         err |= __put_user((u32)regs->dx, &sc->dx);
369         err |= __put_user((u32)regs->cx, &sc->cx);
370         err |= __put_user((u32)regs->ax, &sc->ax);
371         err |= __put_user((u32)regs->cs, &sc->cs);
372         err |= __put_user((u32)regs->ss, &sc->ss);
373         err |= __put_user(current->thread.trap_no, &sc->trapno);
374         err |= __put_user(current->thread.error_code, &sc->err);
375         err |= __put_user((u32)regs->ip, &sc->ip);
376         err |= __put_user((u32)regs->flags, &sc->flags);
377         err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
378
379         tmp = save_i387_ia32(fpstate);
380         if (tmp < 0)
381                 err = -EFAULT;
382         else {
383                 clear_used_math();
384                 stts();
385                 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
386                                         &sc->fpstate);
387         }
388
389         /* non-iBCS2 extensions.. */
390         err |= __put_user(mask, &sc->oldmask);
391         err |= __put_user(current->thread.cr2, &sc->cr2);
392
393         return err;
394 }
395
396 /*
397  * Determine which stack to use..
398  */
399 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
400                                  size_t frame_size)
401 {
402         unsigned long sp;
403
404         /* Default to using normal stack */
405         sp = regs->sp;
406
407         /* This is the X/Open sanctioned signal stack switching.  */
408         if (ka->sa.sa_flags & SA_ONSTACK) {
409                 if (sas_ss_flags(sp) == 0)
410                         sp = current->sas_ss_sp + current->sas_ss_size;
411         }
412
413         /* This is the legacy signal stack switching. */
414         else if ((regs->ss & 0xffff) != __USER_DS &&
415                 !(ka->sa.sa_flags & SA_RESTORER) &&
416                  ka->sa.sa_restorer)
417                 sp = (unsigned long) ka->sa.sa_restorer;
418
419         sp -= frame_size;
420         /* Align the stack pointer according to the i386 ABI,
421          * i.e. so that on function entry ((sp + 4) & 15) == 0. */
422         sp = ((sp + 4) & -16ul) - 4;
423         return (void __user *) sp;
424 }
425
426 int ia32_setup_frame(int sig, struct k_sigaction *ka,
427                      compat_sigset_t *set, struct pt_regs *regs)
428 {
429         struct sigframe __user *frame;
430         void __user *restorer;
431         int err = 0;
432
433         /* copy_to_user optimizes that into a single 8 byte store */
434         static const struct {
435                 u16 poplmovl;
436                 u32 val;
437                 u16 int80;
438                 u16 pad;
439         } __attribute__((packed)) code = {
440                 0xb858,          /* popl %eax ; movl $...,%eax */
441                 __NR_ia32_sigreturn,
442                 0x80cd,         /* int $0x80 */
443                 0,
444         };
445
446         frame = get_sigframe(ka, regs, sizeof(*frame));
447
448         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
449                 goto give_sigsegv;
450
451         err |= __put_user(sig, &frame->sig);
452         if (err)
453                 goto give_sigsegv;
454
455         err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs,
456                                         set->sig[0]);
457         if (err)
458                 goto give_sigsegv;
459
460         if (_COMPAT_NSIG_WORDS > 1) {
461                 err |= __copy_to_user(frame->extramask, &set->sig[1],
462                                       sizeof(frame->extramask));
463                 if (err)
464                         goto give_sigsegv;
465         }
466
467         if (ka->sa.sa_flags & SA_RESTORER) {
468                 restorer = ka->sa.sa_restorer;
469         } else {
470                 /* Return stub is in 32bit vsyscall page */
471                 if (current->mm->context.vdso)
472                         restorer = VDSO32_SYMBOL(current->mm->context.vdso,
473                                                  sigreturn);
474                 else
475                         restorer = &frame->retcode;
476         }
477         err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
478
479         /*
480          * These are actually not used anymore, but left because some
481          * gdb versions depend on them as a marker.
482          */
483         err |= __copy_to_user(frame->retcode, &code, 8);
484         if (err)
485                 goto give_sigsegv;
486
487         /* Set up registers for signal handler */
488         regs->sp = (unsigned long) frame;
489         regs->ip = (unsigned long) ka->sa.sa_handler;
490
491         /* Make -mregparm=3 work */
492         regs->ax = sig;
493         regs->dx = 0;
494         regs->cx = 0;
495
496         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
497         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
498
499         regs->cs = __USER32_CS;
500         regs->ss = __USER32_DS;
501
502         set_fs(USER_DS);
503
504 #if DEBUG_SIG
505         printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
506                current->comm, current->pid, frame, regs->ip, frame->pretcode);
507 #endif
508
509         return 0;
510
511 give_sigsegv:
512         force_sigsegv(sig, current);
513         return -EFAULT;
514 }
515
516 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
517                         compat_sigset_t *set, struct pt_regs *regs)
518 {
519         struct rt_sigframe __user *frame;
520         struct exec_domain *ed = current_thread_info()->exec_domain;
521         void __user *restorer;
522         int err = 0;
523
524         /* __copy_to_user optimizes that into a single 8 byte store */
525         static const struct {
526                 u8 movl;
527                 u32 val;
528                 u16 int80;
529                 u16 pad;
530                 u8  pad2;
531         } __attribute__((packed)) code = {
532                 0xb8,
533                 __NR_ia32_rt_sigreturn,
534                 0x80cd,
535                 0,
536         };
537
538         frame = get_sigframe(ka, regs, sizeof(*frame));
539
540         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
541                 goto give_sigsegv;
542
543         err |= __put_user((ed && ed->signal_invmap && sig < 32
544                            ? ed->signal_invmap[sig] : sig), &frame->sig);
545         err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
546         err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
547         err |= copy_siginfo_to_user32(&frame->info, info);
548         if (err)
549                 goto give_sigsegv;
550
551         /* Create the ucontext.  */
552         err |= __put_user(0, &frame->uc.uc_flags);
553         err |= __put_user(0, &frame->uc.uc_link);
554         err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
555         err |= __put_user(sas_ss_flags(regs->sp),
556                           &frame->uc.uc_stack.ss_flags);
557         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
558         err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
559                                      regs, set->sig[0]);
560         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
561         if (err)
562                 goto give_sigsegv;
563
564         if (ka->sa.sa_flags & SA_RESTORER)
565                 restorer = ka->sa.sa_restorer;
566         else
567                 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
568                                          rt_sigreturn);
569         err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
570
571         /*
572          * Not actually used anymore, but left because some gdb
573          * versions need it.
574          */
575         err |= __copy_to_user(frame->retcode, &code, 8);
576         if (err)
577                 goto give_sigsegv;
578
579         /* Set up registers for signal handler */
580         regs->sp = (unsigned long) frame;
581         regs->ip = (unsigned long) ka->sa.sa_handler;
582
583         /* Make -mregparm=3 work */
584         regs->ax = sig;
585         regs->dx = (unsigned long) &frame->info;
586         regs->cx = (unsigned long) &frame->uc;
587
588         /* Make -mregparm=3 work */
589         regs->ax = sig;
590         regs->dx = (unsigned long) &frame->info;
591         regs->cx = (unsigned long) &frame->uc;
592
593         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
594         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
595
596         regs->cs = __USER32_CS;
597         regs->ss = __USER32_DS;
598
599         set_fs(USER_DS);
600
601 #if DEBUG_SIG
602         printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
603                current->comm, current->pid, frame, regs->ip, frame->pretcode);
604 #endif
605
606         return 0;
607
608 give_sigsegv:
609         force_sigsegv(sig, current);
610         return -EFAULT;
611 }