Skip to content

Commit 3a88f69

Browse files
committed
libct/nsenter: sprinkle missing sane_kill
Add a few missing sane_kill calls where they make sense. Remove one useless sane_kill of stage2_pid, as during SYNC_USERMAP stage2 is not yet started. It is harmless yet it makes the code slightly harder to read. Set the child pid to -1 upon receiving SYNC_CHILD_FINISH to minimize the chances of killing an unrelated process. When a child sends SYNC_CHILD_FINISH it is about to exit (although theoretically it could be stuck during debug logging). Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent a82c14b commit 3a88f69

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

libcontainer/nsenter/nsexec.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,10 @@ void nsexec(void)
851851
bail("unable to spawn stage-1");
852852

853853
syncfd = sync_child_pipe[1];
854-
if (close(sync_child_pipe[0]) < 0)
854+
if (close(sync_child_pipe[0]) < 0) {
855+
sane_kill(stage1_pid, SIGKILL);
855856
bail("failed to close sync_child_pipe[0] fd");
857+
}
856858

857859
/*
858860
* State machine for synchronisation with the children. We only
@@ -863,8 +865,11 @@ void nsexec(void)
863865
while (!stage1_complete) {
864866
enum sync_t s;
865867

866-
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
868+
if (read(syncfd, &s, sizeof(s)) != sizeof(s)) {
869+
sane_kill(stage1_pid, SIGKILL);
870+
sane_kill(stage2_pid, SIGKILL);
867871
bail("failed to sync with stage-1: next state");
872+
}
868873

869874
switch (s) {
870875
case SYNC_USERMAP_PLS:
@@ -890,7 +895,6 @@ void nsexec(void)
890895
s = SYNC_USERMAP_ACK;
891896
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
892897
sane_kill(stage1_pid, SIGKILL);
893-
sane_kill(stage2_pid, SIGKILL);
894898
bail("failed to sync with stage-1: write(SYNC_USERMAP_ACK)");
895899
}
896900
break;
@@ -941,17 +945,22 @@ void nsexec(void)
941945
case SYNC_CHILD_FINISH:
942946
write_log(DEBUG, "stage-1 complete");
943947
stage1_complete = true;
948+
stage1_pid = -1;
944949
break;
945950
default:
951+
sane_kill(stage1_pid, SIGKILL);
952+
sane_kill(stage2_pid, SIGKILL);
946953
bailx("unexpected sync value: %u", s);
947954
}
948955
}
949956
write_log(DEBUG, "<- stage-1 synchronisation loop");
950957

951958
/* Now sync with grandchild. */
952959
syncfd = sync_grandchild_pipe[1];
953-
if (close(sync_grandchild_pipe[0]) < 0)
960+
if (close(sync_grandchild_pipe[0]) < 0) {
961+
sane_kill(stage2_pid, SIGKILL);
954962
bail("failed to close sync_grandchild_pipe[0] fd");
963+
}
955964

956965
write_log(DEBUG, "-> stage-2 synchronisation loop");
957966
stage2_complete = false;
@@ -965,15 +974,19 @@ void nsexec(void)
965974
bail("failed to sync with child: write(SYNC_GRANDCHILD)");
966975
}
967976

968-
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
977+
if (read(syncfd, &s, sizeof(s)) != sizeof(s)) {
978+
sane_kill(stage2_pid, SIGKILL);
969979
bail("failed to sync with child: next state");
980+
}
970981

971982
switch (s) {
972983
case SYNC_CHILD_FINISH:
973984
write_log(DEBUG, "stage-2 complete");
974985
stage2_complete = true;
986+
stage2_pid = -1;
975987
break;
976988
default:
989+
sane_kill(stage2_pid, SIGKILL);
977990
bailx("unexpected sync value: %u", s);
978991
}
979992
}

0 commit comments

Comments
 (0)