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/lx_brand.c
          +++ new/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
↓ open down ↓ 490 lines elided ↑ open up ↑
 491  491           * (to the degree possible) while exiting.
 492  492           */
 493  493          (void) sigfillset(&lxtsd->lxtsd_exit_context.uc_sigmask);
 494  494  
 495  495          if ((err = thr_setspecific(lx_tsd_key, lxtsd)) != 0) {
 496  496                  lx_err_fatal("Unable to initialize thread-specific data: %s",
 497  497                      strerror(err));
 498  498          }
 499  499  }
 500  500  
      501 +void
      502 +lx_jump_to_linux(ucontext_t *ucp)
      503 +{
      504 +        extern void setcontext_sigmask(ucontext_t *);
      505 +
      506 +        /*
      507 +         * Call into this private libc interface to allow us to use only the
      508 +         * signal mask handling part of a regular setcontext() operation.
      509 +         */
      510 +        setcontext_sigmask(ucp);
      511 +
      512 +        if (syscall(SYS_brand, B_JUMP_TO_LINUX, ucp) != 0) {
      513 +                lx_err_fatal("B_JUMP_TO_LINUX failed: %s", strerror(errno));
      514 +        }
      515 +
      516 +        /*
      517 +         * This system call should not return.
      518 +         */
      519 +        abort();
      520 +}
      521 +
 501  522  static void
 502  523  lx_start(uintptr_t sp, uintptr_t entry)
 503  524  {
 504  525          ucontext_t jump_uc;
 505  526  
 506  527          if (getcontext(&jump_uc) != 0) {
 507  528                  lx_err_fatal("Unable to getcontext for program start: %s",
 508  529                      strerror(errno));
 509  530          }
 510  531  
↓ open down ↓ 12 lines elided ↑ open up ↑
 523  544          /*
 524  545           * The AMD64 ABI states that at process entry, %rdx contains "a
 525  546           * function pointer that the application should register with
 526  547           * atexit()".  We make sure to pass NULL explicitly so that
 527  548           * no function is registered.
 528  549           */
 529  550          LX_REG(&jump_uc, REG_RDX) = NULL;
 530  551  #endif
 531  552  
 532  553          lx_debug("starting Linux program sp %p ldentry %p", sp, entry);
 533      -
 534      -        /*
 535      -         * This system call should not return.
 536      -         */
 537      -        if (syscall(SYS_brand, B_JUMP_TO_LINUX, &jump_uc) == -1) {
 538      -                lx_err_fatal("B_JUMP_TO_LINUX failed: %s",
 539      -                    strerror(errno));
 540      -        }
 541      -        abort();
      554 +        lx_jump_to_linux(&jump_uc);
 542  555  }
 543  556  
 544  557  /*ARGSUSED*/
 545  558  int
 546  559  lx_init(int argc, char *argv[], char *envp[])
 547  560  {
 548  561          char            *r;
 549  562          auxv_t          *ap;
 550  563          long            *p;
 551  564          int             err;
↓ open down ↓ 1057 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX