diff options
Diffstat (limited to 'kernel/signal.c')
| -rw-r--r-- | kernel/signal.c | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index e1d7ad8e6ab1..99fa8ff06fd9 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -688,6 +688,48 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *in | |||
| 688 | } | 688 | } |
| 689 | EXPORT_SYMBOL_GPL(dequeue_signal); | 689 | EXPORT_SYMBOL_GPL(dequeue_signal); |
| 690 | 690 | ||
| 691 | static int dequeue_synchronous_signal(kernel_siginfo_t *info) | ||
| 692 | { | ||
| 693 | struct task_struct *tsk = current; | ||
| 694 | struct sigpending *pending = &tsk->pending; | ||
| 695 | struct sigqueue *q, *sync = NULL; | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Might a synchronous signal be in the queue? | ||
| 699 | */ | ||
| 700 | if (!((pending->signal.sig[0] & ~tsk->blocked.sig[0]) & SYNCHRONOUS_MASK)) | ||
| 701 | return 0; | ||
| 702 | |||
| 703 | /* | ||
| 704 | * Return the first synchronous signal in the queue. | ||
| 705 | */ | ||
| 706 | list_for_each_entry(q, &pending->list, list) { | ||
| 707 | /* Synchronous signals have a postive si_code */ | ||
| 708 | if ((q->info.si_code > SI_USER) && | ||
| 709 | (sigmask(q->info.si_signo) & SYNCHRONOUS_MASK)) { | ||
| 710 | sync = q; | ||
| 711 | goto next; | ||
| 712 | } | ||
| 713 | } | ||
| 714 | return 0; | ||
| 715 | next: | ||
| 716 | /* | ||
| 717 | * Check if there is another siginfo for the same signal. | ||
| 718 | */ | ||
| 719 | list_for_each_entry_continue(q, &pending->list, list) { | ||
| 720 | if (q->info.si_signo == sync->info.si_signo) | ||
| 721 | goto still_pending; | ||
| 722 | } | ||
| 723 | |||
| 724 | sigdelset(&pending->signal, sync->info.si_signo); | ||
| 725 | recalc_sigpending(); | ||
| 726 | still_pending: | ||
| 727 | list_del_init(&sync->list); | ||
| 728 | copy_siginfo(info, &sync->info); | ||
| 729 | __sigqueue_free(sync); | ||
| 730 | return info->si_signo; | ||
| 731 | } | ||
| 732 | |||
| 691 | /* | 733 | /* |
| 692 | * Tell a process that it has a new active signal.. | 734 | * Tell a process that it has a new active signal.. |
| 693 | * | 735 | * |
| @@ -1057,10 +1099,9 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc | |||
| 1057 | 1099 | ||
| 1058 | result = TRACE_SIGNAL_DELIVERED; | 1100 | result = TRACE_SIGNAL_DELIVERED; |
| 1059 | /* | 1101 | /* |
| 1060 | * Skip useless siginfo allocation for SIGKILL SIGSTOP, | 1102 | * Skip useless siginfo allocation for SIGKILL and kernel threads. |
| 1061 | * and kernel threads. | ||
| 1062 | */ | 1103 | */ |
| 1063 | if (sig_kernel_only(sig) || (t->flags & PF_KTHREAD)) | 1104 | if ((sig == SIGKILL) || (t->flags & PF_KTHREAD)) |
| 1064 | goto out_set; | 1105 | goto out_set; |
| 1065 | 1106 | ||
| 1066 | /* | 1107 | /* |
| @@ -2394,6 +2435,11 @@ relock: | |||
| 2394 | goto relock; | 2435 | goto relock; |
| 2395 | } | 2436 | } |
| 2396 | 2437 | ||
| 2438 | /* Has this task already been marked for death? */ | ||
| 2439 | ksig->info.si_signo = signr = SIGKILL; | ||
| 2440 | if (signal_group_exit(signal)) | ||
| 2441 | goto fatal; | ||
| 2442 | |||
| 2397 | for (;;) { | 2443 | for (;;) { |
| 2398 | struct k_sigaction *ka; | 2444 | struct k_sigaction *ka; |
| 2399 | 2445 | ||
| @@ -2407,7 +2453,15 @@ relock: | |||
| 2407 | goto relock; | 2453 | goto relock; |
| 2408 | } | 2454 | } |
| 2409 | 2455 | ||
| 2410 | signr = dequeue_signal(current, ¤t->blocked, &ksig->info); | 2456 | /* |
| 2457 | * Signals generated by the execution of an instruction | ||
| 2458 | * need to be delivered before any other pending signals | ||
| 2459 | * so that the instruction pointer in the signal stack | ||
| 2460 | * frame points to the faulting instruction. | ||
| 2461 | */ | ||
| 2462 | signr = dequeue_synchronous_signal(&ksig->info); | ||
| 2463 | if (!signr) | ||
| 2464 | signr = dequeue_signal(current, ¤t->blocked, &ksig->info); | ||
| 2411 | 2465 | ||
| 2412 | if (!signr) | 2466 | if (!signr) |
| 2413 | break; /* will return 0 */ | 2467 | break; /* will return 0 */ |
| @@ -2489,6 +2543,7 @@ relock: | |||
| 2489 | continue; | 2543 | continue; |
| 2490 | } | 2544 | } |
| 2491 | 2545 | ||
| 2546 | fatal: | ||
| 2492 | spin_unlock_irq(&sighand->siglock); | 2547 | spin_unlock_irq(&sighand->siglock); |
| 2493 | 2548 | ||
| 2494 | /* | 2549 | /* |
