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/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
54
55
56
57
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
69
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
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
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
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
232 current_thread_info()->restart_block.fn = do_no_restart_syscall;
233
234 get_user_try {
235
236
237
238
239
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
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
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
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
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
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
378 sp = regs->sp;
379
380
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
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
401
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
415 static const struct {
416 u16 poplmovl;
417 u32 val;
418 u16 int80;
419 } __attribute__((packed)) code = {
420 0xb858,
421 __NR_ia32_sigreturn,
422 0x80cd,
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
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
458
459
460 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
461 } put_user_catch(err);
462
463 if (err)
464 return -EFAULT;
465
466
467 regs->sp = (unsigned long) frame;
468 regs->ip = (unsigned long) ka->sa.sa_handler;
469
470
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
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
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
539
540
541 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
542 } put_user_catch(err);
543
544 if (err)
545 return -EFAULT;
546
547
548 regs->sp = (unsigned long) frame;
549 regs->ip = (unsigned long) ka->sa.sa_handler;
550
551
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}
564