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 mask &= _BLOCKABLE;
131 spin_lock_irq(¤t->sighand->siglock);
132 current->saved_sigmask = current->blocked;
133 siginitset(¤t->blocked, mask);
134 recalc_sigpending();
135 spin_unlock_irq(¤t->sighand->siglock);
136
137 current->state = TASK_INTERRUPTIBLE;
138 schedule();
139 set_restore_sigmask();
140 return -ERESTARTNOHAND;
141}
142
143asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144 stack_ia32_t __user *uoss_ptr,
145 struct pt_regs *regs)
146{
147 stack_t uss, uoss;
148 int ret, err = 0;
149 mm_segment_t seg;
150
151 if (uss_ptr) {
152 u32 ptr;
153
154 memset(&uss, 0, sizeof(stack_t));
155 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
156 return -EFAULT;
157
158 get_user_try {
159 get_user_ex(ptr, &uss_ptr->ss_sp);
160 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162 } get_user_catch(err);
163
164 if (err)
165 return -EFAULT;
166 uss.ss_sp = compat_ptr(ptr);
167 }
168 seg = get_fs();
169 set_fs(KERNEL_DS);
170 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
171 set_fs(seg);
172 if (ret >= 0 && uoss_ptr) {
173 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174 return -EFAULT;
175
176 put_user_try {
177 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180 } put_user_catch(err);
181
182 if (err)
183 ret = -EFAULT;
184 }
185 return ret;
186}
187
188
189
190
191#define loadsegment_gs(v) load_gs_index(v)
192#define loadsegment_fs(v) loadsegment(fs, v)
193#define loadsegment_ds(v) loadsegment(ds, v)
194#define loadsegment_es(v) loadsegment(es, v)
195
196#define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
197#define set_user_seg(seg, v) loadsegment_##seg(v)
198
199#define COPY(x) { \
200 get_user_ex(regs->x, &sc->x); \
201}
202
203#define GET_SEG(seg) ({ \
204 unsigned short tmp; \
205 get_user_ex(tmp, &sc->seg); \
206 tmp; \
207})
208
209#define COPY_SEG_CPL3(seg) do { \
210 regs->seg = GET_SEG(seg) | 3; \
211} while (0)
212
213#define RELOAD_SEG(seg) { \
214 unsigned int pre = GET_SEG(seg); \
215 unsigned int cur = get_user_seg(seg); \
216 pre |= 3; \
217 if (pre != cur) \
218 set_user_seg(seg, pre); \
219}
220
221static int ia32_restore_sigcontext(struct pt_regs *regs,
222 struct sigcontext_ia32 __user *sc,
223 unsigned int *pax)
224{
225 unsigned int tmpflags, err = 0;
226 void __user *buf;
227 u32 tmp;
228
229
230 current_thread_info()->restart_block.fn = do_no_restart_syscall;
231
232 get_user_try {
233
234
235
236
237
238
239 RELOAD_SEG(gs);
240 RELOAD_SEG(fs);
241 RELOAD_SEG(ds);
242 RELOAD_SEG(es);
243
244 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245 COPY(dx); COPY(cx); COPY(ip);
246
247
248 COPY_SEG_CPL3(cs);
249 COPY_SEG_CPL3(ss);
250
251 get_user_ex(tmpflags, &sc->flags);
252 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253
254 regs->orig_ax = -1;
255
256 get_user_ex(tmp, &sc->fpstate);
257 buf = compat_ptr(tmp);
258 err |= restore_i387_xstate_ia32(buf);
259
260 get_user_ex(*pax, &sc->ax);
261 } get_user_catch(err);
262
263 return err;
264}
265
266asmlinkage long sys32_sigreturn(struct pt_regs *regs)
267{
268 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
269 sigset_t set;
270 unsigned int ax;
271
272 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
273 goto badframe;
274 if (__get_user(set.sig[0], &frame->sc.oldmask)
275 || (_COMPAT_NSIG_WORDS > 1
276 && __copy_from_user((((char *) &set.sig) + 4),
277 &frame->extramask,
278 sizeof(frame->extramask))))
279 goto badframe;
280
281 sigdelsetmask(&set, ~_BLOCKABLE);
282 spin_lock_irq(¤t->sighand->siglock);
283 current->blocked = set;
284 recalc_sigpending();
285 spin_unlock_irq(¤t->sighand->siglock);
286
287 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
288 goto badframe;
289 return ax;
290
291badframe:
292 signal_fault(regs, frame, "32bit sigreturn");
293 return 0;
294}
295
296asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
297{
298 struct rt_sigframe_ia32 __user *frame;
299 sigset_t set;
300 unsigned int ax;
301 struct pt_regs tregs;
302
303 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
304
305 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
306 goto badframe;
307 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
308 goto badframe;
309
310 sigdelsetmask(&set, ~_BLOCKABLE);
311 spin_lock_irq(¤t->sighand->siglock);
312 current->blocked = set;
313 recalc_sigpending();
314 spin_unlock_irq(¤t->sighand->siglock);
315
316 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
317 goto badframe;
318
319 tregs = *regs;
320 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
321 goto badframe;
322
323 return ax;
324
325badframe:
326 signal_fault(regs, frame, "32bit rt sigreturn");
327 return 0;
328}
329
330
331
332
333
334static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
335 void __user *fpstate,
336 struct pt_regs *regs, unsigned int mask)
337{
338 int err = 0;
339
340 put_user_try {
341 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
342 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
343 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
344 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
345
346 put_user_ex(regs->di, &sc->di);
347 put_user_ex(regs->si, &sc->si);
348 put_user_ex(regs->bp, &sc->bp);
349 put_user_ex(regs->sp, &sc->sp);
350 put_user_ex(regs->bx, &sc->bx);
351 put_user_ex(regs->dx, &sc->dx);
352 put_user_ex(regs->cx, &sc->cx);
353 put_user_ex(regs->ax, &sc->ax);
354 put_user_ex(current->thread.trap_no, &sc->trapno);
355 put_user_ex(current->thread.error_code, &sc->err);
356 put_user_ex(regs->ip, &sc->ip);
357 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
358 put_user_ex(regs->flags, &sc->flags);
359 put_user_ex(regs->sp, &sc->sp_at_signal);
360 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
361
362 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
363
364
365 put_user_ex(mask, &sc->oldmask);
366 put_user_ex(current->thread.cr2, &sc->cr2);
367 } put_user_catch(err);
368
369 return err;
370}
371
372
373
374
375static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
376 size_t frame_size,
377 void **fpstate)
378{
379 unsigned long sp;
380
381
382 sp = regs->sp;
383
384
385 if (ka->sa.sa_flags & SA_ONSTACK) {
386 if (sas_ss_flags(sp) == 0)
387 sp = current->sas_ss_sp + current->sas_ss_size;
388 }
389
390
391 else if ((regs->ss & 0xffff) != __USER32_DS &&
392 !(ka->sa.sa_flags & SA_RESTORER) &&
393 ka->sa.sa_restorer)
394 sp = (unsigned long) ka->sa.sa_restorer;
395
396 if (used_math()) {
397 sp = sp - sig_xstate_ia32_size;
398 *fpstate = (struct _fpstate_ia32 *) sp;
399 if (save_i387_xstate_ia32(*fpstate) < 0)
400 return (void __user *) -1L;
401 }
402
403 sp -= frame_size;
404
405
406 sp = ((sp + 4) & -16ul) - 4;
407 return (void __user *) sp;
408}
409
410int ia32_setup_frame(int sig, struct k_sigaction *ka,
411 compat_sigset_t *set, struct pt_regs *regs)
412{
413 struct sigframe_ia32 __user *frame;
414 void __user *restorer;
415 int err = 0;
416 void __user *fpstate = NULL;
417
418
419 static const struct {
420 u16 poplmovl;
421 u32 val;
422 u16 int80;
423 } __attribute__((packed)) code = {
424 0xb858,
425 __NR_ia32_sigreturn,
426 0x80cd,
427 };
428
429 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
430
431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
432 return -EFAULT;
433
434 if (__put_user(sig, &frame->sig))
435 return -EFAULT;
436
437 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
438 return -EFAULT;
439
440 if (_COMPAT_NSIG_WORDS > 1) {
441 if (__copy_to_user(frame->extramask, &set->sig[1],
442 sizeof(frame->extramask)))
443 return -EFAULT;
444 }
445
446 if (ka->sa.sa_flags & SA_RESTORER) {
447 restorer = ka->sa.sa_restorer;
448 } else {
449
450 if (current->mm->context.vdso)
451 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
452 sigreturn);
453 else
454 restorer = &frame->retcode;
455 }
456
457 put_user_try {
458 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
459
460
461
462
463
464 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
465 } put_user_catch(err);
466
467 if (err)
468 return -EFAULT;
469
470
471 regs->sp = (unsigned long) frame;
472 regs->ip = (unsigned long) ka->sa.sa_handler;
473
474
475 regs->ax = sig;
476 regs->dx = 0;
477 regs->cx = 0;
478
479 loadsegment(ds, __USER32_DS);
480 loadsegment(es, __USER32_DS);
481
482 regs->cs = __USER32_CS;
483 regs->ss = __USER32_DS;
484
485 return 0;
486}
487
488int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
489 compat_sigset_t *set, struct pt_regs *regs)
490{
491 struct rt_sigframe_ia32 __user *frame;
492 void __user *restorer;
493 int err = 0;
494 void __user *fpstate = NULL;
495
496
497 static const struct {
498 u8 movl;
499 u32 val;
500 u16 int80;
501 u8 pad;
502 } __attribute__((packed)) code = {
503 0xb8,
504 __NR_ia32_rt_sigreturn,
505 0x80cd,
506 0,
507 };
508
509 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
510
511 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
512 return -EFAULT;
513
514 put_user_try {
515 put_user_ex(sig, &frame->sig);
516 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
517 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
518 err |= copy_siginfo_to_user32(&frame->info, info);
519
520
521 if (cpu_has_xsave)
522 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
523 else
524 put_user_ex(0, &frame->uc.uc_flags);
525 put_user_ex(0, &frame->uc.uc_link);
526 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
527 put_user_ex(sas_ss_flags(regs->sp),
528 &frame->uc.uc_stack.ss_flags);
529 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
530 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
531 regs, set->sig[0]);
532 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
533
534 if (ka->sa.sa_flags & SA_RESTORER)
535 restorer = ka->sa.sa_restorer;
536 else
537 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
538 rt_sigreturn);
539 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
540
541
542
543
544
545 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
546 } put_user_catch(err);
547
548 if (err)
549 return -EFAULT;
550
551
552 regs->sp = (unsigned long) frame;
553 regs->ip = (unsigned long) ka->sa.sa_handler;
554
555
556 regs->ax = sig;
557 regs->dx = (unsigned long) &frame->info;
558 regs->cx = (unsigned long) &frame->uc;
559
560 loadsegment(ds, __USER32_DS);
561 loadsegment(es, __USER32_DS);
562
563 regs->cs = __USER32_CS;
564 regs->ss = __USER32_DS;
565
566 return 0;
567}
568