Skip to content

Commit aea52d0

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 067b833 commit aea52d0

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
@@ -848,8 +848,10 @@ void nsexec(void)
848848
bail("unable to spawn stage-1");
849849

850850
syncfd = sync_child_pipe[1];
851-
if (close(sync_child_pipe[0]) < 0)
851+
if (close(sync_child_pipe[0]) < 0) {
852+
sane_kill(stage1_pid, SIGKILL);
852853
bail("failed to close sync_child_pipe[0] fd");
854+
}
853855

854856
/*
855857
* State machine for synchronisation with the children. We only
@@ -860,8 +862,11 @@ void nsexec(void)
860862
while (!stage1_complete) {
861863
enum sync_t s;
862864

863-
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
865+
if (read(syncfd, &s, sizeof(s)) != sizeof(s)) {
866+
sane_kill(stage1_pid, SIGKILL);
867+
sane_kill(stage2_pid, SIGKILL);
864868
bail("failed to sync with stage-1: next state");
869+
}
865870

866871
switch (s) {
867872
case SYNC_USERMAP_PLS:
@@ -887,7 +892,6 @@ void nsexec(void)
887892
s = SYNC_USERMAP_ACK;
888893
if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
889894
sane_kill(stage1_pid, SIGKILL);
890-
sane_kill(stage2_pid, SIGKILL);
891895
bail("failed to sync with stage-1: write(SYNC_USERMAP_ACK)");
892896
}
893897
break;
@@ -938,17 +942,22 @@ void nsexec(void)
938942
case SYNC_CHILD_FINISH:
939943
write_log(DEBUG, "stage-1 complete");
940944
stage1_complete = true;
945+
stage1_pid = -1;
941946
break;
942947
default:
948+
sane_kill(stage1_pid, SIGKILL);
949+
sane_kill(stage2_pid, SIGKILL);
943950
bailx("unexpected sync value: %u", s);
944951
}
945952
}
946953
write_log(DEBUG, "<- stage-1 synchronisation loop");
947954

948955
/* Now sync with grandchild. */
949956
syncfd = sync_grandchild_pipe[1];
950-
if (close(sync_grandchild_pipe[0]) < 0)
957+
if (close(sync_grandchild_pipe[0]) < 0) {
958+
sane_kill(stage2_pid, SIGKILL);
951959
bail("failed to close sync_grandchild_pipe[0] fd");
960+
}
952961

953962
write_log(DEBUG, "-> stage-2 synchronisation loop");
954963
stage2_complete = false;
@@ -962,15 +971,19 @@ void nsexec(void)
962971
bail("failed to sync with child: write(SYNC_GRANDCHILD)");
963972
}
964973

965-
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
974+
if (read(syncfd, &s, sizeof(s)) != sizeof(s)) {
975+
sane_kill(stage2_pid, SIGKILL);
966976
bail("failed to sync with child: next state");
977+
}
967978

968979
switch (s) {
969980
case SYNC_CHILD_FINISH:
970981
write_log(DEBUG, "stage-2 complete");
971982
stage2_complete = true;
983+
stage2_pid = -1;
972984
break;
973985
default:
986+
sane_kill(stage2_pid, SIGKILL);
974987
bailx("unexpected sync value: %u", s);
975988
}
976989
}

0 commit comments

Comments
 (0)