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