Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull signal fixes from Eric Biederman:
"This contains four small fixes for signal handling. A missing range
check, a regression fix, prioritizing signals we have already started
a signal group exit for, and better detection of synchronous signals.

The confused decision of which signals to handle failed spectacularly
when a timer was pointed at SIGBUS and the stack overflowed. Resulting
in an unkillable process in an infinite loop instead of a SIGSEGV and
core dump"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
signal: Better detection of synchronous signals
signal: Always notice exiting tasks
signal: Always attempt to allocate siginfo for SIGSTOP
signal: Make siginmask safe when passed a signal of 0

+60 -5
+1 -1
include/linux/signal.h
··· 392 392 #endif 393 393 394 394 #define siginmask(sig, mask) \ 395 - ((sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) 395 + ((sig) > 0 && (sig) < SIGRTMIN && (rt_sigmask(sig) & (mask))) 396 396 397 397 #define SIG_KERNEL_ONLY_MASK (\ 398 398 rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
+59 -4
kernel/signal.c
··· 688 688 } 689 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 734 * Tell a process that it has a new active signal.. 693 735 * ··· 1099 1057 1100 1058 result = TRACE_SIGNAL_DELIVERED; 1101 1059 /* 1102 - * Skip useless siginfo allocation for SIGKILL SIGSTOP, 1103 - * and kernel threads. 1060 + * Skip useless siginfo allocation for SIGKILL and kernel threads. 1104 1061 */ 1105 - if (sig_kernel_only(sig) || (t->flags & PF_KTHREAD)) 1062 + if ((sig == SIGKILL) || (t->flags & PF_KTHREAD)) 1106 1063 goto out_set; 1107 1064 1108 1065 /* ··· 2435 2394 goto relock; 2436 2395 } 2437 2396 2397 + /* Has this task already been marked for death? */ 2398 + ksig->info.si_signo = signr = SIGKILL; 2399 + if (signal_group_exit(signal)) 2400 + goto fatal; 2401 + 2438 2402 for (;;) { 2439 2403 struct k_sigaction *ka; 2440 2404 ··· 2453 2407 goto relock; 2454 2408 } 2455 2409 2456 - signr = dequeue_signal(current, &current->blocked, &ksig->info); 2410 + /* 2411 + * Signals generated by the execution of an instruction 2412 + * need to be delivered before any other pending signals 2413 + * so that the instruction pointer in the signal stack 2414 + * frame points to the faulting instruction. 2415 + */ 2416 + signr = dequeue_synchronous_signal(&ksig->info); 2417 + if (!signr) 2418 + signr = dequeue_signal(current, &current->blocked, &ksig->info); 2457 2419 2458 2420 if (!signr) 2459 2421 break; /* will return 0 */ ··· 2543 2489 continue; 2544 2490 } 2545 2491 2492 + fatal: 2546 2493 spin_unlock_irq(&sighand->siglock); 2547 2494 2548 2495 /*