1
2
3
4
5
6
7
8
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/errno.h>
16#include <linux/wait.h>
17#include <linux/unistd.h>
18#include <linux/stddef.h>
19#include <linux/personality.h>
20#include <linux/compat.h>
21#include <linux/binfmts.h>
22#include <asm/ucontext.h>
23#include <asm/uaccess.h>
24#include <asm/i387.h>
25#include <asm/fpu-internal.h>
26#include <asm/ptrace.h>
27#include <asm/ia32_unistd.h>
28#include <asm/user32.h>
29#include <asm/sigcontext32.h>
30#include <asm/proto.h>
31#include <asm/vdso.h>
32#include <asm/sigframe.h>
33#include <asm/sighandling.h>
34#include <asm/sys_ia32.h>
35#include <asm/smap.h>
36
37int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
38{
39 int err = 0;
40 bool ia32 = test_thread_flag(TIF_IA32);
41
42 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
43 return -EFAULT;
44
45 put_user_try {
46
47
48
49
50
51 put_user_ex(from->si_signo, &to->si_signo);
52 put_user_ex(from->si_errno, &to->si_errno);
53 put_user_ex((short)from->si_code, &to->si_code);
54
55 if (from->si_code < 0) {
56 put_user_ex(from->si_pid, &to->si_pid);
57 put_user_ex(from->si_uid, &to->si_uid);
58 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
59 } else {
60
61
62
63
64 put_user_ex(from->_sifields._pad[0],
65 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16:
68 break;
69 case __SI_SYS >> 16:
70 put_user_ex(from->si_syscall, &to->si_syscall);
71 put_user_ex(from->si_arch, &to->si_arch);
72 break;
73 case __SI_CHLD >> 16:
74 if (ia32) {
75 put_user_ex(from->si_utime, &to->si_utime);
76 put_user_ex(from->si_stime, &to->si_stime);
77 } else {
78 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
79 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
80 }
81 put_user_ex(from->si_status, &to->si_status);
82
83 default:
84 case __SI_KILL >> 16:
85 put_user_ex(from->si_uid, &to->si_uid);
86 break;
87 case __SI_POLL >> 16:
88 put_user_ex(from->si_fd, &to->si_fd);
89 break;
90 case __SI_TIMER >> 16:
91 put_user_ex(from->si_overrun, &to->si_overrun);
92 put_user_ex(ptr_to_compat(from->si_ptr),
93 &to->si_ptr);
94 break;
95
96 case __SI_RT >> 16:
97 case __SI_MESGQ >> 16:
98 put_user_ex(from->si_uid, &to->si_uid);
99 put_user_ex(from->si_int, &to->si_int);
100 break;
101 }
102 }
103 } put_user_catch(err);
104
105 return err;
106}
107
108int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
109{
110 int err = 0;
111 u32 ptr32;
112
113 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
114 return -EFAULT;
115
116 get_user_try {
117 get_user_ex(to->si_signo, &from->si_signo);
118 get_user_ex(to->si_errno, &from->si_errno);
119 get_user_ex(to->si_code, &from->si_code);
120
121 get_user_ex(to->si_pid, &from->si_pid);
122 get_user_ex(to->si_uid, &from->si_uid);
123 get_user_ex(ptr32, &from->si_ptr);
124 to->si_ptr = compat_ptr(ptr32);
125 } get_user_catch(err);
126
127 return err;
128}
129
130
131
132
133#define loadsegment_gs(v) load_gs_index(v)
134#define loadsegment_fs(v) loadsegment(fs, v)
135#define loadsegment_ds(v) loadsegment(ds, v)
136#define loadsegment_es(v) loadsegment(es, v)
137
138#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
139#define set_user_seg(seg, v) loadsegment_##seg(v)
140
141#define COPY(x) { \
142 get_user_ex(regs->x, &sc->x); \
143}
144
145#define GET_SEG(seg) ({ \
146 unsigned short tmp; \
147 get_user_ex(tmp, &sc->seg); \
148 tmp; \
149})
150
151#define COPY_SEG_CPL3(seg) do { \
152 regs->seg = GET_SEG(seg) | 3; \
153} while (0)
154
155#define RELOAD_SEG(seg) { \
156 unsigned int pre = GET_SEG(seg); \
157 unsigned int cur = get_user_seg(seg); \
158 pre |= 3; \
159 if (pre != cur) \
160 set_user_seg(seg, pre); \
161}
162
163static int ia32_restore_sigcontext(struct pt_regs *regs,
164 struct sigcontext_ia32 __user *sc,
165 unsigned int *pax)
166{
167 unsigned int tmpflags, err = 0;
168 void __user *buf;
169 u32 tmp;
170
171
172 current_thread_info()->restart_block.fn = do_no_restart_syscall;
173
174 get_user_try {
175
176
177
178
179
180
181 RELOAD_SEG(gs);
182 RELOAD_SEG(fs);
183 RELOAD_SEG(ds);
184 RELOAD_SEG(es);
185
186 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
187 COPY(dx); COPY(cx); COPY(ip);
188
189
190 COPY_SEG_CPL3(cs);
191 COPY_SEG_CPL3(ss);
192
193 get_user_ex(tmpflags, &sc->flags);
194 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
195
196 regs->orig_ax = -1;
197
198 get_user_ex(tmp, &sc->fpstate);
199 buf = compat_ptr(tmp);
200
201 get_user_ex(*pax, &sc->ax);
202 } get_user_catch(err);
203
204 err |= restore_xstate_sig(buf, 1);
205
206 return err;
207}
208
209asmlinkage long sys32_sigreturn(void)
210{
211 struct pt_regs *regs = current_pt_regs();
212 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
213 sigset_t set;
214 unsigned int ax;
215
216 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
217 goto badframe;
218 if (__get_user(set.sig[0], &frame->sc.oldmask)
219 || (_COMPAT_NSIG_WORDS > 1
220 && __copy_from_user((((char *) &set.sig) + 4),
221 &frame->extramask,
222 sizeof(frame->extramask))))
223 goto badframe;
224
225 set_current_blocked(&set);
226
227 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
228 goto badframe;
229 return ax;
230
231badframe:
232 signal_fault(regs, frame, "32bit sigreturn");
233 return 0;
234}
235
236asmlinkage long sys32_rt_sigreturn(void)
237{
238 struct pt_regs *regs = current_pt_regs();
239 struct rt_sigframe_ia32 __user *frame;
240 sigset_t set;
241 unsigned int ax;
242
243 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
244
245 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
246 goto badframe;
247 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
248 goto badframe;
249
250 set_current_blocked(&set);
251
252 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
253 goto badframe;
254
255 if (compat_restore_altstack(&frame->uc.uc_stack))
256 goto badframe;
257
258 return ax;
259
260badframe:
261 signal_fault(regs, frame, "32bit rt sigreturn");
262 return 0;
263}
264
265
266
267
268
269static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
270 void __user *fpstate,
271 struct pt_regs *regs, unsigned int mask)
272{
273 int err = 0;
274
275 put_user_try {
276 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
277 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
278 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
279 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
280
281 put_user_ex(regs->di, &sc->di);
282 put_user_ex(regs->si, &sc->si);
283 put_user_ex(regs->bp, &sc->bp);
284 put_user_ex(regs->sp, &sc->sp);
285 put_user_ex(regs->bx, &sc->bx);
286 put_user_ex(regs->dx, &sc->dx);
287 put_user_ex(regs->cx, &sc->cx);
288 put_user_ex(regs->ax, &sc->ax);
289 put_user_ex(current->thread.trap_nr, &sc->trapno);
290 put_user_ex(current->thread.error_code, &sc->err);
291 put_user_ex(regs->ip, &sc->ip);
292 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
293 put_user_ex(regs->flags, &sc->flags);
294 put_user_ex(regs->sp, &sc->sp_at_signal);
295 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
296
297 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
298
299
300 put_user_ex(mask, &sc->oldmask);
301 put_user_ex(current->thread.cr2, &sc->cr2);
302 } put_user_catch(err);
303
304 return err;
305}
306
307
308
309
310static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
311 size_t frame_size,
312 void __user **fpstate)
313{
314 unsigned long sp;
315
316
317 sp = regs->sp;
318
319
320 if (ksig->ka.sa.sa_flags & SA_ONSTACK)
321 sp = sigsp(sp, ksig);
322
323 else if ((regs->ss & 0xffff) != __USER32_DS &&
324 !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
325 ksig->ka.sa.sa_restorer)
326 sp = (unsigned long) ksig->ka.sa.sa_restorer;
327
328 if (used_math()) {
329 unsigned long fx_aligned, math_size;
330
331 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
332 *fpstate = (struct _fpstate_ia32 __user *) sp;
333 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
334 math_size) < 0)
335 return (void __user *) -1L;
336 }
337
338 sp -= frame_size;
339
340
341 sp = ((sp + 4) & -16ul) - 4;
342 return (void __user *) sp;
343}
344
345int ia32_setup_frame(int sig, struct ksignal *ksig,
346 compat_sigset_t *set, struct pt_regs *regs)
347{
348 struct sigframe_ia32 __user *frame;
349 void __user *restorer;
350 int err = 0;
351 void __user *fpstate = NULL;
352
353
354 static const struct {
355 u16 poplmovl;
356 u32 val;
357 u16 int80;
358 } __attribute__((packed)) code = {
359 0xb858,
360 __NR_ia32_sigreturn,
361 0x80cd,
362 };
363
364 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
365
366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
367 return -EFAULT;
368
369 if (__put_user(sig, &frame->sig))
370 return -EFAULT;
371
372 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
373 return -EFAULT;
374
375 if (_COMPAT_NSIG_WORDS > 1) {
376 if (__copy_to_user(frame->extramask, &set->sig[1],
377 sizeof(frame->extramask)))
378 return -EFAULT;
379 }
380
381 if (ksig->ka.sa.sa_flags & SA_RESTORER) {
382 restorer = ksig->ka.sa.sa_restorer;
383 } else {
384
385 if (current->mm->context.vdso)
386 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
387 sigreturn);
388 else
389 restorer = &frame->retcode;
390 }
391
392 put_user_try {
393 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
394
395
396
397
398
399 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
400 } put_user_catch(err);
401
402 if (err)
403 return -EFAULT;
404
405
406 regs->sp = (unsigned long) frame;
407 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
408
409
410 regs->ax = sig;
411 regs->dx = 0;
412 regs->cx = 0;
413
414 loadsegment(ds, __USER32_DS);
415 loadsegment(es, __USER32_DS);
416
417 regs->cs = __USER32_CS;
418 regs->ss = __USER32_DS;
419
420 return 0;
421}
422
423int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
424 compat_sigset_t *set, struct pt_regs *regs)
425{
426 struct rt_sigframe_ia32 __user *frame;
427 void __user *restorer;
428 int err = 0;
429 void __user *fpstate = NULL;
430
431
432 static const struct {
433 u8 movl;
434 u32 val;
435 u16 int80;
436 u8 pad;
437 } __attribute__((packed)) code = {
438 0xb8,
439 __NR_ia32_rt_sigreturn,
440 0x80cd,
441 0,
442 };
443
444 frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
445
446 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
447 return -EFAULT;
448
449 put_user_try {
450 put_user_ex(sig, &frame->sig);
451 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
452 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
453
454
455 if (cpu_has_xsave)
456 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
457 else
458 put_user_ex(0, &frame->uc.uc_flags);
459 put_user_ex(0, &frame->uc.uc_link);
460 compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
461
462 if (ksig->ka.sa.sa_flags & SA_RESTORER)
463 restorer = ksig->ka.sa.sa_restorer;
464 else
465 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
466 rt_sigreturn);
467 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
468
469
470
471
472
473 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
474 } put_user_catch(err);
475
476 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
477 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
478 regs, set->sig[0]);
479 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
480
481 if (err)
482 return -EFAULT;
483
484
485 regs->sp = (unsigned long) frame;
486 regs->ip = (unsigned long) ksig->ka.sa.sa_handler;
487
488
489 regs->ax = sig;
490 regs->dx = (unsigned long) &frame->info;
491 regs->cx = (unsigned long) &frame->uc;
492
493 loadsegment(ds, __USER32_DS);
494 loadsegment(es, __USER32_DS);
495
496 regs->cs = __USER32_CS;
497 regs->ss = __USER32_DS;
498
499 return 0;
500}
501