[Devel] [PATCH RHEL7 COMMIT] ms/fork: Unconditionally exit if a fatal signal is pending

Vasily Averin vvs at virtuozzo.com
Sat Jan 30 14:40:44 MSK 2021


The commit is pushed to "branch-rh7-3.10.0-1160.11.1.vz7.172.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.11.1.vz7.172.10
------>
commit 8172902f147a24c17a2fff05a82ce3a8b3f6bfe2
Author: Eric W. Biederman <ebiederm at xmission.com>
Date:   Sat Jan 30 14:40:43 2021 +0300

    ms/fork: Unconditionally exit if a fatal signal is pending
    
    In practice this does not change anything as testing for fatal_signal_pending
    and exiting for with an error code duplicates the work of the next clause
    which recalculates pending signals and then exits fork if any are pending.
    In both cases the pending signal will trigger the slow path when existing
    to userspace, and the fatal signal will cause do_exit to be called.
    
    The advantage of making this a separate test is that it makes it clear
    processing the fatal signal will terminate the fork, and it allows the
    rest of the signal logic to be updated without fear that this important
    case will be lost.
    
    Signed-off-by: "Eric W. Biederman" <ebiederm at xmission.com>
    
    After [1] we were able to see situations on a zdtm pthread-bomb.c test,
    that after leader thread exits with return 0, there are some threads
    left running non-receiving SIGKILL of thread group exit. We send SIGKILL
    to all the threads in do_group_exit -> zap_other_threads, but if one
    thread is in copy_process at this point, it can fork one more thread
    which would not get the signal.
    
    https://jira.sw.ru/browse/PSBM-124538
    
    Fixes: 056f2c6a7c8ee ("ms/fork: Have new threads join on-going signal
    group stops") [1]
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 kernel/fork.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/kernel/fork.c b/kernel/fork.c
index 7ed142f..d0f92f2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1704,6 +1704,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	 */
 	copy_seccomp(p);
 
+	/* Let kill terminate clone/fork in the middle */
+	if (fatal_signal_pending(current)) {
+		retval = -EINTR;
+		goto bad_fork_cancel_cgroup;
+	}
+
 	if (!(clone_flags & CLONE_THREAD)) {
 		/*
 		 * Process group and session signals need to be delivered to just the


More information about the Devel mailing list