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