]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - arch/x86/ia32/ia32_signal.c
sparc: convert to ksignal
[mirror_ubuntu-focal-kernel.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
1da177e4
LT
132/*
133 * Do a signal return; undo the signal stack.
134 */
a967bb3f
HS
135#define loadsegment_gs(v) load_gs_index(v)
136#define loadsegment_fs(v) loadsegment(fs, v)
137#define loadsegment_ds(v) loadsegment(ds, v)
138#define loadsegment_es(v) loadsegment(es, v)
139
140#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
141#define set_user_seg(seg, v) loadsegment_##seg(v)
142
b78a5b52 143#define COPY(x) { \
3b4b7570 144 get_user_ex(regs->x, &sc->x); \
1da177e4 145}
1da177e4 146
8801ead4
HS
147#define GET_SEG(seg) ({ \
148 unsigned short tmp; \
149 get_user_ex(tmp, &sc->seg); \
150 tmp; \
151})
152
153#define COPY_SEG_CPL3(seg) do { \
154 regs->seg = GET_SEG(seg) | 3; \
155} while (0)
1da177e4 156
8c6e5ce0 157#define RELOAD_SEG(seg) { \
a967bb3f
HS
158 unsigned int pre = GET_SEG(seg); \
159 unsigned int cur = get_user_seg(seg); \
8c6e5ce0
HS
160 pre |= 3; \
161 if (pre != cur) \
a967bb3f 162 set_user_seg(seg, pre); \
8c6e5ce0 163}
99b9cdf7
TG
164
165static int ia32_restore_sigcontext(struct pt_regs *regs,
166 struct sigcontext_ia32 __user *sc,
047ce935 167 unsigned int *pax)
99b9cdf7 168{
a967bb3f 169 unsigned int tmpflags, err = 0;
ab513701 170 void __user *buf;
99b9cdf7
TG
171 u32 tmp;
172
173 /* Always make any pending restarted system calls return -EINTR */
174 current_thread_info()->restart_block.fn = do_no_restart_syscall;
175
3b4b7570
HS
176 get_user_try {
177 /*
178 * Reload fs and gs if they have changed in the signal
179 * handler. This does not handle long fs/gs base changes in
180 * the handler, but does not clobber them at least in the
181 * normal case.
182 */
a967bb3f 183 RELOAD_SEG(gs);
3b4b7570
HS
184 RELOAD_SEG(fs);
185 RELOAD_SEG(ds);
186 RELOAD_SEG(es);
187
188 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
189 COPY(dx); COPY(cx); COPY(ip);
190 /* Don't touch extended registers */
191
192 COPY_SEG_CPL3(cs);
193 COPY_SEG_CPL3(ss);
194
195 get_user_ex(tmpflags, &sc->flags);
196 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
197 /* disable syscall checks */
198 regs->orig_ax = -1;
199
200 get_user_ex(tmp, &sc->fpstate);
201 buf = compat_ptr(tmp);
3b4b7570
HS
202
203 get_user_ex(*pax, &sc->ax);
204 } get_user_catch(err);
205
49b8c695 206 err |= restore_xstate_sig(buf, 1);
5e88353d 207
1da177e4 208 return err;
1da177e4
LT
209}
210
3fe26fa3 211asmlinkage long sys32_sigreturn(void)
1da177e4 212{
3fe26fa3 213 struct pt_regs *regs = current_pt_regs();
3b0d29ee 214 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
1da177e4 215 sigset_t set;
65ea5b03 216 unsigned int ax;
1da177e4
LT
217
218 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
219 goto badframe;
220 if (__get_user(set.sig[0], &frame->sc.oldmask)
221 || (_COMPAT_NSIG_WORDS > 1
99b9cdf7
TG
222 && __copy_from_user((((char *) &set.sig) + 4),
223 &frame->extramask,
1da177e4
LT
224 sizeof(frame->extramask))))
225 goto badframe;
226
905f29e2 227 set_current_blocked(&set);
99b9cdf7 228
65ea5b03 229 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
1da177e4 230 goto badframe;
65ea5b03 231 return ax;
1da177e4
LT
232
233badframe:
234 signal_fault(regs, frame, "32bit sigreturn");
235 return 0;
99b9cdf7 236}
1da177e4 237
3fe26fa3 238asmlinkage long sys32_rt_sigreturn(void)
1da177e4 239{
3fe26fa3 240 struct pt_regs *regs = current_pt_regs();
3b0d29ee 241 struct rt_sigframe_ia32 __user *frame;
1da177e4 242 sigset_t set;
65ea5b03 243 unsigned int ax;
1da177e4 244
3b0d29ee 245 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
1da177e4
LT
246
247 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
248 goto badframe;
249 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
250 goto badframe;
251
905f29e2 252 set_current_blocked(&set);
99b9cdf7 253
65ea5b03 254 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
1da177e4
LT
255 goto badframe;
256
90268439 257 if (compat_restore_altstack(&frame->uc.uc_stack))
1da177e4
LT
258 goto badframe;
259
65ea5b03 260 return ax;
1da177e4
LT
261
262badframe:
99b9cdf7 263 signal_fault(regs, frame, "32bit rt sigreturn");
1da177e4 264 return 0;
99b9cdf7 265}
1da177e4
LT
266
267/*
268 * Set up a signal frame.
269 */
270
99b9cdf7 271static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
ab513701 272 void __user *fpstate,
99b9cdf7 273 struct pt_regs *regs, unsigned int mask)
1da177e4 274{
a967bb3f 275 int err = 0;
1da177e4 276
3b4b7570 277 put_user_try {
a967bb3f
HS
278 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
279 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
280 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
281 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
3b4b7570
HS
282
283 put_user_ex(regs->di, &sc->di);
284 put_user_ex(regs->si, &sc->si);
285 put_user_ex(regs->bp, &sc->bp);
286 put_user_ex(regs->sp, &sc->sp);
287 put_user_ex(regs->bx, &sc->bx);
288 put_user_ex(regs->dx, &sc->dx);
289 put_user_ex(regs->cx, &sc->cx);
290 put_user_ex(regs->ax, &sc->ax);
51e7dc70 291 put_user_ex(current->thread.trap_nr, &sc->trapno);
3b4b7570
HS
292 put_user_ex(current->thread.error_code, &sc->err);
293 put_user_ex(regs->ip, &sc->ip);
294 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
295 put_user_ex(regs->flags, &sc->flags);
296 put_user_ex(regs->sp, &sc->sp_at_signal);
297 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
298
299 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
300
301 /* non-iBCS2 extensions.. */
302 put_user_ex(mask, &sc->oldmask);
303 put_user_ex(current->thread.cr2, &sc->cr2);
304 } put_user_catch(err);
1da177e4
LT
305
306 return err;
307}
308
309/*
310 * Determine which stack to use..
311 */
99b9cdf7 312static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
3c1c7f10 313 size_t frame_size,
0ff8fef4 314 void __user **fpstate)
1da177e4 315{
65ea5b03 316 unsigned long sp;
1da177e4
LT
317
318 /* Default to using normal stack */
65ea5b03 319 sp = regs->sp;
1da177e4
LT
320
321 /* This is the X/Open sanctioned signal stack switching. */
322 if (ka->sa.sa_flags & SA_ONSTACK) {
65ea5b03
PA
323 if (sas_ss_flags(sp) == 0)
324 sp = current->sas_ss_sp + current->sas_ss_size;
1da177e4
LT
325 }
326
327 /* This is the legacy signal stack switching. */
8bee3f0a 328 else if ((regs->ss & 0xffff) != __USER32_DS &&
1da177e4 329 !(ka->sa.sa_flags & SA_RESTORER) &&
99b9cdf7 330 ka->sa.sa_restorer)
65ea5b03 331 sp = (unsigned long) ka->sa.sa_restorer;
1da177e4 332
3c1c7f10 333 if (used_math()) {
72a671ce
SS
334 unsigned long fx_aligned, math_size;
335
336 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
0ff8fef4 337 *fpstate = (struct _fpstate_ia32 __user *) sp;
72a671ce
SS
338 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
339 math_size) < 0)
99ea1b93 340 return (void __user *) -1L;
3c1c7f10
SS
341 }
342
65ea5b03 343 sp -= frame_size;
d347f372
MO
344 /* Align the stack pointer according to the i386 ABI,
345 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
65ea5b03
PA
346 sp = ((sp + 4) & -16ul) - 4;
347 return (void __user *) sp;
1da177e4
LT
348}
349
0928d6ef 350int ia32_setup_frame(int sig, struct k_sigaction *ka,
99b9cdf7 351 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 352{
3b0d29ee 353 struct sigframe_ia32 __user *frame;
99b9cdf7 354 void __user *restorer;
1da177e4 355 int err = 0;
ab513701 356 void __user *fpstate = NULL;
1da177e4 357
99b9cdf7
TG
358 /* copy_to_user optimizes that into a single 8 byte store */
359 static const struct {
360 u16 poplmovl;
361 u32 val;
362 u16 int80;
99b9cdf7
TG
363 } __attribute__((packed)) code = {
364 0xb858, /* popl %eax ; movl $...,%eax */
365 __NR_ia32_sigreturn,
366 0x80cd, /* int $0x80 */
99b9cdf7
TG
367 };
368
3c1c7f10 369 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
370
371 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 372 return -EFAULT;
1da177e4 373
2ba48e16 374 if (__put_user(sig, &frame->sig))
3d0aedd9 375 return -EFAULT;
1da177e4 376
2ba48e16 377 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
3d0aedd9 378 return -EFAULT;
1da177e4
LT
379
380 if (_COMPAT_NSIG_WORDS > 1) {
2ba48e16
HS
381 if (__copy_to_user(frame->extramask, &set->sig[1],
382 sizeof(frame->extramask)))
3d0aedd9 383 return -EFAULT;
1da177e4 384 }
1da177e4 385
af65d648 386 if (ka->sa.sa_flags & SA_RESTORER) {
99b9cdf7 387 restorer = ka->sa.sa_restorer;
af65d648
RM
388 } else {
389 /* Return stub is in 32bit vsyscall page */
1a3e4ca4 390 if (current->mm->context.vdso)
af65d648
RM
391 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
392 sigreturn);
393 else
ade1af77 394 restorer = &frame->retcode;
af65d648 395 }
99b9cdf7 396
3b4b7570
HS
397 put_user_try {
398 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
399
400 /*
401 * These are actually not used anymore, but left because some
402 * gdb versions depend on them as a marker.
403 */
0ff8fef4 404 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570
HS
405 } put_user_catch(err);
406
1da177e4 407 if (err)
3d0aedd9 408 return -EFAULT;
1da177e4
LT
409
410 /* Set up registers for signal handler */
65ea5b03
PA
411 regs->sp = (unsigned long) frame;
412 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 413
536e3ee4 414 /* Make -mregparm=3 work */
65ea5b03
PA
415 regs->ax = sig;
416 regs->dx = 0;
417 regs->cx = 0;
536e3ee4 418
b6edbb1e
JF
419 loadsegment(ds, __USER32_DS);
420 loadsegment(es, __USER32_DS);
1da177e4 421
99b9cdf7
TG
422 regs->cs = __USER32_CS;
423 regs->ss = __USER32_DS;
1da177e4 424
1d001df1 425 return 0;
1da177e4
LT
426}
427
0928d6ef 428int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
99b9cdf7 429 compat_sigset_t *set, struct pt_regs *regs)
1da177e4 430{
3b0d29ee 431 struct rt_sigframe_ia32 __user *frame;
af65d648 432 void __user *restorer;
1da177e4 433 int err = 0;
ab513701 434 void __user *fpstate = NULL;
1da177e4 435
99b9cdf7
TG
436 /* __copy_to_user optimizes that into a single 8 byte store */
437 static const struct {
438 u8 movl;
439 u32 val;
440 u16 int80;
9cc3c49e 441 u8 pad;
99b9cdf7
TG
442 } __attribute__((packed)) code = {
443 0xb8,
444 __NR_ia32_rt_sigreturn,
445 0x80cd,
446 0,
447 };
448
3c1c7f10 449 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
1da177e4
LT
450
451 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
3d0aedd9 452 return -EFAULT;
1da177e4 453
3b4b7570
HS
454 put_user_try {
455 put_user_ex(sig, &frame->sig);
456 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
457 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
1da177e4 458
3b4b7570
HS
459 /* Create the ucontext. */
460 if (cpu_has_xsave)
461 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
462 else
463 put_user_ex(0, &frame->uc.uc_flags);
464 put_user_ex(0, &frame->uc.uc_link);
c40702c4 465 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
3b4b7570
HS
466
467 if (ka->sa.sa_flags & SA_RESTORER)
468 restorer = ka->sa.sa_restorer;
469 else
470 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
471 rt_sigreturn);
472 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
473
474 /*
475 * Not actually used anymore, but left because some gdb
476 * versions need it.
477 */
0ff8fef4 478 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
3b4b7570 479 } put_user_catch(err);
1da177e4 480
5e88353d
PA
481 err |= copy_siginfo_to_user32(&frame->info, info);
482 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
483 regs, set->sig[0]);
484 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
485
1da177e4 486 if (err)
3d0aedd9 487 return -EFAULT;
1da177e4
LT
488
489 /* Set up registers for signal handler */
65ea5b03
PA
490 regs->sp = (unsigned long) frame;
491 regs->ip = (unsigned long) ka->sa.sa_handler;
1da177e4 492
a7aacdf9 493 /* Make -mregparm=3 work */
65ea5b03
PA
494 regs->ax = sig;
495 regs->dx = (unsigned long) &frame->info;
496 regs->cx = (unsigned long) &frame->uc;
a7aacdf9 497
b6edbb1e
JF
498 loadsegment(ds, __USER32_DS);
499 loadsegment(es, __USER32_DS);
99b9cdf7
TG
500
501 regs->cs = __USER32_CS;
502 regs->ss = __USER32_DS;
1da177e4 503
1d001df1 504 return 0;
1da177e4 505}