[PATCH 05/17] signal: Bring down all threads when handling a non-coredump fatal signal

Eric W. Biederman posted 17 patches 1 year, 7 months ago
[PATCH 05/17] signal: Bring down all threads when handling a non-coredump fatal signal
Posted by Eric W. Biederman 1 year, 7 months ago

For non-coredump fatal signals instead of dropping and reacquiring
siglock to shoot down the other threads from do_group_exit
at the end of get_signal, shot down the other threads before
siglock is dropped.

This can not be done for coredump signals yet, because do_coredump
needs to be in a position to catch dying threads before it kills them
so it can make certain to catch them, so they can be added to the
coredump.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index caeaff81a197..269ec88f650d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2882,7 +2882,13 @@ bool get_signal(struct ksignal *ksig)
 		 * Anything else is fatal, maybe with a core dump.
 		 */
 		exit_code = signr;
-		group_exit_needed = true;
+		if (sig_kernel_coredump(signr))
+			group_exit_needed = true;
+		else {
+			signal->group_exit_code = exit_code;
+			signal->flags = SIGNAL_GROUP_EXIT;
+			zap_other_threads(current);
+		}
 	fatal:
 		spin_unlock_irq(&sighand->siglock);
 		if (unlikely(cgroup_task_frozen(current)))
-- 
2.41.0
Re: [PATCH 05/17] signal: Bring down all threads when handling a non-coredump fatal signal
Posted by Oleg Nesterov 1 year, 7 months ago
On 06/18, Eric W. Biederman wrote:
>
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2882,7 +2882,13 @@ bool get_signal(struct ksignal *ksig)
>  		 * Anything else is fatal, maybe with a core dump.
>  		 */
>  		exit_code = signr;
> -		group_exit_needed = true;
> +		if (sig_kernel_coredump(signr))
> +			group_exit_needed = true;

OK... do_coredump() can fail before coredump_wait() even if CONFIG_COREDUMP

> +		else {
> +			signal->group_exit_code = exit_code;
> +			signal->flags = SIGNAL_GROUP_EXIT;
> +			zap_other_threads(current);
> +		}

dequeue_signal() and/or ptrace_signal() can drop siglock, I think
the else branch should re-check SIGNAL_GROUP_EXIT/group_exec_task.

Oleg.