1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/smp.h>
16#include <linux/smp_lock.h>
17#include <linux/kernel.h>
18#include <linux/signal.h>
19#include <linux/errno.h>
20#include <linux/wait.h>
21#include <linux/ptrace.h>
22#include <linux/unistd.h>
23#include <linux/stddef.h>
24#include <linux/personality.h>
25#include <asm/ucontext.h>
26#include <asm/uaccess.h>
27#include <asm/i387.h>
28#include <asm/ia32.h>
29#include <asm/ptrace.h>
30#include <asm/ia32_unistd.h>
31#include <asm/user32.h>
32#include <asm/sigcontext32.h>
33#include <asm/fpu32.h>
34
35#define ptr_to_u32(x) ((u32)(u64)(x))
36#define u32_to_ptr(x) ((void *)(u64)(x))
37
38#define DEBUG_SIG 0
39
40#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
41
42asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
43void signal_fault(struct pt_regs *regs, void *frame, char *where);
44
45static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
46{
47 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
48 return -EFAULT;
49 if (from->si_code < 0) {
50
51
52
53 memmove(&((siginfo_t32 *)&from)->si_int,
54 &from->si_int,
55 sizeof(siginfo_t) - offsetof(siginfo_t, si_int));
56
57 return __copy_to_user(to, from, sizeof(siginfo_t32));
58 } else {
59 int err;
60
61
62
63
64
65
66 err = __put_user(from->si_signo, &to->si_signo);
67 err |= __put_user(from->si_errno, &to->si_errno);
68 err |= __put_user(from->si_code, &to->si_code);
69
70 err |= __put_user(from->si_pid, &to->si_pid);
71 switch (from->si_code >> 16) {
72 case __SI_FAULT >> 16:
73 break;
74 case __SI_CHLD >> 16:
75 err |= __put_user(from->si_utime, &to->si_utime);
76 err |= __put_user(from->si_stime, &to->si_stime);
77 err |= __put_user(from->si_status, &to->si_status);
78 default:
79 err |= __put_user(from->si_uid, &to->si_uid);
80 break;
81 case __SI_POLL >> 16:
82 err |= __put_user(from->si_band, &to->si_band);
83 err |= __put_user(from->si_fd, &to->si_fd);
84 break;
85
86 }
87 return err;
88 }
89}
90
91asmlinkage long
92sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
93{
94 sigset_t saveset;
95
96 mask &= _BLOCKABLE;
97 spin_lock_irq(¤t->sigmask_lock);
98 saveset = current->blocked;
99 siginitset(¤t->blocked, mask);
100 recalc_sigpending(current);
101 spin_unlock_irq(¤t->sigmask_lock);
102
103 regs.rax = -EINTR;
104 while (1) {
105 current->state = TASK_INTERRUPTIBLE;
106 schedule();
107 if (do_signal(®s, &saveset))
108 return -EINTR;
109 }
110}
111
112asmlinkage long
113sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr,
114 struct pt_regs regs)
115{
116 stack_t uss,uoss;
117 int ret;
118 mm_segment_t seg;
119 if (uss_ptr) {
120 u32 val32;
121 memset(&uss, 0, sizeof(stack_t));
122 if (!access_ok(VERIFY_READ,uss_ptr,sizeof(stack_ia32_t)) ||
123 __get_user(val32, &uss_ptr->ss_sp) ||
124 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
125 __get_user(uss.ss_size, &uss_ptr->ss_size))
126 return -EFAULT;
127 uss.ss_sp = u32_to_ptr(val32);
128 }
129 seg = get_fs();
130 set_fs(KERNEL_DS);
131 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs.rsp);
132 set_fs(seg);
133 if (ret >= 0 && uoss_ptr) {
134 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
135 __put_user(ptr_to_u32(uoss.ss_sp), &uoss_ptr->ss_sp) ||
136 __put_user((u32)uoss.ss_flags, &uoss_ptr->ss_flags) ||
137 __put_user((u32)uoss.ss_size, &uoss_ptr->ss_size))
138 ret = -EFAULT;
139 }
140 return ret;
141}
142
143
144
145
146
147struct sigframe
148{
149 u32 pretcode;
150 int sig;
151 struct sigcontext_ia32 sc;
152 struct _fpstate_ia32 fpstate;
153 unsigned int extramask[_IA32_NSIG_WORDS-1];
154 char retcode[8];
155};
156
157struct rt_sigframe
158{
159 u32 pretcode;
160 int sig;
161 u32 pinfo;
162 u32 puc;
163 struct siginfo32 info;
164 struct ucontext_ia32 uc;
165 struct _fpstate_ia32 fpstate;
166 char retcode[8];
167};
168
169static int
170ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
171{
172 unsigned int err = 0;
173
174#if DEBUG_SIG
175 printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
176 sc, sc->err, sc->eip, sc->cs, sc->eflags);
177#endif
178#define COPY(x) { \
179 unsigned int reg; \
180 err |= __get_user(reg, &sc->e ##x); \
181 regs->r ## x = reg; \
182}
183
184#define RELOAD_SEG(seg,mask) \
185 { unsigned int cur; \
186 unsigned short pre; \
187 err |= __get_user(pre, &sc->seg); \
188 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
189 pre |= mask; \
190 if (pre != cur) loadsegment(seg,pre); }
191
192
193
194
195
196 {
197 unsigned short gs;
198 unsigned int curgs;
199 err |= __get_user(gs, &sc->gs);
200 asm volatile("movl %%gs,%0" : "=r" (curgs));
201 if (gs != curgs)
202 load_gs_index(gs | 3);
203 }
204 RELOAD_SEG(fs,3);
205 RELOAD_SEG(ds,3);
206 RELOAD_SEG(es,3);
207
208 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
209 COPY(dx); COPY(cx); COPY(ip);
210
211
212 err |= __get_user(regs->cs, &sc->cs);
213 regs->cs |= 3;
214 err |= __get_user(regs->ss, &sc->ss);
215 regs->ss |= 3;
216
217 {
218 unsigned int tmpflags;
219 err |= __get_user(tmpflags, &sc->eflags);
220 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
221 regs->orig_rax = -1;
222 }
223
224 {
225 u32 tmp;
226 struct _fpstate_ia32 * buf;
227 err |= __get_user(tmp, &sc->fpstate);
228 buf = (struct _fpstate_ia32 *) (u64)tmp;
229 if (buf) {
230 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
231 return 1;
232 err |= restore_i387_ia32(current, buf, 0);
233 }
234 }
235
236 {
237 u32 tmp;
238 err |= __get_user(tmp, &sc->eax);
239 *peax = tmp;
240 }
241 return err;
242}
243
244asmlinkage long sys32_sigreturn(struct pt_regs regs)
245{
246 struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
247 sigset_t set;
248 unsigned int eax;
249
250 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
251 goto badframe;
252 if (__get_user(set.sig[0], &frame->sc.oldmask)
253 || (_IA32_NSIG_WORDS > 1
254 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
255 sizeof(frame->extramask))))
256 goto badframe;
257
258 sigdelsetmask(&set, ~_BLOCKABLE);
259 spin_lock_irq(¤t->sigmask_lock);
260 current->blocked = set;
261 recalc_sigpending(current);
262 spin_unlock_irq(¤t->sigmask_lock);
263
264 if (ia32_restore_sigcontext(®s, &frame->sc, &eax))
265 goto badframe;
266 return eax;
267
268badframe:
269 signal_fault(®s,frame,"32bit sigreturn");
270 return 0;
271}
272
273asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
274{
275 struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
276 sigset_t set;
277 stack_t st;
278 unsigned int eax;
279
280 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
281 goto badframe;
282 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
283 goto badframe;
284
285 sigdelsetmask(&set, ~_BLOCKABLE);
286 spin_lock_irq(¤t->sigmask_lock);
287 current->blocked = set;
288 recalc_sigpending(current);
289 spin_unlock_irq(¤t->sigmask_lock);
290
291 if (ia32_restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax))
292 goto badframe;
293
294 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
295 goto badframe;
296
297
298 {
299 mm_segment_t oldds = get_fs();
300 set_fs(KERNEL_DS);
301 do_sigaltstack(&st, NULL, regs.rsp);
302 set_fs(oldds);
303 }
304
305 return eax;
306
307badframe:
308 signal_fault(®s,frame,"32bit rt sigreturn");
309 return 0;
310}
311
312
313
314
315
316static int
317ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
318 struct pt_regs *regs, unsigned int mask)
319{
320 int tmp, err = 0;
321
322 tmp = 0;
323 __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
324 err |= __put_user(tmp, (unsigned int *)&sc->gs);
325 __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
326 err |= __put_user(tmp, (unsigned int *)&sc->fs);
327 __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
328 err |= __put_user(tmp, (unsigned int *)&sc->ds);
329 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
330 err |= __put_user(tmp, (unsigned int *)&sc->es);
331
332 err |= __put_user((u32)regs->rdi, &sc->edi);
333 err |= __put_user((u32)regs->rsi, &sc->esi);
334 err |= __put_user((u32)regs->rbp, &sc->ebp);
335 err |= __put_user((u32)regs->rsp, &sc->esp);
336 err |= __put_user((u32)regs->rbx, &sc->ebx);
337 err |= __put_user((u32)regs->rdx, &sc->edx);
338 err |= __put_user((u32)regs->rcx, &sc->ecx);
339 err |= __put_user((u32)regs->rax, &sc->eax);
340 err |= __put_user((u32)regs->cs, &sc->cs);
341 err |= __put_user((u32)regs->ss, &sc->ss);
342 err |= __put_user(current->thread.trap_no, &sc->trapno);
343 err |= __put_user(current->thread.error_code, &sc->err);
344 err |= __put_user((u32)regs->rip, &sc->eip);
345 err |= __put_user((u32)regs->eflags, &sc->eflags);
346 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
347
348 tmp = save_i387_ia32(current, fpstate, regs, 0);
349 if (tmp < 0)
350 err = -EFAULT;
351 else {
352
353 current->used_math = 0;
354 stts();
355 err |= __put_user((u32)(u64)(tmp ? fpstate : NULL), &sc->fpstate);
356 }
357
358
359 err |= __put_user(mask, &sc->oldmask);
360 err |= __put_user(current->thread.cr2, &sc->cr2);
361
362 return err;
363}
364
365
366
367
368static inline void *
369get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
370{
371 unsigned long rsp;
372
373
374 rsp = regs->rsp;
375
376
377 if (ka->sa.sa_flags & SA_ONSTACK) {
378 if (! on_sig_stack(rsp))
379 rsp = current->sas_ss_sp + current->sas_ss_size;
380 }
381
382
383 else if ((regs->ss & 0xffff) != __USER_DS &&
384 !(ka->sa.sa_flags & SA_RESTORER) &&
385 ka->sa.sa_restorer) {
386 rsp = (unsigned long) ka->sa.sa_restorer;
387 }
388
389 return (void *)((rsp - frame_size) & -8UL);
390}
391
392void ia32_setup_frame(int sig, struct k_sigaction *ka,
393 sigset32_t *set, struct pt_regs * regs)
394{
395 struct sigframe *frame;
396 int err = 0;
397
398 frame = get_sigframe(ka, regs, sizeof(*frame));
399
400 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
401 goto give_sigsegv;
402
403 err |= __put_user((current->exec_domain
404 && current->exec_domain->signal_invmap
405 && sig < 32
406 ? current->exec_domain->signal_invmap[sig]
407 : sig),
408 &frame->sig);
409 if (err)
410 goto give_sigsegv;
411
412 err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
413 if (err)
414 goto give_sigsegv;
415
416 if (_IA32_NSIG_WORDS > 1) {
417 err |= __copy_to_user(frame->extramask, &set->sig[1],
418 sizeof(frame->extramask));
419 }
420 if (err)
421 goto give_sigsegv;
422
423
424
425 if (ka->sa.sa_flags & SA_RESTORER) {
426 err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
427 } else {
428 err |= __put_user((u32)(u64)frame->retcode, &frame->pretcode);
429
430 err |= __put_user((u16)0xb858, (short *)(frame->retcode+0));
431 err |= __put_user((u32)__NR_ia32_sigreturn, (int *)(frame->retcode+2));
432 err |= __put_user((u16)0x80cd, (short *)(frame->retcode+6));
433 }
434
435 if (err)
436 goto give_sigsegv;
437
438
439 regs->rsp = (unsigned long) frame;
440 regs->rip = (unsigned long) ka->sa.sa_handler;
441
442 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
443 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
444
445 regs->cs = __USER32_CS;
446 regs->ss = __USER32_DS;
447
448 set_fs(USER_DS);
449 regs->eflags &= ~TF_MASK;
450
451#if DEBUG_SIG
452 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
453 current->comm, current->pid, frame, regs->rip, frame->pretcode);
454#endif
455
456 return;
457
458give_sigsegv:
459 if (sig == SIGSEGV)
460 ka->sa.sa_handler = SIG_DFL;
461 signal_fault(regs,frame,"32bit signal deliver");
462}
463
464void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
465 sigset32_t *set, struct pt_regs * regs)
466{
467 struct rt_sigframe *frame;
468 int err = 0;
469
470 frame = get_sigframe(ka, regs, sizeof(*frame));
471
472 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
473 goto give_sigsegv;
474
475 err |= __put_user((current->exec_domain
476 && current->exec_domain->signal_invmap
477 && sig < 32
478 ? current->exec_domain->signal_invmap[sig]
479 : sig),
480 &frame->sig);
481 err |= __put_user((u32)(u64)&frame->info, &frame->pinfo);
482 err |= __put_user((u32)(u64)&frame->uc, &frame->puc);
483 err |= ia32_copy_siginfo_to_user(&frame->info, info);
484 if (err)
485 goto give_sigsegv;
486
487
488 err |= __put_user(0, &frame->uc.uc_flags);
489 err |= __put_user(0, &frame->uc.uc_link);
490 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
491 err |= __put_user(sas_ss_flags(regs->rsp),
492 &frame->uc.uc_stack.ss_flags);
493 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
494 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
495 regs, set->sig[0]);
496 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
497 if (err)
498 goto give_sigsegv;
499
500
501
502 if (ka->sa.sa_flags & SA_RESTORER) {
503 err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
504 } else {
505 err |= __put_user(ptr_to_u32(frame->retcode), &frame->pretcode);
506
507 err |= __put_user(0xb8, (char *)(frame->retcode+0));
508 err |= __put_user((u32)__NR_ia32_rt_sigreturn, (int *)(frame->retcode+1));
509 err |= __put_user(0x80cd, (short *)(frame->retcode+5));
510 }
511
512 if (err)
513 goto give_sigsegv;
514
515
516 regs->rsp = (unsigned long) frame;
517 regs->rip = (unsigned long) ka->sa.sa_handler;
518
519 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
520 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
521
522 regs->cs = __USER32_CS;
523 regs->ss = __USER32_DS;
524
525 set_fs(USER_DS);
526 regs->eflags &= ~TF_MASK;
527
528#if DEBUG_SIG
529 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
530 current->comm, current->pid, frame, regs->rip, frame->pretcode);
531#endif
532
533 return;
534
535give_sigsegv:
536 if (sig == SIGSEGV)
537 ka->sa.sa_handler = SIG_DFL;
538 signal_fault(regs,frame,"32bit rt signal deliver");
539}
540
541