Branch data Line data Source code
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 <linux/syscalls.h>
25 : : #include <asm/ucontext.h>
26 : : #include <linux/uaccess.h>
27 : : #include <asm/fpu/internal.h>
28 : : #include <asm/fpu/signal.h>
29 : : #include <asm/ptrace.h>
30 : : #include <asm/ia32_unistd.h>
31 : : #include <asm/user32.h>
32 : : #include <uapi/asm/sigcontext.h>
33 : : #include <asm/proto.h>
34 : : #include <asm/vdso.h>
35 : : #include <asm/sigframe.h>
36 : : #include <asm/sighandling.h>
37 : : #include <asm/smap.h>
38 : :
39 : : /*
40 : : * Do a signal return; undo the signal stack.
41 : : */
42 : : #define loadsegment_gs(v) load_gs_index(v)
43 : : #define loadsegment_fs(v) loadsegment(fs, v)
44 : : #define loadsegment_ds(v) loadsegment(ds, v)
45 : : #define loadsegment_es(v) loadsegment(es, v)
46 : :
47 : : #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
48 : : #define set_user_seg(seg, v) loadsegment_##seg(v)
49 : :
50 : : #define COPY(x) { \
51 : : get_user_ex(regs->x, &sc->x); \
52 : : }
53 : :
54 : : #define GET_SEG(seg) ({ \
55 : : unsigned short tmp; \
56 : : get_user_ex(tmp, &sc->seg); \
57 : : tmp; \
58 : : })
59 : :
60 : : #define COPY_SEG_CPL3(seg) do { \
61 : : regs->seg = GET_SEG(seg) | 3; \
62 : : } while (0)
63 : :
64 : : #define RELOAD_SEG(seg) { \
65 : : unsigned int pre = (seg) | 3; \
66 : : unsigned int cur = get_user_seg(seg); \
67 : : if (pre != cur) \
68 : : set_user_seg(seg, pre); \
69 : : }
70 : :
71 : 0 : static int ia32_restore_sigcontext(struct pt_regs *regs,
72 : : struct sigcontext_32 __user *sc)
73 : : {
74 : 0 : unsigned int tmpflags, err = 0;
75 : 0 : u16 gs, fs, es, ds;
76 : 0 : void __user *buf;
77 : 0 : u32 tmp;
78 : :
79 : : /* Always make any pending restarted system calls return -EINTR */
80 : 0 : current->restart_block.fn = do_no_restart_syscall;
81 : :
82 : 0 : get_user_try {
83 : 0 : gs = GET_SEG(gs);
84 : 0 : fs = GET_SEG(fs);
85 : 0 : ds = GET_SEG(ds);
86 : 0 : es = GET_SEG(es);
87 : :
88 : 0 : COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
89 : 0 : COPY(dx); COPY(cx); COPY(ip); COPY(ax);
90 : : /* Don't touch extended registers */
91 : :
92 : 0 : COPY_SEG_CPL3(cs);
93 : 0 : COPY_SEG_CPL3(ss);
94 : :
95 : 0 : get_user_ex(tmpflags, &sc->flags);
96 : 0 : regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
97 : : /* disable syscall checks */
98 : 0 : regs->orig_ax = -1;
99 : :
100 : 0 : get_user_ex(tmp, &sc->fpstate);
101 : 0 : buf = compat_ptr(tmp);
102 [ # # ]: 0 : } get_user_catch(err);
103 : :
104 : : /*
105 : : * Reload fs and gs if they have changed in the signal
106 : : * handler. This does not handle long fs/gs base changes in
107 : : * the handler, but does not clobber them at least in the
108 : : * normal case.
109 : : */
110 [ # # ]: 0 : RELOAD_SEG(gs);
111 [ # # ]: 0 : RELOAD_SEG(fs);
112 [ # # ]: 0 : RELOAD_SEG(ds);
113 [ # # ]: 0 : RELOAD_SEG(es);
114 : :
115 : 0 : err |= fpu__restore_sig(buf, 1);
116 : :
117 : 0 : return err;
118 : : }
119 : :
120 : 0 : COMPAT_SYSCALL_DEFINE0(sigreturn)
121 : : {
122 [ # # ]: 0 : struct pt_regs *regs = current_pt_regs();
123 : 0 : struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
124 : 0 : sigset_t set;
125 : :
126 [ # # ]: 0 : if (!access_ok(frame, sizeof(*frame)))
127 : 0 : goto badframe;
128 [ # # ]: 0 : if (__get_user(set.sig[0], &frame->sc.oldmask)
129 [ # # ]: 0 : || (_COMPAT_NSIG_WORDS > 1
130 : : && __copy_from_user((((char *) &set.sig) + 4),
131 : 0 : &frame->extramask,
132 : : sizeof(frame->extramask))))
133 : 0 : goto badframe;
134 : :
135 : 0 : set_current_blocked(&set);
136 : :
137 [ # # ]: 0 : if (ia32_restore_sigcontext(regs, &frame->sc))
138 : 0 : goto badframe;
139 : 0 : return regs->ax;
140 : :
141 : 0 : badframe:
142 : 0 : signal_fault(regs, frame, "32bit sigreturn");
143 : 0 : return 0;
144 : : }
145 : :
146 : 0 : COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
147 : : {
148 [ # # ]: 0 : struct pt_regs *regs = current_pt_regs();
149 : 0 : struct rt_sigframe_ia32 __user *frame;
150 : 0 : sigset_t set;
151 : :
152 : 0 : frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
153 : :
154 [ # # ]: 0 : if (!access_ok(frame, sizeof(*frame)))
155 : 0 : goto badframe;
156 [ # # ]: 0 : if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
157 : 0 : goto badframe;
158 : :
159 : 0 : set_current_blocked(&set);
160 : :
161 [ # # ]: 0 : if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext))
162 : 0 : goto badframe;
163 : :
164 [ # # ]: 0 : if (compat_restore_altstack(&frame->uc.uc_stack))
165 : 0 : goto badframe;
166 : :
167 : 0 : return regs->ax;
168 : :
169 : 0 : badframe:
170 : 0 : signal_fault(regs, frame, "32bit rt sigreturn");
171 : 0 : return 0;
172 : : }
173 : :
174 : : /*
175 : : * Set up a signal frame.
176 : : */
177 : :
178 : 0 : static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc,
179 : : void __user *fpstate,
180 : : struct pt_regs *regs, unsigned int mask)
181 : : {
182 : 0 : int err = 0;
183 : :
184 : 0 : put_user_try {
185 : 0 : put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
186 : 0 : put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
187 : 0 : put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
188 : 0 : put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
189 : :
190 : 0 : put_user_ex(regs->di, &sc->di);
191 : 0 : put_user_ex(regs->si, &sc->si);
192 : 0 : put_user_ex(regs->bp, &sc->bp);
193 : 0 : put_user_ex(regs->sp, &sc->sp);
194 : 0 : put_user_ex(regs->bx, &sc->bx);
195 : 0 : put_user_ex(regs->dx, &sc->dx);
196 : 0 : put_user_ex(regs->cx, &sc->cx);
197 : 0 : put_user_ex(regs->ax, &sc->ax);
198 : 0 : put_user_ex(current->thread.trap_nr, &sc->trapno);
199 : 0 : put_user_ex(current->thread.error_code, &sc->err);
200 : 0 : put_user_ex(regs->ip, &sc->ip);
201 : 0 : put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
202 : 0 : put_user_ex(regs->flags, &sc->flags);
203 : 0 : put_user_ex(regs->sp, &sc->sp_at_signal);
204 : 0 : put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
205 : :
206 : 0 : put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
207 : :
208 : : /* non-iBCS2 extensions.. */
209 : 0 : put_user_ex(mask, &sc->oldmask);
210 : 0 : put_user_ex(current->thread.cr2, &sc->cr2);
211 [ # # ]: 0 : } put_user_catch(err);
212 : :
213 : 0 : return err;
214 : : }
215 : :
216 : : /*
217 : : * Determine which stack to use..
218 : : */
219 : : static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
220 : : size_t frame_size,
221 : : void __user **fpstate)
222 : : {
223 : : unsigned long sp, fx_aligned, math_size;
224 : :
225 : : /* Default to using normal stack */
226 : : sp = regs->sp;
227 : :
228 : : /* This is the X/Open sanctioned signal stack switching. */
229 : : if (ksig->ka.sa.sa_flags & SA_ONSTACK)
230 : : sp = sigsp(sp, ksig);
231 : : /* This is the legacy signal stack switching. */
232 : : else if (regs->ss != __USER32_DS &&
233 : : !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
234 : : ksig->ka.sa.sa_restorer)
235 : : sp = (unsigned long) ksig->ka.sa.sa_restorer;
236 : :
237 : : sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
238 : : *fpstate = (struct _fpstate_32 __user *) sp;
239 : : if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
240 : : math_size) < 0)
241 : : return (void __user *) -1L;
242 : :
243 : : sp -= frame_size;
244 : : /* Align the stack pointer according to the i386 ABI,
245 : : * i.e. so that on function entry ((sp + 4) & 15) == 0. */
246 : : sp = ((sp + 4) & -16ul) - 4;
247 : : return (void __user *) sp;
248 : : }
249 : :
250 : 0 : int ia32_setup_frame(int sig, struct ksignal *ksig,
251 : : compat_sigset_t *set, struct pt_regs *regs)
252 : : {
253 : 0 : struct sigframe_ia32 __user *frame;
254 : 0 : void __user *restorer;
255 : 0 : int err = 0;
256 : 0 : void __user *fpstate = NULL;
257 : :
258 : : /* copy_to_user optimizes that into a single 8 byte store */
259 : 0 : static const struct {
260 : : u16 poplmovl;
261 : : u32 val;
262 : : u16 int80;
263 : : } __attribute__((packed)) code = {
264 : : 0xb858, /* popl %eax ; movl $...,%eax */
265 : : __NR_ia32_sigreturn,
266 : : 0x80cd, /* int $0x80 */
267 : : };
268 : :
269 : 0 : frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
270 : :
271 [ # # ]: 0 : if (!access_ok(frame, sizeof(*frame)))
272 : : return -EFAULT;
273 : :
274 [ # # # # ]: 0 : if (__put_user(sig, &frame->sig))
275 : : return -EFAULT;
276 : :
277 [ # # ]: 0 : if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
278 : : return -EFAULT;
279 : :
280 : 0 : if (_COMPAT_NSIG_WORDS > 1) {
281 [ # # ]: 0 : if (__copy_to_user(frame->extramask, &set->sig[1],
282 : : sizeof(frame->extramask)))
283 : : return -EFAULT;
284 : : }
285 : :
286 [ # # ]: 0 : if (ksig->ka.sa.sa_flags & SA_RESTORER) {
287 : 0 : restorer = ksig->ka.sa.sa_restorer;
288 : : } else {
289 : : /* Return stub is in 32bit vsyscall page */
290 [ # # ]: 0 : if (current->mm->context.vdso)
291 : 0 : restorer = current->mm->context.vdso +
292 : 0 : vdso_image_32.sym___kernel_sigreturn;
293 : : else
294 : 0 : restorer = &frame->retcode;
295 : : }
296 : :
297 : 0 : put_user_try {
298 : 0 : put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
299 : :
300 : : /*
301 : : * These are actually not used anymore, but left because some
302 : : * gdb versions depend on them as a marker.
303 : : */
304 : 0 : put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
305 [ # # ]: 0 : } put_user_catch(err);
306 : :
307 : 0 : if (err)
308 : : return -EFAULT;
309 : :
310 : : /* Set up registers for signal handler */
311 : 0 : regs->sp = (unsigned long) frame;
312 : 0 : regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
313 : :
314 : : /* Make -mregparm=3 work */
315 : 0 : regs->ax = sig;
316 : 0 : regs->dx = 0;
317 : 0 : regs->cx = 0;
318 : :
319 : 0 : loadsegment(ds, __USER32_DS);
320 : 0 : loadsegment(es, __USER32_DS);
321 : :
322 : 0 : regs->cs = __USER32_CS;
323 : 0 : regs->ss = __USER32_DS;
324 : :
325 : 0 : return 0;
326 : : }
327 : :
328 : 0 : int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
329 : : compat_sigset_t *set, struct pt_regs *regs)
330 : : {
331 : 0 : struct rt_sigframe_ia32 __user *frame;
332 : 0 : void __user *restorer;
333 : 0 : int err = 0;
334 : 0 : void __user *fpstate = NULL;
335 : :
336 : : /* __copy_to_user optimizes that into a single 8 byte store */
337 : 0 : static const struct {
338 : : u8 movl;
339 : : u32 val;
340 : : u16 int80;
341 : : u8 pad;
342 : : } __attribute__((packed)) code = {
343 : : 0xb8,
344 : : __NR_ia32_rt_sigreturn,
345 : : 0x80cd,
346 : : 0,
347 : : };
348 : :
349 : 0 : frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
350 : :
351 [ # # ]: 0 : if (!access_ok(frame, sizeof(*frame)))
352 : : return -EFAULT;
353 : :
354 : 0 : put_user_try {
355 : 0 : put_user_ex(sig, &frame->sig);
356 : 0 : put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
357 : 0 : put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
358 : :
359 : : /* Create the ucontext. */
360 [ # # # ]: 0 : if (static_cpu_has(X86_FEATURE_XSAVE))
361 : 0 : put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
362 : : else
363 : 0 : put_user_ex(0, &frame->uc.uc_flags);
364 : 0 : put_user_ex(0, &frame->uc.uc_link);
365 [ # # ]: 0 : compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
366 : :
367 [ # # ]: 0 : if (ksig->ka.sa.sa_flags & SA_RESTORER)
368 : 0 : restorer = ksig->ka.sa.sa_restorer;
369 : : else
370 : 0 : restorer = current->mm->context.vdso +
371 : 0 : vdso_image_32.sym___kernel_rt_sigreturn;
372 : 0 : put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
373 : :
374 : : /*
375 : : * Not actually used anymore, but left because some gdb
376 : : * versions need it.
377 : : */
378 : 0 : put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
379 [ # # ]: 0 : } put_user_catch(err);
380 : :
381 : 0 : err |= __copy_siginfo_to_user32(&frame->info, &ksig->info, false);
382 : 0 : err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
383 : : regs, set->sig[0]);
384 : 0 : err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
385 : :
386 [ # # ]: 0 : if (err)
387 : : return -EFAULT;
388 : :
389 : : /* Set up registers for signal handler */
390 : 0 : regs->sp = (unsigned long) frame;
391 : 0 : regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
392 : :
393 : : /* Make -mregparm=3 work */
394 : 0 : regs->ax = sig;
395 : 0 : regs->dx = (unsigned long) &frame->info;
396 : 0 : regs->cx = (unsigned long) &frame->uc;
397 : :
398 : 0 : loadsegment(ds, __USER32_DS);
399 : 0 : loadsegment(es, __USER32_DS);
400 : :
401 : 0 : regs->cs = __USER32_CS;
402 : 0 : regs->ss = __USER32_DS;
403 : :
404 : 0 : return 0;
405 : : }
|