소스 검색

[LibOS] Always unset SIGKILL and SIGSTOP in set_signal_mask()

POSIX guarantees that SIGKILL and SIGSTOP are silently ignored even if
supplied to sigprocmask() and co. This commit adds handling of this case.
jack.wxz 4 년 전
부모
커밋
cea63a7101

+ 6 - 1
LibOS/shim/src/bookkeep/shim_signal.c

@@ -607,9 +607,14 @@ __sigset_t * set_sig_mask (struct shim_thread * thread,
 
     assert(thread);
 
-    if (set)
+    if (set) {
         memcpy(&thread->signal_mask, set, sizeof(__sigset_t));
 
+        /* SIGKILL and SIGSTOP cannot be ignored */
+        __sigdelset(&thread->signal_mask, SIGKILL);
+        __sigdelset(&thread->signal_mask, SIGSTOP);
+    }
+
     return &thread->signal_mask;
 }
 

+ 1 - 0
LibOS/shim/test/regression/Makefile

@@ -25,6 +25,7 @@ CFLAGS-abort_multithread = -pthread
 CFLAGS-eventfd = -pthread
 CFLAGS-futex = -pthread
 CFLAGS-spinlock += -I$(PALDIR)/../lib -pthread
+CFLAGS-sigprocmask += -pthread
 
 %: %.c
 	$(call cmd,csingle)

+ 51 - 0
LibOS/shim/test/regression/sigprocmask.c

@@ -0,0 +1,51 @@
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void* thread_func(void* arg)
+{
+    exit(113);
+    return NULL;
+}
+
+int main(int argc, char* argv[])
+{
+    sigset_t newmask;
+    sigset_t oldmask;
+    sigemptyset(&newmask);
+    sigemptyset(&oldmask);
+    sigaddset(&newmask, SIGKILL);
+    sigaddset(&newmask, SIGSTOP);
+
+    int ret = sigprocmask(SIG_SETMASK, &newmask, NULL);
+
+    if (ret < 0) {
+        perror("sigprocmask failed");
+        return -1;
+    }
+
+    ret = sigprocmask(SIG_SETMASK, NULL, &oldmask);
+    if (ret < 0) {
+        perror("sigprocmask failed");
+        return -1;
+    }
+
+    if (sigismember(&oldmask, SIGKILL) || sigismember(&oldmask, SIGSTOP)) {
+        printf("SIGKILL or SIGSTOP should be ignored, but not.\n");
+        return -1;
+    }
+
+    pthread_t thread;
+    ret = pthread_create(&thread, NULL, thread_func, NULL);
+    if (ret < 0) {
+        perror("pthread_create failed");
+        return -1;
+    }
+
+    while(1)
+        sleep(1);
+
+    return -1;
+}

+ 4 - 0
LibOS/shim/test/regression/test_libos.py

@@ -140,6 +140,10 @@ class TC_01_Bootstrap(RegressionTestCase):
         with self.expect_returncode(134):
             self.run_binary(['abort_multithread'])
 
+    def test_404_sigprocmask(self):
+        with self.expect_returncode(113):
+            self.run_binary(['sigprocmask'])
+
     def test_500_init_fail(self):
         try:
             self.run_binary(['init_fail'])