x86 signals: lift flags diddling code
[deliverable/linux.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 }
This page took 0.064179 seconds and 5 git commands to generate.