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