Print this page
OS-4470 lxbrand unblocking signals in new threads must be atomic

@@ -496,10 +496,31 @@
                 lx_err_fatal("Unable to initialize thread-specific data: %s",
                     strerror(err));
         }
 }
 
+void
+lx_jump_to_linux(ucontext_t *ucp)
+{
+        extern void setcontext_sigmask(ucontext_t *);
+
+        /*
+         * Call into this private libc interface to allow us to use only the
+         * signal mask handling part of a regular setcontext() operation.
+         */
+        setcontext_sigmask(ucp);
+
+        if (syscall(SYS_brand, B_JUMP_TO_LINUX, ucp) != 0) {
+                lx_err_fatal("B_JUMP_TO_LINUX failed: %s", strerror(errno));
+        }
+
+        /*
+         * This system call should not return.
+         */
+        abort();
+}
+
 static void
 lx_start(uintptr_t sp, uintptr_t entry)
 {
         ucontext_t jump_uc;
 

@@ -528,19 +549,11 @@
          */
         LX_REG(&jump_uc, REG_RDX) = NULL;
 #endif
 
         lx_debug("starting Linux program sp %p ldentry %p", sp, entry);
-
-        /*
-         * This system call should not return.
-         */
-        if (syscall(SYS_brand, B_JUMP_TO_LINUX, &jump_uc) == -1) {
-                lx_err_fatal("B_JUMP_TO_LINUX failed: %s",
-                    strerror(errno));
-        }
-        abort();
+        lx_jump_to_linux(&jump_uc);
 }
 
 /*ARGSUSED*/
 int
 lx_init(int argc, char *argv[], char *envp[])