Print this page
OS-3561 lxbrand emulation library should execute on alternate stack
OS-3558 lxbrand add support for full in-kernel syscall handling
OS-3545 lx_syscall_regs should not walk stack
OS-3868 many LTP testcases now hang
OS-3901 lxbrand lx_recvmsg fails to translate control messages when 64-bit
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/ia32/os/sendsig.c
          +++ new/usr/src/uts/intel/ia32/os/sendsig.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
       23 + * Copyright 2015 Joyent, Inc.
       24 + */
       25 +/*
  23   26   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   27   * Use is subject to license terms.
  25   28   */
  26   29  
  27   30  /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  28   31  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T   */
  29   32  /*      All Rights Reserved   */
  30   33  
  31   34  #include <sys/types.h>
  32   35  #include <sys/param.h>
↓ open down ↓ 47 lines elided ↑ open up ↑
  80   83  #include <sys/modctl.h>
  81   84  #include <sys/tuneable.h>
  82   85  #include <c2/audit.h>
  83   86  #include <sys/bootconf.h>
  84   87  #include <sys/dumphdr.h>
  85   88  #include <sys/promif.h>
  86   89  #include <sys/systeminfo.h>
  87   90  #include <sys/kdi.h>
  88   91  #include <sys/contract_impl.h>
  89   92  #include <sys/x86_archext.h>
       93 +#include <sys/brand.h>
       94 +#include <sys/sdt.h>
  90   95  
  91   96  /*
  92   97   * Construct the execution environment for the user's signal
  93   98   * handler and arrange for control to be given to it on return
  94   99   * to userland.  The library code now calls setcontext() to
  95  100   * clean up after the signal handler, so sigret() is no longer
  96  101   * needed.
  97  102   *
  98  103   * (The various 'volatile' declarations are need to ensure that values
  99  104   * are correct on the error return from on_fault().)
↓ open down ↓ 79 lines elided ↑ open up ↑
 179  184  
 180  185          /*
 181  186           * Figure out whether we will be handling this signal on
 182  187           * an alternate stack specified by the user.  Then allocate
 183  188           * and validate the stack requirements for the signal handler
 184  189           * context.  on_fault will catch any faults.
 185  190           */
 186  191          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 187  192              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 188  193  
 189      -        if (newstack) {
      194 +        /*
      195 +         * If this is a branded process, the brand may provide an alternate
      196 +         * stack pointer for signal delivery:
      197 +         */
      198 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
      199 +                /*
      200 +                 * Use the stack pointer value provided by the brand,
      201 +                 * accounting for the 128-byte reserved region.
      202 +                 */
      203 +                newstack = 0;
      204 +                fp = BROP(p)->b_sendsig_stack(sig) - STACK_RESERVE;
      205 +        } else if (newstack) {
 190  206                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 191  207                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
 192  208          } else {
 193  209                  /*
 194  210                   * Drop below the 128-byte reserved region of the stack frame
 195  211                   * we're interrupting.
 196  212                   */
 197  213                  fp = (caddr_t)rp->r_sp - STACK_RESERVE;
 198  214          }
 199  215  
↓ open down ↓ 89 lines elided ↑ open up ↑
 289  305          uc = (ucontext_t *)(sp + sizeof (struct sigframe));
 290  306          tuc = kmem_alloc(sizeof (*tuc), KM_SLEEP);
 291  307          no_fault();
 292  308          savecontext(tuc, &lwp->lwp_sigoldmask);
 293  309          if (on_fault(&ljb))
 294  310                  goto badstack;
 295  311          copyout_noerr(tuc, uc, sizeof (*tuc));
 296  312          kmem_free(tuc, sizeof (*tuc));
 297  313          tuc = NULL;
 298  314  
      315 +        DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
      316 +            uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 299  317          lwp->lwp_oldcontext = (uintptr_t)uc;
 300  318  
 301  319          if (newstack) {
 302  320                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
 303  321                  if (lwp->lwp_ustack)
 304  322                          copyout_noerr(&lwp->lwp_sigaltstack,
 305  323                              (stack_t *)lwp->lwp_ustack, sizeof (stack_t));
 306  324          }
 307  325  
 308  326          /*
↓ open down ↓ 29 lines elided ↑ open up ↑
 338  356          if ((rp->r_cs & 0xffff) != UCS_SEL ||
 339  357              (rp->r_ss & 0xffff) != UDS_SEL) {
 340  358                  /*
 341  359                   * Try our best to deliver the signal.
 342  360                   */
 343  361                  rp->r_cs = UCS_SEL;
 344  362                  rp->r_ss = UDS_SEL;
 345  363          }
 346  364  
 347  365          /*
      366 +         * Allow the brand to perform additional book-keeping once the signal
      367 +         * handling frame has been fully assembled:
      368 +         */
      369 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
      370 +                BROP(p)->b_sendsig(sig);
      371 +        }
      372 +
      373 +        /*
 348  374           * Don't set lwp_eosys here.  sendsig() is called via psig() after
 349  375           * lwp_eosys is handled, so setting it here would affect the next
 350  376           * system call.
 351  377           */
 352  378          return (1);
 353  379  
 354  380  badstack:
 355  381          no_fault();
 356  382          if (watched)
 357  383                  watch_enable_addr((caddr_t)sp, minstacksz, S_WRITE);
↓ open down ↓ 55 lines elided ↑ open up ↑
 413  439  
 414  440          /*
 415  441           * Figure out whether we will be handling this signal on
 416  442           * an alternate stack specified by the user.  Then allocate
 417  443           * and validate the stack requirements for the signal handler
 418  444           * context.  on_fault will catch any faults.
 419  445           */
 420  446          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 421  447              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 422  448  
 423      -        if (newstack) {
      449 +        /*
      450 +         * If this is a branded process, the brand may provide an alternate
      451 +         * stack pointer for signal delivery:
      452 +         */
      453 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
      454 +                /*
      455 +                 * Use the stack pointer value provided by the brand:
      456 +                 */
      457 +                newstack = 0;
      458 +                fp = BROP(p)->b_sendsig_stack(sig);
      459 +        } else if (newstack) {
 424  460                  fp = (caddr_t)(SA32((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 425  461                      SA32(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN32);
 426  462          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
 427  463                  user_desc_t *ldt;
 428  464                  /*
 429  465                   * If the stack segment selector is -not- pointing at
 430  466                   * the UDS_SEL descriptor and we have an LDT entry for
 431  467                   * it instead, add the base address to find the effective va.
 432  468                   */
 433  469                  if ((ldt = p->p_ldt) != NULL)
 434  470                          fp = (caddr_t)rp->r_sp +
 435  471                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
 436  472                  else
 437  473                          fp = (caddr_t)rp->r_sp;
 438      -        } else
      474 +        } else {
 439  475                  fp = (caddr_t)rp->r_sp;
      476 +        }
 440  477  
 441  478          /*
 442  479           * Force proper stack pointer alignment, even in the face of a
 443  480           * misaligned stack pointer from user-level before the signal.
 444  481           * Don't use the SA32() macro because that rounds up, not down.
 445  482           */
 446  483          fp = (caddr_t)((uintptr_t)fp & ~(STACK_ALIGN32 - 1));
 447  484          sp = fp - minstacksz;
 448  485  
 449  486          /*
↓ open down ↓ 60 lines elided ↑ open up ↑
 510  547          uc = (ucontext32_t *)fp;
 511  548          tuc = kmem_alloc(sizeof (*tuc), KM_SLEEP);
 512  549          no_fault();
 513  550          savecontext32(tuc, &lwp->lwp_sigoldmask);
 514  551          if (on_fault(&ljb))
 515  552                  goto badstack;
 516  553          copyout_noerr(tuc, uc, sizeof (*tuc));
 517  554          kmem_free(tuc, sizeof (*tuc));
 518  555          tuc = NULL;
 519  556  
      557 +        DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
      558 +            uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 520  559          lwp->lwp_oldcontext = (uintptr_t)uc;
 521  560  
 522  561          if (newstack) {
 523  562                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
 524  563                  if (lwp->lwp_ustack) {
 525  564                          stack32_t stk32;
 526  565  
 527  566                          stk32.ss_sp = (caddr32_t)(uintptr_t)
 528  567                              lwp->lwp_sigaltstack.ss_sp;
 529  568                          stk32.ss_size = (size32_t)
↓ open down ↓ 29 lines elided ↑ open up ↑
 559  598          if ((rp->r_cs & 0xffff) != U32CS_SEL ||
 560  599              (rp->r_ss & 0xffff) != UDS_SEL) {
 561  600                  /*
 562  601                   * Try our best to deliver the signal.
 563  602                   */
 564  603                  rp->r_cs = U32CS_SEL;
 565  604                  rp->r_ss = UDS_SEL;
 566  605          }
 567  606  
 568  607          /*
      608 +         * Allow the brand to perform additional book-keeping once the signal
      609 +         * handling frame has been fully assembled:
      610 +         */
      611 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
      612 +                BROP(p)->b_sendsig(sig);
      613 +        }
      614 +
      615 +        /*
 569  616           * Don't set lwp_eosys here.  sendsig() is called via psig() after
 570  617           * lwp_eosys is handled, so setting it here would affect the next
 571  618           * system call.
 572  619           */
 573  620          return (1);
 574  621  
 575  622  badstack:
 576  623          no_fault();
 577  624          if (watched)
 578  625                  watch_enable_addr((caddr_t)sp, minstacksz, S_WRITE);
↓ open down ↓ 57 lines elided ↑ open up ↑
 636  683  
 637  684          /*
 638  685           * Figure out whether we will be handling this signal on
 639  686           * an alternate stack specified by the user. Then allocate
 640  687           * and validate the stack requirements for the signal handler
 641  688           * context. on_fault will catch any faults.
 642  689           */
 643  690          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
 644  691              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
 645  692  
 646      -        if (newstack) {
      693 +        /*
      694 +         * If this is a branded process, the brand may provide an alternate
      695 +         * stack pointer for signal delivery:
      696 +         */
      697 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
      698 +                /*
      699 +                 * Use the stack pointer value provided by the brand:
      700 +                 */
      701 +                newstack = 0;
      702 +                fp = BROP(p)->b_sendsig_stack(sig);
      703 +        } else if (newstack) {
 647  704                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
 648  705                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
 649  706          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
 650  707                  user_desc_t *ldt;
 651  708                  /*
 652  709                   * If the stack segment selector is -not- pointing at
 653  710                   * the UDS_SEL descriptor and we have an LDT entry for
 654  711                   * it instead, add the base address to find the effective va.
 655  712                   */
 656  713                  if ((ldt = p->p_ldt) != NULL)
 657  714                          fp = (caddr_t)rp->r_sp +
 658  715                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
 659  716                  else
 660  717                          fp = (caddr_t)rp->r_sp;
 661      -        } else
      718 +        } else {
 662  719                  fp = (caddr_t)rp->r_sp;
      720 +        }
 663  721  
 664  722          /*
 665  723           * Force proper stack pointer alignment, even in the face of a
 666  724           * misaligned stack pointer from user-level before the signal.
 667  725           * Don't use the SA() macro because that rounds up, not down.
 668  726           */
 669  727          fp = (caddr_t)((uintptr_t)fp & ~(STACK_ALIGN - 1ul));
 670  728          sp = fp - minstacksz;
 671  729  
 672  730          /*
↓ open down ↓ 57 lines elided ↑ open up ↑
 730  788  
 731  789          /* save the current context on the user stack */
 732  790          fp -= SA(sizeof (*tuc));
 733  791          uc = (ucontext_t *)fp;
 734  792          tuc = kmem_alloc(sizeof (*tuc), KM_SLEEP);
 735  793          savecontext(tuc, &lwp->lwp_sigoldmask);
 736  794          copyout_noerr(tuc, uc, sizeof (*tuc));
 737  795          kmem_free(tuc, sizeof (*tuc));
 738  796          tuc = NULL;
 739  797  
      798 +        DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
      799 +            uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
 740  800          lwp->lwp_oldcontext = (uintptr_t)uc;
 741  801  
 742  802          if (newstack) {
 743  803                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
 744  804                  if (lwp->lwp_ustack)
 745  805                          copyout_noerr(&lwp->lwp_sigaltstack,
 746  806                              (stack_t *)lwp->lwp_ustack, sizeof (stack_t));
 747  807          }
 748  808  
 749  809          /*
↓ open down ↓ 16 lines elided ↑ open up ↑
 766  826          rp->r_sp = (greg_t)sp;
 767  827          rp->r_pc = (greg_t)hdlr;
 768  828          rp->r_ps = PSL_USER | (rp->r_ps & PS_IOPL);
 769  829  
 770  830          if ((rp->r_cs & 0xffff) != UCS_SEL ||
 771  831              (rp->r_ss & 0xffff) != UDS_SEL) {
 772  832                  rp->r_cs = UCS_SEL;
 773  833                  rp->r_ss = UDS_SEL;
 774  834          }
 775  835  
      836 +        /*
      837 +         * Allow the brand to perform additional book-keeping once the signal
      838 +         * handling frame has been fully assembled:
      839 +         */
      840 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
      841 +                BROP(p)->b_sendsig(sig);
      842 +        }
      843 +
 776  844          /*
 777  845           * Don't set lwp_eosys here.  sendsig() is called via psig() after
 778  846           * lwp_eosys is handled, so setting it here would affect the next
 779  847           * system call.
 780  848           */
 781  849          return (1);
 782  850  
 783  851  badstack:
 784  852          no_fault();
 785  853          if (watched)
↓ open down ↓ 13 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX