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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/brand/lx/lx_brand/common/signal.c
          +++ new/usr/src/lib/brand/lx/lx_brand/common/signal.c
↓ open down ↓ 1549 lines elided ↑ open up ↑
1550 1550          ucontext_t uc;
1551 1551          lx_tsd_t *lxtsd = lx_get_tsd();
1552 1552          int totsz = 0;
1553 1553          uintptr_t flags;
1554 1554          uintptr_t hargs[3];
1555 1555          /*
1556 1556           * These variables must be "volatile", as they are modified after the
1557 1557           * getcontext() stores the register state:
1558 1558           */
1559 1559          volatile boolean_t signal_delivered = B_FALSE;
1560      -        volatile uintptr_t lxfp;
1561      -        volatile uintptr_t old_tsd_sp;
1562      -        volatile int newstack;
     1560 +        volatile uintptr_t lxfp = 0;
     1561 +        volatile uintptr_t old_tsd_sp = 0;
     1562 +        volatile int newstack = 0;
1563 1563  
1564 1564          /*
1565 1565           * This function involves modifying the Linux process stack for this
1566 1566           * thread.  To do so without corruption requires us to exclude other
1567 1567           * signal handlers (or emulated system calls called from within those
1568 1568           * handlers) from running while we reserve space on that stack.  We
1569 1569           * defer the execution of further instances of lx_call_user_handler()
1570 1570           * until we have completed this operation.
1571 1571           */
1572 1572          _sigoff();
↓ open down ↓ 225 lines elided ↑ open up ↑
1798 1798  
1799 1799  #if defined(_LP64)
1800 1800                  /*
1801 1801                   * Pass signal handler arguments by registers on AMD64.
1802 1802                   */
1803 1803                  LX_REG(&jump_uc, REG_RDI) = hargs[0];
1804 1804                  LX_REG(&jump_uc, REG_RSI) = hargs[1];
1805 1805                  LX_REG(&jump_uc, REG_RDX) = hargs[2];
1806 1806  #endif
1807 1807  
1808      -                if (syscall(SYS_brand, B_JUMP_TO_LINUX, &jump_uc) == -1) {
1809      -                        lx_err_fatal("B_JUMP_TO_LINUX failed: %s",
1810      -                            strerror(errno));
1811      -                }
     1808 +                lx_jump_to_linux(&jump_uc);
1812 1809          }
1813 1810  
1814 1811          assert(0);
     1812 +        abort();
1815 1813  
1816 1814  after_signal_handler:
1817 1815          /*
1818 1816           * Ensure all nested signal handlers have completed correctly
1819 1817           * and then remove our stack reservation.
1820 1818           */
1821 1819          _sigoff();
1822 1820          LX_SIGNAL_POST_HANDLER(lxfp, old_tsd_sp);
1823 1821          assert(lxtsd->lxtsd_lx_sp == lxfp);
1824 1822          lx_debug("lx_sigdeliver: after; Linux tsd sp %p -> %p\n", lxfp,
↓ open down ↓ 780 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX