From bdddc8401f68039225b69f2ff0260f7bd136df27 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Fri, 28 Aug 2020 14:16:27 -0700 Subject: [PATCH] [LibOS] Do not recursively send KILL messages via Graphene's IPC Previously, Graphene not only broadcasted the KILL_ALL message via its IPC mechanism to direct children and the parent (and they broadcasted to their children and parents in turn), but also sent additional KILL messages to all processes. These additional KILL messages triggered the FINDNS/TELLNS IPC mechanism to find the corresponding PID leaders. However, FINDNS/TELLNS are sent with acknowledgements, forcing the sending thread to wait on futex. This led to segfaults/hangs due to recursive IPC (e.g., in Apache web server after user sends SIGINT to terminate the process). This commit fixes this bug by *not* sending additional KILL messages to other processes (the process already broadcasted KILL_ALL). --- LibOS/shim/src/ipc/shim_ipc_pid.c | 2 +- LibOS/shim/src/sys/shim_sigaction.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LibOS/shim/src/ipc/shim_ipc_pid.c b/LibOS/shim/src/ipc/shim_ipc_pid.c index 874fe055..c8532cc1 100644 --- a/LibOS/shim/src/ipc/shim_ipc_pid.c +++ b/LibOS/shim/src/ipc/shim_ipc_pid.c @@ -118,7 +118,7 @@ int ipc_pid_kill_callback(struct shim_ipc_msg* msg, struct shim_ipc_port* port) break; case KILL_ALL: broadcast_ipc(msg, IPC_PORT_DIRCLD | IPC_PORT_DIRPRT, port); - ret = do_kill_proc(msgin->sender, msgin->id, msgin->signum, true); + ret = do_kill_proc(msgin->sender, msgin->id, msgin->signum, false); break; } return ret; diff --git a/LibOS/shim/src/sys/shim_sigaction.c b/LibOS/shim/src/sys/shim_sigaction.c index 8bf21917..592de060 100644 --- a/LibOS/shim/src/sys/shim_sigaction.c +++ b/LibOS/shim/src/sys/shim_sigaction.c @@ -376,7 +376,7 @@ int shim_do_kill(pid_t pid, int sig) { /* If `pid` equals -1, then signal is sent to every process for which the calling process * has permission to send, which means all processes in Graphene. */ ipc_pid_kill_send(cur->tid, /*target=*/0, KILL_ALL, sig); - return do_kill_proc(cur->tid, cur->tgid, sig, true); + return do_kill_proc(cur->tid, cur->tgid, sig, false); } else if (pid == 0) { /* If `pid` equals 0, then signal is sent to every process in the process group of * the calling process. */