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