Skip to content

Commit 5917d21

Browse files
avagingvisor-bot
authored andcommitted
kernel: kill all pidns processes when their init terminates.
This CL fixes an issue where processes in a PID namespace were not being properly terminated when the namespace's init process exited. Previously, if a "subreaper" process existed, it would adopt the orphaned processes from the PID namespace. The correct behavior is for all processes in the PID namespace to be killed when their init process dies. The fix involves modifying findReparentTargetLocked to ensure that if the exiting process is the init process for its PID namespace, no reparenting target is returned. This leads to the termination of all other processes in the namespace. Fixes #11981 PiperOrigin-RevId: 791442773
1 parent 1fb4c08 commit 5917d21

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

pkg/sentry/kernel/task_exit.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ import (
3535
"gvisor.dev/gvisor/pkg/log"
3636
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
3737
"gvisor.dev/gvisor/pkg/sentry/seccheck"
38-
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
3938
"gvisor.dev/gvisor/pkg/waiter"
39+
40+
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
4041
)
4142

4243
// TaskExitState represents a step in the task exit path.
@@ -435,6 +436,10 @@ func (t *Task) findReparentTargetLocked() *Task {
435436
return t2
436437
}
437438

439+
if t.tg.isInitInLocked(t.PIDNamespace()) {
440+
return nil // The init process is terminating.
441+
}
442+
438443
if !t.tg.hasChildSubreaper {
439444
// No child subreaper exists. We can immediately return the
440445
// init process in this PID namespace if it exists.

test/syscalls/linux/setns.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <linux/prctl.h>
1516
#include <sched.h>
1617
#include <signal.h>
1718
#include <stdio.h>
19+
#include <sys/prctl.h>
1820
#include <sys/wait.h>
1921

2022
#include <cstdint>
@@ -96,6 +98,9 @@ TEST(SetnsTest, ChangePIDNamespace) {
9698
return 0;
9799
};
98100

101+
// Check that a subreaper doesn't affect how pidns is destroyed.
102+
ASSERT_THAT(prctl(PR_SET_CHILD_SUBREAPER, 1), SyscallSucceeds());
103+
99104
// Fork a test process in a new PID namespace, because it needs to manipulate
100105
// with reparented processes.
101106
struct clone_arg {
@@ -139,6 +144,8 @@ TEST(SetnsTest, ChangePIDNamespace) {
139144
ASSERT_THAT(RetryEINTR(waitpid)(pid, &status, 0),
140145
SyscallSucceedsWithValue(pid));
141146
EXPECT_EQ(WEXITSTATUS(status), 5);
147+
148+
ASSERT_THAT(prctl(PR_SET_CHILD_SUBREAPER, 0), SyscallSucceeds());
142149
}
143150

144151
} // namespace

0 commit comments

Comments
 (0)