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 tag 'signal-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull ptrace update from Eric Biederman:
"ptrace: Stop supporting SIGKILL for PTRACE_EVENT_EXIT

Recently I had a conversation where it was pointed out to me that
SIGKILL sent to a tracee stropped in PTRACE_EVENT_EXIT is quite
difficult for a tracer to handle.

Keeping SIGKILL working after the process has been killed is pain from
an implementation point of view.

So since the debuggers don't want this behavior let's see if we can
remove this wart for the userspace API

If a regression is detected it should only need to be the last change
that is the reverted. The other two are just general cleanups that
make the last patch simpler"

* tag 'signal-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
signal: Drop signals received after a fatal signal has been processed
signal: Guarantee that SIGNAL_GROUP_EXIT is set on process exit
signal: Ensure SIGNAL_GROUP_EXIT gets set in do_group_exit

+25 -3
+1 -1
fs/coredump.c
··· 354 354 struct task_struct *t; 355 355 int nr = 0; 356 356 357 - /* ignore all signals except SIGKILL, see prepare_signal() */ 357 + /* Allow SIGKILL, see prepare_signal() */ 358 358 start->signal->flags = SIGNAL_GROUP_EXIT; 359 359 start->signal->group_exit_code = exit_code; 360 360 start->signal->group_stop_count = 0;
+1
include/linux/sched/signal.h
··· 94 94 refcount_t sigcnt; 95 95 atomic_t live; 96 96 int nr_threads; 97 + int quick_threads; 97 98 struct list_head thread_head; 98 99 99 100 wait_queue_head_t wait_chldexit; /* for wait4() */
+19 -1
kernel/exit.c
··· 733 733 static inline void check_stack_usage(void) {} 734 734 #endif 735 735 736 + static void synchronize_group_exit(struct task_struct *tsk, long code) 737 + { 738 + struct sighand_struct *sighand = tsk->sighand; 739 + struct signal_struct *signal = tsk->signal; 740 + 741 + spin_lock_irq(&sighand->siglock); 742 + signal->quick_threads--; 743 + if ((signal->quick_threads == 0) && 744 + !(signal->flags & SIGNAL_GROUP_EXIT)) { 745 + signal->flags = SIGNAL_GROUP_EXIT; 746 + signal->group_exit_code = code; 747 + signal->group_stop_count = 0; 748 + } 749 + spin_unlock_irq(&sighand->siglock); 750 + } 751 + 736 752 void __noreturn do_exit(long code) 737 753 { 738 754 struct task_struct *tsk = current; 739 755 int group_dead; 756 + 757 + synchronize_group_exit(tsk, code); 740 758 741 759 WARN_ON(tsk->plug); 742 760 ··· 923 905 exit_code = sig->group_exit_code; 924 906 else if (sig->group_exec_task) 925 907 exit_code = 0; 926 - else if (!thread_group_empty(current)) { 908 + else { 927 909 struct sighand_struct *const sighand = current->sighand; 928 910 929 911 spin_lock_irq(&sighand->siglock);
+2
kernel/fork.c
··· 1693 1693 return -ENOMEM; 1694 1694 1695 1695 sig->nr_threads = 1; 1696 + sig->quick_threads = 1; 1696 1697 atomic_set(&sig->live, 1); 1697 1698 refcount_set(&sig->sigcnt, 1); 1698 1699 ··· 2461 2460 __this_cpu_inc(process_counts); 2462 2461 } else { 2463 2462 current->signal->nr_threads++; 2463 + current->signal->quick_threads++; 2464 2464 atomic_inc(&current->signal->live); 2465 2465 refcount_inc(&current->signal->sigcnt); 2466 2466 task_join_group_stop(p);
+2 -1
kernel/signal.c
··· 913 913 if (signal->core_state) 914 914 return sig == SIGKILL; 915 915 /* 916 - * The process is in the middle of dying, nothing to do. 916 + * The process is in the middle of dying, drop the signal. 917 917 */ 918 + return false; 918 919 } else if (sig_kernel_stop(sig)) { 919 920 /* 920 921 * This is a stop signal. Remove SIGCONT from all queues.