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