From 1df82ea88b8aad4e69d824e54f20e4af365cb934 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Tue, 16 Jun 2020 01:49:42 +0000 Subject: [PATCH] [LibOS] Do not try to send signal 0 in kill()/tkill() Previously, Graphene didn't handle special case of kill()/tkill() with signal equal to zero. This signal is used to check for existence of processes and threads. However, Graphene tried to send/append it which led to segfaults. This commit correctly handles signal equal to zero and improves LibOS tests to verify this fix. --- LibOS/shim/src/sys/shim_sigaction.c | 14 ++++++++++++++ LibOS/shim/test/regression/sigaction_per_process.c | 6 ++++++ LibOS/shim/test/regression/signal_multithread.c | 6 ++++++ 3 files changed, 26 insertions(+) diff --git a/LibOS/shim/src/sys/shim_sigaction.c b/LibOS/shim/src/sys/shim_sigaction.c index c6d4d8f1..8bf21917 100644 --- a/LibOS/shim/src/sys/shim_sigaction.c +++ b/LibOS/shim/src/sys/shim_sigaction.c @@ -245,6 +245,13 @@ static int _signal_one_thread(struct shim_thread* thread, void* _arg) { BUG(); } + if (!arg->sig) { + /* special case of sig == 0: don't really send signal but simply report success */ + arg->sent = true; + ret = 1; + goto out; + } + /* Appending the signal to the whole process. */ if (!arg->sent) { siginfo_t info = { @@ -393,6 +400,13 @@ int do_kill_thread(IDTYPE sender, IDTYPE tgid, IDTYPE tid, int sig, bool use_ipc if (thread->in_vm) { if (!tgid || thread->tgid == tgid) { + if (!sig) { + /* special case of sig == 0: don't really send signal but report success */ + unlock(&thread->lock); + put_thread(thread); + return 0; + } + siginfo_t info = { .si_signo = sig, .si_pid = sender, diff --git a/LibOS/shim/test/regression/sigaction_per_process.c b/LibOS/shim/test/regression/sigaction_per_process.c index 7c724a3d..85e90510 100644 --- a/LibOS/shim/test/regression/sigaction_per_process.c +++ b/LibOS/shim/test/regression/sigaction_per_process.c @@ -80,6 +80,12 @@ int main() { printf("parent tid: %d\n", tid); + /* the below dummy tkill (no signal is sent) is for sanity */ + if (tkill(tid, /*sig=*/0)) { + fprintf(stderr, "tkill(sig=0) failed: %m\n"); + return 1; + } + if (tkill(tid, SIGTERM)) { fprintf(stderr, "tkill failed: %m\n"); return 1; diff --git a/LibOS/shim/test/regression/signal_multithread.c b/LibOS/shim/test/regression/signal_multithread.c index c283e689..5cae5859 100644 --- a/LibOS/shim/test/regression/signal_multithread.c +++ b/LibOS/shim/test/regression/signal_multithread.c @@ -51,6 +51,12 @@ int main() { wait_for(1); + /* the below dummy kill (no signal is sent) is for sanity */ + if (kill(getpid(), /*sig=*/0)) { + fprintf(stderr, "kill(sig=0) failed: %m\n"); + return 1; + } + if (kill(getpid(), SIGTERM)) { fprintf(stderr, "kill failed: %m\n"); return 1;