aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/signal_32.c')
-rw-r--r--arch/x86/kernel/signal_32.c222
1 files changed, 134 insertions, 88 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index b21070ea33a4..d6dd057d0f22 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -27,6 +27,7 @@
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <asm/i387.h> 28#include <asm/i387.h>
29#include <asm/vdso.h> 29#include <asm/vdso.h>
30#include <asm/syscall.h>
30#include <asm/syscalls.h> 31#include <asm/syscalls.h>
31 32
32#include "sigframe.h" 33#include "sigframe.h"
@@ -112,6 +113,27 @@ asmlinkage int sys_sigaltstack(unsigned long bx)
112 return do_sigaltstack(uss, uoss, regs->sp); 113 return do_sigaltstack(uss, uoss, regs->sp);
113} 114}
114 115
116#define COPY(x) { \
117 err |= __get_user(regs->x, &sc->x); \
118}
119
120#define COPY_SEG(seg) { \
121 unsigned short tmp; \
122 err |= __get_user(tmp, &sc->seg); \
123 regs->seg = tmp; \
124}
125
126#define COPY_SEG_STRICT(seg) { \
127 unsigned short tmp; \
128 err |= __get_user(tmp, &sc->seg); \
129 regs->seg = tmp | 3; \
130}
131
132#define GET_SEG(seg) { \
133 unsigned short tmp; \
134 err |= __get_user(tmp, &sc->seg); \
135 loadsegment(seg, tmp); \
136}
115 137
116/* 138/*
117 * Do a signal return; undo the signal stack. 139 * Do a signal return; undo the signal stack.
@@ -120,28 +142,13 @@ static int
120restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, 142restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
121 unsigned long *pax) 143 unsigned long *pax)
122{ 144{
145 void __user *buf;
146 unsigned int tmpflags;
123 unsigned int err = 0; 147 unsigned int err = 0;
124 148
125 /* Always make any pending restarted system calls return -EINTR */ 149 /* Always make any pending restarted system calls return -EINTR */
126 current_thread_info()->restart_block.fn = do_no_restart_syscall; 150 current_thread_info()->restart_block.fn = do_no_restart_syscall;
127 151
128#define COPY(x) err |= __get_user(regs->x, &sc->x)
129
130#define COPY_SEG(seg) \
131 { unsigned short tmp; \
132 err |= __get_user(tmp, &sc->seg); \
133 regs->seg = tmp; }
134
135#define COPY_SEG_STRICT(seg) \
136 { unsigned short tmp; \
137 err |= __get_user(tmp, &sc->seg); \
138 regs->seg = tmp|3; }
139
140#define GET_SEG(seg) \
141 { unsigned short tmp; \
142 err |= __get_user(tmp, &sc->seg); \
143 loadsegment(seg, tmp); }
144
145 GET_SEG(gs); 152 GET_SEG(gs);
146 COPY_SEG(fs); 153 COPY_SEG(fs);
147 COPY_SEG(es); 154 COPY_SEG(es);
@@ -151,21 +158,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
151 COPY_SEG_STRICT(cs); 158 COPY_SEG_STRICT(cs);
152 COPY_SEG_STRICT(ss); 159 COPY_SEG_STRICT(ss);
153 160
154 { 161 err |= __get_user(tmpflags, &sc->flags);
155 unsigned int tmpflags; 162 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
156 163 regs->orig_ax = -1; /* disable syscall checks */
157 err |= __get_user(tmpflags, &sc->flags);
158 regs->flags = (regs->flags & ~FIX_EFLAGS) |
159 (tmpflags & FIX_EFLAGS);
160 regs->orig_ax = -1; /* disable syscall checks */
161 }
162
163 {
164 void __user *buf;
165 164
166 err |= __get_user(buf, &sc->fpstate); 165 err |= __get_user(buf, &sc->fpstate);
167 err |= restore_i387_xstate(buf); 166 err |= restore_i387_xstate(buf);
168 }
169 167
170 err |= __get_user(*pax, &sc->ax); 168 err |= __get_user(*pax, &sc->ax);
171 return err; 169 return err;
@@ -214,9 +212,8 @@ badframe:
214 return 0; 212 return 0;
215} 213}
216 214
217asmlinkage int sys_rt_sigreturn(unsigned long __unused) 215static long do_rt_sigreturn(struct pt_regs *regs)
218{ 216{
219 struct pt_regs *regs = (struct pt_regs *)&__unused;
220 struct rt_sigframe __user *frame; 217 struct rt_sigframe __user *frame;
221 unsigned long ax; 218 unsigned long ax;
222 sigset_t set; 219 sigset_t set;
@@ -242,10 +239,17 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
242 return ax; 239 return ax;
243 240
244badframe: 241badframe:
245 force_sig(SIGSEGV, current); 242 signal_fault(regs, frame, "rt_sigreturn");
246 return 0; 243 return 0;
247} 244}
248 245
246asmlinkage int sys_rt_sigreturn(unsigned long __unused)
247{
248 struct pt_regs *regs = (struct pt_regs *)&__unused;
249
250 return do_rt_sigreturn(regs);
251}
252
249/* 253/*
250 * Set up a signal frame. 254 * Set up a signal frame.
251 */ 255 */
@@ -337,39 +341,29 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
337} 341}
338 342
339static int 343static int
340setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, 344__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
341 struct pt_regs *regs) 345 struct pt_regs *regs)
342{ 346{
343 struct sigframe __user *frame; 347 struct sigframe __user *frame;
344 void __user *restorer; 348 void __user *restorer;
345 int err = 0; 349 int err = 0;
346 int usig;
347 void __user *fpstate = NULL; 350 void __user *fpstate = NULL;
348 351
349 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); 352 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
350 353
351 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 354 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
352 goto give_sigsegv; 355 return -EFAULT;
353 356
354 usig = current_thread_info()->exec_domain 357 if (__put_user(sig, &frame->sig))
355 && current_thread_info()->exec_domain->signal_invmap 358 return -EFAULT;
356 && sig < 32
357 ? current_thread_info()->exec_domain->signal_invmap[sig]
358 : sig;
359 359
360 err = __put_user(usig, &frame->sig); 360 if (setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
361 if (err) 361 return -EFAULT;
362 goto give_sigsegv;
363
364 err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
365 if (err)
366 goto give_sigsegv;
367 362
368 if (_NSIG_WORDS > 1) { 363 if (_NSIG_WORDS > 1) {
369 err = __copy_to_user(&frame->extramask, &set->sig[1], 364 if (__copy_to_user(&frame->extramask, &set->sig[1],
370 sizeof(frame->extramask)); 365 sizeof(frame->extramask)))
371 if (err) 366 return -EFAULT;
372 goto give_sigsegv;
373 } 367 }
374 368
375 if (current->mm->context.vdso) 369 if (current->mm->context.vdso)
@@ -394,7 +388,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
394 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); 388 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
395 389
396 if (err) 390 if (err)
397 goto give_sigsegv; 391 return -EFAULT;
398 392
399 /* Set up registers for signal handler */ 393 /* Set up registers for signal handler */
400 regs->sp = (unsigned long)frame; 394 regs->sp = (unsigned long)frame;
@@ -409,38 +403,27 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
409 regs->cs = __USER_CS; 403 regs->cs = __USER_CS;
410 404
411 return 0; 405 return 0;
412
413give_sigsegv:
414 force_sigsegv(sig, current);
415 return -EFAULT;
416} 406}
417 407
418static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 408static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
419 sigset_t *set, struct pt_regs *regs) 409 sigset_t *set, struct pt_regs *regs)
420{ 410{
421 struct rt_sigframe __user *frame; 411 struct rt_sigframe __user *frame;
422 void __user *restorer; 412 void __user *restorer;
423 int err = 0; 413 int err = 0;
424 int usig;
425 void __user *fpstate = NULL; 414 void __user *fpstate = NULL;
426 415
427 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate); 416 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
428 417
429 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 418 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
430 goto give_sigsegv; 419 return -EFAULT;
431
432 usig = current_thread_info()->exec_domain
433 && current_thread_info()->exec_domain->signal_invmap
434 && sig < 32
435 ? current_thread_info()->exec_domain->signal_invmap[sig]
436 : sig;
437 420
438 err |= __put_user(usig, &frame->sig); 421 err |= __put_user(sig, &frame->sig);
439 err |= __put_user(&frame->info, &frame->pinfo); 422 err |= __put_user(&frame->info, &frame->pinfo);
440 err |= __put_user(&frame->uc, &frame->puc); 423 err |= __put_user(&frame->uc, &frame->puc);
441 err |= copy_siginfo_to_user(&frame->info, info); 424 err |= copy_siginfo_to_user(&frame->info, info);
442 if (err) 425 if (err)
443 goto give_sigsegv; 426 return -EFAULT;
444 427
445 /* Create the ucontext. */ 428 /* Create the ucontext. */
446 if (cpu_has_xsave) 429 if (cpu_has_xsave)
@@ -456,7 +439,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
456 regs, set->sig[0]); 439 regs, set->sig[0]);
457 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 440 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
458 if (err) 441 if (err)
459 goto give_sigsegv; 442 return -EFAULT;
460 443
461 /* Set up to return from userspace. */ 444 /* Set up to return from userspace. */
462 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn); 445 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -476,12 +459,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
476 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); 459 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
477 460
478 if (err) 461 if (err)
479 goto give_sigsegv; 462 return -EFAULT;
480 463
481 /* Set up registers for signal handler */ 464 /* Set up registers for signal handler */
482 regs->sp = (unsigned long)frame; 465 regs->sp = (unsigned long)frame;
483 regs->ip = (unsigned long)ka->sa.sa_handler; 466 regs->ip = (unsigned long)ka->sa.sa_handler;
484 regs->ax = (unsigned long)usig; 467 regs->ax = (unsigned long)sig;
485 regs->dx = (unsigned long)&frame->info; 468 regs->dx = (unsigned long)&frame->info;
486 regs->cx = (unsigned long)&frame->uc; 469 regs->cx = (unsigned long)&frame->uc;
487 470
@@ -491,15 +474,48 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
491 regs->cs = __USER_CS; 474 regs->cs = __USER_CS;
492 475
493 return 0; 476 return 0;
494
495give_sigsegv:
496 force_sigsegv(sig, current);
497 return -EFAULT;
498} 477}
499 478
500/* 479/*
501 * OK, we're invoking a handler: 480 * OK, we're invoking a handler:
502 */ 481 */
482static int signr_convert(int sig)
483{
484 struct thread_info *info = current_thread_info();
485
486 if (info->exec_domain && info->exec_domain->signal_invmap && sig < 32)
487 return info->exec_domain->signal_invmap[sig];
488 return sig;
489}
490
491#define is_ia32 1
492#define ia32_setup_frame __setup_frame
493#define ia32_setup_rt_frame __setup_rt_frame
494
495static int
496setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
497 sigset_t *set, struct pt_regs *regs)
498{
499 int usig = signr_convert(sig);
500 int ret;
501
502 /* Set up the stack frame */
503 if (is_ia32) {
504 if (ka->sa.sa_flags & SA_SIGINFO)
505 ret = ia32_setup_rt_frame(usig, ka, info, set, regs);
506 else
507 ret = ia32_setup_frame(usig, ka, set, regs);
508 } else
509 ret = __setup_rt_frame(sig, ka, info, set, regs);
510
511 if (ret) {
512 force_sigsegv(sig, current);
513 return -EFAULT;
514 }
515
516 return ret;
517}
518
503static int 519static int
504handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 520handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
505 sigset_t *oldset, struct pt_regs *regs) 521 sigset_t *oldset, struct pt_regs *regs)
@@ -507,9 +523,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
507 int ret; 523 int ret;
508 524
509 /* Are we from a system call? */ 525 /* Are we from a system call? */
510 if ((long)regs->orig_ax >= 0) { 526 if (syscall_get_nr(current, regs) >= 0) {
511 /* If so, check system call restarting.. */ 527 /* If so, check system call restarting.. */
512 switch (regs->ax) { 528 switch (syscall_get_error(current, regs)) {
513 case -ERESTART_RESTARTBLOCK: 529 case -ERESTART_RESTARTBLOCK:
514 case -ERESTARTNOHAND: 530 case -ERESTARTNOHAND:
515 regs->ax = -EINTR; 531 regs->ax = -EINTR;
@@ -536,15 +552,20 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
536 likely(test_and_clear_thread_flag(TIF_FORCED_TF))) 552 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
537 regs->flags &= ~X86_EFLAGS_TF; 553 regs->flags &= ~X86_EFLAGS_TF;
538 554
539 /* Set up the stack frame */ 555 ret = setup_rt_frame(sig, ka, info, oldset, regs);
540 if (ka->sa.sa_flags & SA_SIGINFO)
541 ret = setup_rt_frame(sig, ka, info, oldset, regs);
542 else
543 ret = setup_frame(sig, ka, oldset, regs);
544 556
545 if (ret) 557 if (ret)
546 return ret; 558 return ret;
547 559
560#ifdef CONFIG_X86_64
561 /*
562 * This has nothing to do with segment registers,
563 * despite the name. This magic affects uaccess.h
564 * macros' behavior. Reset it to the normal setting.
565 */
566 set_fs(USER_DS);
567#endif
568
548 /* 569 /*
549 * Clear the direction flag as per the ABI for function entry. 570 * Clear the direction flag as per the ABI for function entry.
550 */ 571 */
@@ -571,6 +592,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
571 return 0; 592 return 0;
572} 593}
573 594
595#define NR_restart_syscall __NR_restart_syscall
574/* 596/*
575 * Note that 'init' is a special process: it doesn't get signals it doesn't 597 * Note that 'init' is a special process: it doesn't get signals it doesn't
576 * want to handle. Thus you cannot kill init even with a SIGKILL even by 598 * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -623,9 +645,9 @@ static void do_signal(struct pt_regs *regs)
623 } 645 }
624 646
625 /* Did we come from a system call? */ 647 /* Did we come from a system call? */
626 if ((long)regs->orig_ax >= 0) { 648 if (syscall_get_nr(current, regs) >= 0) {
627 /* Restart the system call - no handlers present */ 649 /* Restart the system call - no handlers present */
628 switch (regs->ax) { 650 switch (syscall_get_error(current, regs)) {
629 case -ERESTARTNOHAND: 651 case -ERESTARTNOHAND:
630 case -ERESTARTSYS: 652 case -ERESTARTSYS:
631 case -ERESTARTNOINTR: 653 case -ERESTARTNOINTR:
@@ -634,7 +656,7 @@ static void do_signal(struct pt_regs *regs)
634 break; 656 break;
635 657
636 case -ERESTART_RESTARTBLOCK: 658 case -ERESTART_RESTARTBLOCK:
637 regs->ax = __NR_restart_syscall; 659 regs->ax = NR_restart_syscall;
638 regs->ip -= 2; 660 regs->ip -= 2;
639 break; 661 break;
640 } 662 }
@@ -657,6 +679,12 @@ static void do_signal(struct pt_regs *regs)
657void 679void
658do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) 680do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
659{ 681{
682#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
683 /* notify userspace of pending MCEs */
684 if (thread_info_flags & _TIF_MCE_NOTIFY)
685 mce_notify_user();
686#endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
687
660 /* deal with pending signal delivery */ 688 /* deal with pending signal delivery */
661 if (thread_info_flags & _TIF_SIGPENDING) 689 if (thread_info_flags & _TIF_SIGPENDING)
662 do_signal(regs); 690 do_signal(regs);
@@ -666,5 +694,23 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
666 tracehook_notify_resume(regs); 694 tracehook_notify_resume(regs);
667 } 695 }
668 696
697#ifdef CONFIG_X86_32
669 clear_thread_flag(TIF_IRET); 698 clear_thread_flag(TIF_IRET);
699#endif /* CONFIG_X86_32 */
700}
701
702void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
703{
704 struct task_struct *me = current;
705
706 if (show_unhandled_signals && printk_ratelimit()) {
707 printk(KERN_INFO
708 "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
709 me->comm, me->pid, where, frame,
710 regs->ip, regs->sp, regs->orig_ax);
711 print_vma_addr(" in ", regs->ip);
712 printk(KERN_CONT "\n");
713 }
714
715 force_sig(SIGSEGV, me);
670} 716}