diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/signal.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index ea46d028af08..344400787c39 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -346,8 +346,8 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) | |||
346 | extern void __user __kernel_sigreturn; | 346 | extern void __user __kernel_sigreturn; |
347 | extern void __user __kernel_rt_sigreturn; | 347 | extern void __user __kernel_rt_sigreturn; |
348 | 348 | ||
349 | static void setup_frame(int sig, struct k_sigaction *ka, | 349 | static int setup_frame(int sig, struct k_sigaction *ka, |
350 | sigset_t *set, struct pt_regs * regs) | 350 | sigset_t *set, struct pt_regs * regs) |
351 | { | 351 | { |
352 | void __user *restorer; | 352 | void __user *restorer; |
353 | struct sigframe __user *frame; | 353 | struct sigframe __user *frame; |
@@ -429,13 +429,14 @@ static void setup_frame(int sig, struct k_sigaction *ka, | |||
429 | current->comm, current->pid, frame, regs->eip, frame->pretcode); | 429 | current->comm, current->pid, frame, regs->eip, frame->pretcode); |
430 | #endif | 430 | #endif |
431 | 431 | ||
432 | return; | 432 | return 1; |
433 | 433 | ||
434 | give_sigsegv: | 434 | give_sigsegv: |
435 | force_sigsegv(sig, current); | 435 | force_sigsegv(sig, current); |
436 | return 0; | ||
436 | } | 437 | } |
437 | 438 | ||
438 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 439 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
439 | sigset_t *set, struct pt_regs * regs) | 440 | sigset_t *set, struct pt_regs * regs) |
440 | { | 441 | { |
441 | void __user *restorer; | 442 | void __user *restorer; |
@@ -522,20 +523,23 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
522 | current->comm, current->pid, frame, regs->eip, frame->pretcode); | 523 | current->comm, current->pid, frame, regs->eip, frame->pretcode); |
523 | #endif | 524 | #endif |
524 | 525 | ||
525 | return; | 526 | return 1; |
526 | 527 | ||
527 | give_sigsegv: | 528 | give_sigsegv: |
528 | force_sigsegv(sig, current); | 529 | force_sigsegv(sig, current); |
530 | return 0; | ||
529 | } | 531 | } |
530 | 532 | ||
531 | /* | 533 | /* |
532 | * OK, we're invoking a handler | 534 | * OK, we're invoking a handler |
533 | */ | 535 | */ |
534 | 536 | ||
535 | static void | 537 | static int |
536 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 538 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
537 | sigset_t *oldset, struct pt_regs * regs) | 539 | sigset_t *oldset, struct pt_regs * regs) |
538 | { | 540 | { |
541 | int ret; | ||
542 | |||
539 | /* Are we from a system call? */ | 543 | /* Are we from a system call? */ |
540 | if (regs->orig_eax >= 0) { | 544 | if (regs->orig_eax >= 0) { |
541 | /* If so, check system call restarting.. */ | 545 | /* If so, check system call restarting.. */ |
@@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
569 | 573 | ||
570 | /* Set up the stack frame */ | 574 | /* Set up the stack frame */ |
571 | if (ka->sa.sa_flags & SA_SIGINFO) | 575 | if (ka->sa.sa_flags & SA_SIGINFO) |
572 | setup_rt_frame(sig, ka, info, oldset, regs); | 576 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
573 | else | 577 | else |
574 | setup_frame(sig, ka, oldset, regs); | 578 | ret = setup_frame(sig, ka, oldset, regs); |
575 | 579 | ||
576 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 580 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { |
577 | spin_lock_irq(¤t->sighand->siglock); | 581 | spin_lock_irq(¤t->sighand->siglock); |
578 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 582 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
579 | sigaddset(¤t->blocked,sig); | 583 | sigaddset(¤t->blocked,sig); |
580 | recalc_sigpending(); | 584 | recalc_sigpending(); |
581 | spin_unlock_irq(¤t->sighand->siglock); | 585 | spin_unlock_irq(¤t->sighand->siglock); |
582 | } | 586 | } |
587 | |||
588 | return ret; | ||
583 | } | 589 | } |
584 | 590 | ||
585 | /* | 591 | /* |
@@ -622,8 +628,7 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
622 | } | 628 | } |
623 | 629 | ||
624 | /* Whee! Actually deliver the signal. */ | 630 | /* Whee! Actually deliver the signal. */ |
625 | handle_signal(signr, &info, &ka, oldset, regs); | 631 | return handle_signal(signr, &info, &ka, oldset, regs); |
626 | return 1; | ||
627 | } | 632 | } |
628 | 633 | ||
629 | no_signal: | 634 | no_signal: |