Print this page
    
OS-4460 exec brands processes that still have multiple threads
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4188 NULL dereference in lwp_hash_in
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4151 setbrand hooks should be sane during fork
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4129 lxbrand should not abuse p_brand_data for storing exit signal
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-3712 lx brand: DTrace pid provider induces core dumps on 64-bit processes
OS-3517 lx brand: branded zones don't interpret .interp section
OS-3149 lx brand always sends SIGCHLD to parent processes, regardless of how clone was invoked
OS-2887 lxbrand add WALL, WCLONE, WNOTHREAD support to waitid
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-2877 lx_librtld_db falls to load due to NULL DT_DEBUG
OS-2834 ship lx brand
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/os/brand.c
          +++ new/usr/src/uts/common/os/brand.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ 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   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright (c) 2015, Joyent, Inc. All rights reserved.
  23   24   */
  24   25  
  25   26  #include <sys/kmem.h>
  26   27  #include <sys/errno.h>
  27   28  #include <sys/systm.h>
  28   29  #include <sys/cmn_err.h>
  29   30  #include <sys/brand.h>
  30   31  #include <sys/machbrand.h>
  31   32  #include <sys/modctl.h>
  32   33  #include <sys/rwlock.h>
  33   34  #include <sys/zone.h>
  34   35  #include <sys/pathname.h>
  35   36  
  36   37  #define SUPPORTED_BRAND_VERSION BRAND_VER_1
  37   38  
  
    | 
      ↓ open down ↓ | 
    5 lines elided | 
    
      ↑ open up ↑ | 
  
  38   39  #if defined(__sparcv9)
  39   40  /* sparcv9 uses system wide brand interposition hooks */
  40   41  static void brand_plat_interposition_enable(void);
  41   42  static void brand_plat_interposition_disable(void);
  42   43  
  43   44  struct brand_mach_ops native_mach_ops  = {
  44   45                  NULL, NULL
  45   46  };
  46   47  #else /* !__sparcv9 */
  47   48  struct brand_mach_ops native_mach_ops  = {
  48      -                NULL, NULL, NULL, NULL
       49 +                NULL, NULL, NULL, NULL, NULL, NULL, NULL
  49   50  };
  50   51  #endif /* !__sparcv9 */
  51   52  
  52   53  brand_t native_brand = {
  53   54                  BRAND_VER_1,
  54   55                  "native",
  55   56                  NULL,
  56      -                &native_mach_ops
       57 +                &native_mach_ops,
       58 +                0
  57   59  };
  58   60  
  59   61  /*
  60   62   * Used to maintain a list of all the brands currently loaded into the
  61   63   * kernel.
  62   64   */
  63   65  struct brand_list {
  64   66          int                     bl_refcnt;
  65   67          struct brand_list       *bl_next;
  66   68          brand_t                 *bl_brand;
  67   69  };
  68   70  
  69   71  static struct brand_list *brand_list = NULL;
  70   72  
  71   73  /*
  72   74   * This lock protects the integrity of the brand list.
  73   75   */
  74   76  static kmutex_t brand_list_lock;
  75   77  
  76   78  void
  77   79  brand_init()
  78   80  {
  79   81          mutex_init(&brand_list_lock, NULL, MUTEX_DEFAULT, NULL);
  80   82          p0.p_brand = &native_brand;
  81   83  }
  82   84  
  83   85  int
  84   86  brand_register(brand_t *brand)
  85   87  {
  86   88          struct brand_list *list, *scan;
  87   89  
  88   90          if (brand == NULL)
  89   91                  return (EINVAL);
  90   92  
  91   93          if (brand->b_version != SUPPORTED_BRAND_VERSION) {
  92   94                  if (brand->b_version < SUPPORTED_BRAND_VERSION) {
  93   95                          cmn_err(CE_WARN,
  94   96                              "brand '%s' was built to run on older versions "
  95   97                              "of Solaris.",
  96   98                              brand->b_name);
  97   99                  } else {
  98  100                          cmn_err(CE_WARN,
  99  101                              "brand '%s' was built to run on a newer version "
 100  102                              "of Solaris.",
 101  103                              brand->b_name);
 102  104                  }
 103  105                  return (EINVAL);
 104  106          }
 105  107  
 106  108          /* Sanity checks */
 107  109          if (brand->b_name == NULL || brand->b_ops == NULL ||
 108  110              brand->b_ops->b_brandsys == NULL) {
 109  111                  cmn_err(CE_WARN, "Malformed brand");
 110  112                  return (EINVAL);
 111  113          }
 112  114  
 113  115          list = kmem_alloc(sizeof (struct brand_list), KM_SLEEP);
 114  116  
 115  117          /* Add the brand to the list of loaded brands. */
 116  118          mutex_enter(&brand_list_lock);
 117  119  
 118  120          /*
 119  121           * Check to be sure we haven't already registered this brand.
 120  122           */
 121  123          for (scan = brand_list; scan != NULL; scan = scan->bl_next) {
 122  124                  if (strcmp(brand->b_name, scan->bl_brand->b_name) == 0) {
 123  125                          cmn_err(CE_WARN,
 124  126                              "Invalid attempt to load a second instance of "
 125  127                              "brand %s", brand->b_name);
 126  128                          mutex_exit(&brand_list_lock);
 127  129                          kmem_free(list, sizeof (struct brand_list));
 128  130                          return (EINVAL);
 129  131                  }
 130  132          }
 131  133  
 132  134  #if defined(__sparcv9)
 133  135          /* sparcv9 uses system wide brand interposition hooks */
 134  136          if (brand_list == NULL)
 135  137                  brand_plat_interposition_enable();
 136  138  #endif /* __sparcv9 */
 137  139  
 138  140          list->bl_brand = brand;
 139  141          list->bl_refcnt = 0;
 140  142          list->bl_next = brand_list;
 141  143          brand_list = list;
 142  144  
 143  145          mutex_exit(&brand_list_lock);
 144  146  
 145  147          return (0);
 146  148  }
 147  149  
 148  150  /*
 149  151   * The kernel module implementing this brand is being unloaded, so remove
 150  152   * it from the list of active brands.
 151  153   */
 152  154  int
 153  155  brand_unregister(brand_t *brand)
 154  156  {
 155  157          struct brand_list *list, *prev;
 156  158  
 157  159          /* Sanity checks */
 158  160          if (brand == NULL || brand->b_name == NULL) {
 159  161                  cmn_err(CE_WARN, "Malformed brand");
 160  162                  return (EINVAL);
 161  163          }
 162  164  
 163  165          prev = NULL;
 164  166          mutex_enter(&brand_list_lock);
 165  167  
 166  168          for (list = brand_list; list != NULL; list = list->bl_next) {
 167  169                  if (list->bl_brand == brand)
 168  170                          break;
 169  171                  prev = list;
 170  172          }
 171  173  
 172  174          if (list == NULL) {
 173  175                  cmn_err(CE_WARN, "Brand %s wasn't registered", brand->b_name);
 174  176                  mutex_exit(&brand_list_lock);
 175  177                  return (EINVAL);
 176  178          }
 177  179  
 178  180          if (list->bl_refcnt > 0) {
 179  181                  cmn_err(CE_WARN, "Unregistering brand %s which is still in use",
 180  182                      brand->b_name);
 181  183                  mutex_exit(&brand_list_lock);
 182  184                  return (EBUSY);
 183  185          }
 184  186  
 185  187          /* Remove brand from the list */
 186  188          if (prev != NULL)
 187  189                  prev->bl_next = list->bl_next;
 188  190          else
 189  191                  brand_list = list->bl_next;
 190  192  
 191  193  #if defined(__sparcv9)
 192  194          /* sparcv9 uses system wide brand interposition hooks */
 193  195          if (brand_list == NULL)
 194  196                  brand_plat_interposition_disable();
 195  197  #endif /* __sparcv9 */
 196  198  
 197  199          mutex_exit(&brand_list_lock);
 198  200  
 199  201          kmem_free(list, sizeof (struct brand_list));
 200  202  
 201  203          return (0);
 202  204  }
 203  205  
 204  206  /*
 205  207   * Record that a zone of this brand has been instantiated.  If the kernel
 206  208   * module implementing this brand's functionality is not present, this
 207  209   * routine attempts to load the module as a side effect.
 208  210   */
 209  211  brand_t *
 210  212  brand_register_zone(struct brand_attr *attr)
 211  213  {
 212  214          struct brand_list *l = NULL;
 213  215          ddi_modhandle_t hdl = NULL;
 214  216          char *modname;
 215  217          int err = 0;
 216  218  
 217  219          if (is_system_labeled()) {
 218  220                  cmn_err(CE_WARN,
 219  221                      "Branded zones are not allowed on labeled systems.");
 220  222                  return (NULL);
 221  223          }
 222  224  
 223  225          /*
 224  226           * We make at most two passes through this loop.  The first time
 225  227           * through, we're looking to see if this is a new user of an
 226  228           * already loaded brand.  If the brand hasn't been loaded, we
 227  229           * call ddi_modopen() to force it to be loaded and then make a
 228  230           * second pass through the list of brands.  If we don't find the
 229  231           * brand the second time through it means that the modname
 230  232           * specified in the brand_attr structure doesn't provide the brand
 231  233           * specified in the brandname field.  This would suggest a bug in
 232  234           * the brand's config.xml file.  We close the module and return
 233  235           * 'NULL' to the caller.
 234  236           */
 235  237          for (;;) {
 236  238                  /*
 237  239                   * Search list of loaded brands
 238  240                   */
 239  241                  mutex_enter(&brand_list_lock);
 240  242                  for (l = brand_list; l != NULL; l = l->bl_next)
 241  243                          if (strcmp(attr->ba_brandname,
 242  244                              l->bl_brand->b_name) == 0)
 243  245                                  break;
 244  246                  if ((l != NULL) || (hdl != NULL))
 245  247                          break;
 246  248                  mutex_exit(&brand_list_lock);
 247  249  
 248  250                  /*
 249  251                   * We didn't find that the requested brand has been loaded
 250  252                   * yet, so we trigger the load of the appropriate kernel
 251  253                   * module and search the list again.
 252  254                   */
 253  255                  modname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
 254  256                  (void) strcpy(modname, "brand/");
 255  257                  (void) strcat(modname, attr->ba_modname);
 256  258                  hdl = ddi_modopen(modname, KRTLD_MODE_FIRST, &err);
 257  259                  kmem_free(modname, MAXPATHLEN);
 258  260  
 259  261                  if (err != 0)
 260  262                          return (NULL);
 261  263          }
 262  264  
 263  265          /*
 264  266           * If we found the matching brand, bump its reference count.
 265  267           */
 266  268          if (l != NULL)
 267  269                  l->bl_refcnt++;
 268  270  
 269  271          mutex_exit(&brand_list_lock);
 270  272  
 271  273          if (hdl != NULL)
 272  274                  (void) ddi_modclose(hdl);
 273  275  
 274  276          return ((l != NULL) ? l->bl_brand : NULL);
 275  277  }
 276  278  
 277  279  /*
 278  280   * Return the number of zones currently using this brand.
 279  281   */
 280  282  int
 281  283  brand_zone_count(struct brand *bp)
 282  284  {
 283  285          struct brand_list *l;
 284  286          int cnt = 0;
 285  287  
 286  288          mutex_enter(&brand_list_lock);
 287  289          for (l = brand_list; l != NULL; l = l->bl_next)
 288  290                  if (l->bl_brand == bp) {
 289  291                          cnt = l->bl_refcnt;
 290  292                          break;
 291  293                  }
 292  294          mutex_exit(&brand_list_lock);
 293  295  
 294  296          return (cnt);
 295  297  }
 296  298  
 297  299  void
 298  300  brand_unregister_zone(struct brand *bp)
 299  301  {
 300  302          struct brand_list *list;
 301  303  
 302  304          mutex_enter(&brand_list_lock);
  
    | 
      ↓ open down ↓ | 
    236 lines elided | 
    
      ↑ open up ↑ | 
  
 303  305          for (list = brand_list; list != NULL; list = list->bl_next) {
 304  306                  if (list->bl_brand == bp) {
 305  307                          ASSERT(list->bl_refcnt > 0);
 306  308                          list->bl_refcnt--;
 307  309                          break;
 308  310                  }
 309  311          }
 310  312          mutex_exit(&brand_list_lock);
 311  313  }
 312  314  
 313      -void
 314      -brand_setbrand(proc_t *p)
      315 +int
      316 +brand_setbrand(proc_t *p, boolean_t lwps_ok)
 315  317  {
 316  318          brand_t *bp = p->p_zone->zone_brand;
      319 +        void *brand_data = NULL;
 317  320  
 318      -        ASSERT(bp != NULL);
 319      -        ASSERT(p->p_brand == &native_brand);
      321 +        VERIFY(MUTEX_NOT_HELD(&p->p_lock));
      322 +        VERIFY(bp != NULL);
 320  323  
 321  324          /*
 322      -         * We should only be called from exec(), when we know the process
 323      -         * is single-threaded.
      325 +         * Process branding occurs during fork() and exec().  When it happens
      326 +         * during fork(), the LWP count will always be 0 since branding is
      327 +         * performed as part of getproc(), before LWPs have been associated.
      328 +         * The same is not true during exec(), where a multi-LWP process may
      329 +         * undergo branding just prior to gexec(). This is to ensure
      330 +         * exec-related brand hooks are available.  While it may seem
      331 +         * complicated to brand a multi-LWP process, the two possible outcomes
      332 +         * simplify things:
      333 +         *
      334 +         * 1. The exec() succeeds:  LWPs besides the caller will be killed and
      335 +         *    any further branding will occur in a single-LWP context.
      336 +         * 2. The exec() fails: The process will be promptly unbranded since
      337 +         *    the hooks are no longer needed.
      338 +         *
      339 +         * To prevent inconsistent brand state from being encountered during
      340 +         * the exec(), LWPs beyond the caller which are associated with this
      341 +         * process must be held temporarily.  They will be released either when
      342 +         * they are killed in the exec() success, or when the brand is cleared
      343 +         * after exec() failure.
 324  344           */
 325      -        ASSERT(p->p_tlist == p->p_tlist->t_forw);
      345 +        if (lwps_ok) {
      346 +                /*
      347 +                 * We've been called from a exec() context tolerating the
      348 +                 * existence of multiple LWPs during branding is necessary.
      349 +                 */
      350 +                VERIFY(p == curproc);
      351 +                VERIFY(p->p_tlist != NULL);
 326  352  
      353 +                if (p->p_tlist != p->p_tlist->t_forw) {
      354 +                        /*
      355 +                         * Multiple LWPs are present.  Hold all but the caller.
      356 +                         */
      357 +                        if (!holdlwps(SHOLDFORK1)) {
      358 +                                return (-1);
      359 +                        }
      360 +                }
      361 +        } else {
      362 +                /*
      363 +                 * Processes branded during fork() should not have LWPs at all.
      364 +                 */
      365 +                VERIFY(p->p_tlist == NULL);
      366 +        }
      367 +
      368 +        if (bp->b_data_size > 0) {
      369 +                brand_data = kmem_zalloc(bp->b_data_size, KM_SLEEP);
      370 +        }
      371 +
      372 +        mutex_enter(&p->p_lock);
      373 +        ASSERT(!PROC_IS_BRANDED(p));
 327  374          p->p_brand = bp;
      375 +        p->p_brand_data = brand_data;
 328  376          ASSERT(PROC_IS_BRANDED(p));
 329  377          BROP(p)->b_setbrand(p);
      378 +        mutex_exit(&p->p_lock);
      379 +        return (0);
 330  380  }
 331  381  
 332  382  void
 333      -brand_clearbrand(proc_t *p, boolean_t no_lwps)
      383 +brand_clearbrand(proc_t *p, boolean_t lwps_ok)
 334  384  {
 335  385          brand_t *bp = p->p_zone->zone_brand;
 336      -        klwp_t *lwp = NULL;
 337      -        ASSERT(bp != NULL);
 338      -        ASSERT(!no_lwps || (p->p_tlist == NULL));
      386 +        void *brand_data;
 339  387  
 340      -        /*
 341      -         * If called from exec_common() or proc_exit(),
 342      -         * we know the process is single-threaded.
 343      -         * If called from fork_fail, p_tlist is NULL.
 344      -         */
 345      -        if (!no_lwps) {
 346      -                ASSERT(p->p_tlist == p->p_tlist->t_forw);
 347      -                lwp = p->p_tlist->t_lwp;
 348      -        }
      388 +        VERIFY(MUTEX_NOT_HELD(&p->p_lock));
      389 +        VERIFY(bp != NULL);
      390 +        VERIFY(PROC_IS_BRANDED(p));
 349  391  
 350      -        ASSERT(PROC_IS_BRANDED(p));
 351      -        BROP(p)->b_proc_exit(p, lwp);
      392 +        mutex_enter(&p->p_lock);
 352  393          p->p_brand = &native_brand;
      394 +        brand_data = p->p_brand_data;
      395 +        p->p_brand_data = NULL;
      396 +
      397 +        if (lwps_ok) {
      398 +                VERIFY(p == curproc);
      399 +                /*
      400 +                 * A process with multiple LWPs is being de-branded after
      401 +                 * failing an exec.  The other LWPs were held as part of the
      402 +                 * procedure, so they must be resumed now.
      403 +                 */
      404 +                if (p->p_tlist != NULL && p->p_tlist != p->p_tlist->t_forw) {
      405 +                        continuelwps(p);
      406 +                }
      407 +        } else {
      408 +                /*
      409 +                 * While clearing the brand, it's ok for one LWP to be present.
      410 +                 * This happens when a native binary is executed inside a
      411 +                 * branded zone, since the brand will be removed during the
      412 +                 * course of a successful exec.
      413 +                 */
      414 +                VERIFY(p->p_tlist == NULL || p->p_tlist == p->p_tlist->t_forw);
      415 +        }
      416 +        mutex_exit(&p->p_lock);
      417 +
      418 +        if (brand_data != NULL) {
      419 +                kmem_free(brand_data, bp->b_data_size);
      420 +        }
 353  421  }
 354  422  
 355  423  #if defined(__sparcv9)
 356  424  /*
 357  425   * Currently, only sparc has system level brand syscall interposition.
 358  426   * On x86 we're able to enable syscall interposition on a per-cpu basis
 359  427   * when a branded thread is scheduled to run on a cpu.
 360  428   */
 361  429  
 362  430  /* Local variables needed for dynamic syscall interposition support */
 363  431  static uint32_t syscall_trap_patch_instr_orig;
 364  432  static uint32_t syscall_trap32_patch_instr_orig;
 365  433  
 366  434  /* Trap Table syscall entry hot patch points */
 367  435  extern void     syscall_trap_patch_point(void);
 368  436  extern void     syscall_trap32_patch_point(void);
 369  437  
 370  438  /* Alternate syscall entry handlers used when branded zones are running */
 371  439  extern void     syscall_wrapper(void);
 372  440  extern void     syscall_wrapper32(void);
 373  441  
 374  442  /* Macros used to facilitate sparcv9 instruction generation */
 375  443  #define BA_A_INSTR      0x30800000      /* ba,a addr */
 376  444  #define DISP22(from, to) \
 377  445          ((((uintptr_t)(to) - (uintptr_t)(from)) >> 2) & 0x3fffff)
 378  446  
 379  447  /*ARGSUSED*/
 380  448  static void
 381  449  brand_plat_interposition_enable(void)
 382  450  {
 383  451          ASSERT(MUTEX_HELD(&brand_list_lock));
 384  452  
 385  453          /*
 386  454           * Before we hot patch the kernel save the current instructions
 387  455           * so that we can restore them later.
 388  456           */
 389  457          syscall_trap_patch_instr_orig =
 390  458              *(uint32_t *)syscall_trap_patch_point;
 391  459          syscall_trap32_patch_instr_orig =
 392  460              *(uint32_t *)syscall_trap32_patch_point;
 393  461  
 394  462          /*
 395  463           * Modify the trap table at the patch points.
 396  464           *
 397  465           * We basically replace the first instruction at the patch
 398  466           * point with a ba,a instruction that will transfer control
 399  467           * to syscall_wrapper or syscall_wrapper32 for 64-bit and
 400  468           * 32-bit syscalls respectively.  It's important to note that
 401  469           * the annul bit is set in the branch so we don't execute
 402  470           * the instruction directly following the one we're patching
 403  471           * during the branch's delay slot.
 404  472           *
 405  473           * It also doesn't matter that we're not atomically updating both
 406  474           * the 64 and 32 bit syscall paths at the same time since there's
 407  475           * no actual branded processes running on the system yet.
 408  476           */
 409  477          hot_patch_kernel_text((caddr_t)syscall_trap_patch_point,
 410  478              BA_A_INSTR | DISP22(syscall_trap_patch_point, syscall_wrapper),
 411  479              4);
 412  480          hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point,
 413  481              BA_A_INSTR | DISP22(syscall_trap32_patch_point, syscall_wrapper32),
 414  482              4);
 415  483  }
 416  484  
 417  485  /*ARGSUSED*/
 418  486  static void
 419  487  brand_plat_interposition_disable(void)
 420  488  {
 421  489          ASSERT(MUTEX_HELD(&brand_list_lock));
 422  490  
 423  491          /*
 424  492           * Restore the original instructions at the trap table syscall
 425  493           * patch points to disable the brand syscall interposition
 426  494           * mechanism.
 427  495           */
 428  496          hot_patch_kernel_text((caddr_t)syscall_trap_patch_point,
 429  497              syscall_trap_patch_instr_orig, 4);
 430  498          hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point,
 431  499              syscall_trap32_patch_instr_orig, 4);
 432  500  }
 433  501  #endif /* __sparcv9 */
 434  502  
 435  503  /*
 436  504   * The following functions can be shared among kernel brand modules which
 437  505   * implement Solaris-derived brands, all of which need to do similar tasks
 438  506   * to manage the brand.
 439  507   */
 440  508  
 441  509  #if defined(_LP64)
 442  510  static void
 443  511  Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst)
 444  512  {
 445  513          bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
 446  514          dst->e_type =           src->e_type;
 447  515          dst->e_machine =        src->e_machine;
 448  516          dst->e_version =        src->e_version;
 449  517          dst->e_entry =          src->e_entry;
 450  518          dst->e_phoff =          src->e_phoff;
 451  519          dst->e_shoff =          src->e_shoff;
 452  520          dst->e_flags =          src->e_flags;
 453  521          dst->e_ehsize =         src->e_ehsize;
 454  522          dst->e_phentsize =      src->e_phentsize;
 455  523          dst->e_phnum =          src->e_phnum;
 456  524          dst->e_shentsize =      src->e_shentsize;
 457  525          dst->e_shnum =          src->e_shnum;
 458  526          dst->e_shstrndx =       src->e_shstrndx;
 459  527  }
 460  528  #endif /* _LP64 */
 461  529  
 462  530  /*
 463  531   * Return -1 if the cmd was not handled by this function.
 464  532   */
 465  533  /*ARGSUSED*/
 466  534  int
 467  535  brand_solaris_cmd(int cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
 468  536      struct brand *pbrand, int brandvers)
 469  537  {
 470  538          brand_proc_data_t       *spd;
 471  539          brand_proc_reg_t        reg;
 472  540          proc_t                  *p = curproc;
 473  541          int                     err;
 474  542  
 475  543          /*
  
    | 
      ↓ open down ↓ | 
    113 lines elided | 
    
      ↑ open up ↑ | 
  
 476  544           * There is one operation that is supported for a native
 477  545           * process; B_EXEC_BRAND.  This brand operaion is redundant
 478  546           * since the kernel assumes a native process doing an exec
 479  547           * in a branded zone is going to run a branded processes.
 480  548           * hence we don't support this operation.
 481  549           */
 482  550          if (cmd == B_EXEC_BRAND)
 483  551                  return (ENOSYS);
 484  552  
 485  553          /* For all other operations this must be a branded process. */
 486      -        if (p->p_brand == &native_brand)
      554 +        if (!PROC_IS_BRANDED(p))
 487  555                  return (ENOSYS);
 488  556  
 489  557          ASSERT(p->p_brand == pbrand);
 490  558          ASSERT(p->p_brand_data != NULL);
 491  559  
 492  560          spd = (brand_proc_data_t *)p->p_brand_data;
 493  561  
 494  562          switch ((cmd)) {
 495  563          case B_EXEC_NATIVE:
 496  564                  err = exec_common((char *)arg1, (const char **)arg2,
 497  565                      (const char **)arg3, EBA_NATIVE);
 498  566                  return (err);
 499  567  
 500  568          /*
 501  569           * Get the address of the user-space system call handler from
 502  570           * the user process and attach it to the proc structure.
 503  571           */
 504  572          case B_REGISTER:
 505  573                  if (p->p_model == DATAMODEL_NATIVE) {
 506  574                          if (copyin((void *)arg1, ®, sizeof (reg)) != 0)
 507  575                                  return (EFAULT);
 508  576                  }
 509  577  #if defined(_LP64)
 510  578                  else {
 511  579                          brand_common_reg32_t reg32;
 512  580  
 513  581                          if (copyin((void *)arg1, ®32, sizeof (reg32)) != 0)
 514  582                                  return (EFAULT);
 515  583                          reg.sbr_version = reg32.sbr_version;
 516  584                          reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
 517  585                  }
 518  586  #endif /* _LP64 */
 519  587  
 520  588                  if (reg.sbr_version != brandvers)
 521  589                          return (ENOTSUP);
 522  590                  spd->spd_handler = reg.sbr_handler;
 523  591                  return (0);
 524  592  
 525  593          case B_ELFDATA:
 526  594                  if (p->p_model == DATAMODEL_NATIVE) {
 527  595                          if (copyout(&spd->spd_elf_data, (void *)arg1,
 528  596                              sizeof (brand_elf_data_t)) != 0)
 529  597                                  return (EFAULT);
 530  598                  }
 531  599  #if defined(_LP64)
 532  600                  else {
 533  601                          brand_elf_data32_t sed32;
 534  602  
 535  603                          sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
 536  604                          sed32.sed_phent = spd->spd_elf_data.sed_phent;
 537  605                          sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
 538  606                          sed32.sed_entry = spd->spd_elf_data.sed_entry;
 539  607                          sed32.sed_base = spd->spd_elf_data.sed_base;
 540  608                          sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
 541  609                          sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
 542  610                          if (copyout(&sed32, (void *)arg1, sizeof (sed32))
 543  611                              != 0)
 544  612                                  return (EFAULT);
 545  613                  }
 546  614  #endif /* _LP64 */
 547  615                  return (0);
 548  616  
 549  617          /*
 550  618           * The B_TRUSS_POINT subcommand exists so that we can see
 551  619           * truss output from interposed system calls that return
 552  620           * without first calling any other system call, meaning they
 553  621           * would be invisible to truss(1).
 554  622           * If the second argument is set non-zero, set errno to that
 555  623           * value as well.
 556  624           *
 557  625           * Common arguments seen with truss are:
 558  626           *
 559  627           *      arg1: syscall number
 560  628           *      arg2: errno
 561  629           */
 562  630          case B_TRUSS_POINT:
 563  631                  return ((arg2 == 0) ? 0 : set_errno((uint_t)arg2));
 564  632          }
 565  633  
 566  634          return (-1);
 567  635  }
 568  636  
 569  637  /*ARGSUSED*/
 570  638  void
 571  639  brand_solaris_copy_procdata(proc_t *child, proc_t *parent, struct brand *pbrand)
 572  640  {
 573  641          brand_proc_data_t       *spd;
 574  642  
 575  643          ASSERT(parent->p_brand == pbrand);
 576  644          ASSERT(child->p_brand == pbrand);
 577  645          ASSERT(parent->p_brand_data != NULL);
 578  646          ASSERT(child->p_brand_data == NULL);
 579  647  
 580  648          /*
 581  649           * Just duplicate all the proc data of the parent for the
 582  650           * child
 583  651           */
 584  652          spd = kmem_alloc(sizeof (brand_proc_data_t), KM_SLEEP);
 585  653          bcopy(parent->p_brand_data, spd, sizeof (brand_proc_data_t));
 586  654          child->p_brand_data = spd;
 587  655  }
 588  656  
 589  657  static void
 590  658  restoreexecenv(struct execenv *ep, stack_t *sp)
 591  659  {
 592  660          klwp_t *lwp = ttolwp(curthread);
 593  661  
  
    | 
      ↓ open down ↓ | 
    97 lines elided | 
    
      ↑ open up ↑ | 
  
 594  662          setexecenv(ep);
 595  663          lwp->lwp_sigaltstack.ss_sp = sp->ss_sp;
 596  664          lwp->lwp_sigaltstack.ss_size = sp->ss_size;
 597  665          lwp->lwp_sigaltstack.ss_flags = sp->ss_flags;
 598  666  }
 599  667  
 600  668  /*ARGSUSED*/
 601  669  int
 602  670  brand_solaris_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args,
 603  671      intpdata_t *idatap, int level, long *execsz, int setid, caddr_t exec_file,
 604      -    cred_t *cred, int brand_action, struct brand *pbrand, char *bname,
 605      -    char *brandlib, char *brandlib32, char *brandlinker, char *brandlinker32)
      672 +    cred_t *cred, int *brand_action, struct brand *pbrand, char *bname,
      673 +    char *brandlib, char *brandlib32)
 606  674  {
 607  675  
 608  676          vnode_t         *nvp;
 609  677          Ehdr            ehdr;
 610  678          Addr            uphdr_vaddr;
 611  679          intptr_t        voffset;
 612      -        int             interp;
      680 +        char            *interp;
 613  681          int             i, err;
 614  682          struct execenv  env;
 615  683          struct execenv  origenv;
 616  684          stack_t         orig_sigaltstack;
 617  685          struct user     *up = PTOU(curproc);
 618  686          proc_t          *p = ttoproc(curthread);
 619  687          klwp_t          *lwp = ttolwp(curthread);
 620  688          brand_proc_data_t       *spd;
 621  689          brand_elf_data_t sed, *sedp;
 622      -        char            *linker;
 623  690          uintptr_t       lddata; /* lddata of executable's linker */
 624  691  
 625  692          ASSERT(curproc->p_brand == pbrand);
 626  693          ASSERT(curproc->p_brand_data != NULL);
 627  694  
 628  695          spd = (brand_proc_data_t *)curproc->p_brand_data;
 629  696          sedp = &spd->spd_elf_data;
 630  697  
 631  698          args->brandname = bname;
 632  699  
 633  700          /*
 634  701           * We will exec the brand library and then map in the target
 635  702           * application and (optionally) the brand's default linker.
 636  703           */
 637  704          if (args->to_model == DATAMODEL_NATIVE) {
 638  705                  args->emulator = brandlib;
 639      -                linker = brandlinker;
 640  706          }
 641  707  #if defined(_LP64)
 642  708          else {
 643  709                  args->emulator = brandlib32;
 644      -                linker = brandlinker32;
 645  710          }
 646  711  #endif  /* _LP64 */
 647  712  
 648  713          if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW,
 649  714              NULLVPP, &nvp)) != 0) {
 650  715                  uprintf("%s: not found.", args->emulator);
 651  716                  return (err);
 652  717          }
 653  718  
 654  719          /*
 655  720           * The following elf{32}exec call changes the execenv in the proc
 656  721           * struct which includes changing the p_exec member to be the vnode
 657  722           * for the brand library (e.g. /.SUNWnative/usr/lib/s10_brand.so.1).
 658  723           * We will eventually set the p_exec member to be the vnode for the new
 659  724           * executable when we call setexecenv().  However, if we get an error
 660  725           * before that call we need to restore the execenv to its original
 661  726           * values so that when we return to the caller fop_close() works
 662  727           * properly while cleaning up from the failed exec().  Restoring the
 663  728           * original value will also properly decrement the 2nd VN_RELE that we
 664  729           * took on the brand library.
 665  730           */
 666  731          origenv.ex_bssbase = p->p_bssbase;
 667  732          origenv.ex_brkbase = p->p_brkbase;
 668  733          origenv.ex_brksize = p->p_brksize;
 669  734          origenv.ex_vp = p->p_exec;
 670  735          orig_sigaltstack.ss_sp = lwp->lwp_sigaltstack.ss_sp;
 671  736          orig_sigaltstack.ss_size = lwp->lwp_sigaltstack.ss_size;
 672  737          orig_sigaltstack.ss_flags = lwp->lwp_sigaltstack.ss_flags;
 673  738  
 674  739          if (args->to_model == DATAMODEL_NATIVE) {
 675  740                  err = elfexec(nvp, uap, args, idatap, INTP_MAXDEPTH + 1, execsz,
 676  741                      setid, exec_file, cred, brand_action);
 677  742          }
 678  743  #if defined(_LP64)
 679  744          else {
 680  745                  err = elf32exec(nvp, uap, args, idatap, INTP_MAXDEPTH + 1,
 681  746                      execsz, setid, exec_file, cred, brand_action);
 682  747          }
 683  748  #endif  /* _LP64 */
 684  749          VN_RELE(nvp);
 685  750          if (err != 0) {
 686  751                  restoreexecenv(&origenv, &orig_sigaltstack);
 687  752                  return (err);
 688  753          }
 689  754  
 690  755          /*
 691  756           * The u_auxv veCTors are set up by elfexec to point to the
 692  757           * brand emulation library and linker.  Save these so they can
 693  758           * be copied to the specific brand aux vectors.
 694  759           */
 695  760          bzero(&sed, sizeof (sed));
 696  761          for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
 697  762                  switch (up->u_auxv[i].a_type) {
 698  763                  case AT_SUN_LDDATA:
 699  764                          sed.sed_lddata = up->u_auxv[i].a_un.a_val;
 700  765                          break;
 701  766                  case AT_BASE:
 702  767                          sed.sed_base = up->u_auxv[i].a_un.a_val;
 703  768                          break;
 704  769                  case AT_ENTRY:
 705  770                          sed.sed_entry = up->u_auxv[i].a_un.a_val;
 706  771                          break;
 707  772                  case AT_PHDR:
 708  773                          sed.sed_phdr = up->u_auxv[i].a_un.a_val;
 709  774                          break;
 710  775                  case AT_PHENT:
 711  776                          sed.sed_phent = up->u_auxv[i].a_un.a_val;
 712  777                          break;
 713  778                  case AT_PHNUM:
 714  779                          sed.sed_phnum = up->u_auxv[i].a_un.a_val;
 715  780                          break;
 716  781                  default:
 717  782                          break;
  
    | 
      ↓ open down ↓ | 
    63 lines elided | 
    
      ↑ open up ↑ | 
  
 718  783                  }
 719  784          }
 720  785          /* Make sure the emulator has an entry point */
 721  786          ASSERT(sed.sed_entry != NULL);
 722  787          ASSERT(sed.sed_phdr != NULL);
 723  788  
 724  789          bzero(&env, sizeof (env));
 725  790          if (args->to_model == DATAMODEL_NATIVE) {
 726  791                  err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr,
 727  792                      &voffset, exec_file, &interp, &env.ex_bssbase,
 728      -                    &env.ex_brkbase, &env.ex_brksize, NULL);
      793 +                    &env.ex_brkbase, &env.ex_brksize, NULL, NULL);
 729  794          }
 730  795  #if defined(_LP64)
 731  796          else {
 732  797                  Elf32_Ehdr ehdr32;
 733  798                  Elf32_Addr uphdr_vaddr32;
 734  799                  err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
 735  800                      &voffset, exec_file, &interp, &env.ex_bssbase,
 736      -                    &env.ex_brkbase, &env.ex_brksize, NULL);
      801 +                    &env.ex_brkbase, &env.ex_brksize, NULL, NULL);
 737  802                  Ehdr32to64(&ehdr32, &ehdr);
 738  803  
 739  804                  if (uphdr_vaddr32 == (Elf32_Addr)-1)
 740  805                          uphdr_vaddr = (Addr)-1;
 741  806                  else
 742  807                          uphdr_vaddr = uphdr_vaddr32;
 743  808          }
 744  809  #endif  /* _LP64 */
 745  810          if (err != 0) {
 746  811                  restoreexecenv(&origenv, &orig_sigaltstack);
      812 +
      813 +                if (interp != NULL)
      814 +                        kmem_free(interp, MAXPATHLEN);
      815 +
 747  816                  return (err);
 748  817          }
 749  818  
 750  819          /*
 751  820           * Save off the important properties of the executable. The
 752  821           * brand library will ask us for this data later, when it is
 753  822           * initializing and getting ready to transfer control to the
 754  823           * brand application.
 755  824           */
 756  825          if (uphdr_vaddr == (Addr)-1)
 757  826                  sedp->sed_phdr = voffset + ehdr.e_phoff;
 758  827          else
 759  828                  sedp->sed_phdr = voffset + uphdr_vaddr;
 760  829          sedp->sed_entry = voffset + ehdr.e_entry;
 761  830          sedp->sed_phent = ehdr.e_phentsize;
 762  831          sedp->sed_phnum = ehdr.e_phnum;
 763  832  
 764      -        if (interp) {
      833 +        if (interp != NULL) {
 765  834                  if (ehdr.e_type == ET_DYN) {
 766  835                          /*
 767  836                           * This is a shared object executable, so we
 768  837                           * need to pick a reasonable place to put the
 769  838                           * heap. Just don't use the first page.
 770  839                           */
 771  840                          env.ex_brkbase = (caddr_t)PAGESIZE;
 772  841                          env.ex_bssbase = (caddr_t)PAGESIZE;
 773  842                  }
 774  843  
 775  844                  /*
 776  845                   * If the program needs an interpreter (most do), map
 777  846                   * it in and store relevant information about it in the
 778  847                   * aux vector, where the brand library can find it.
 779  848                   */
 780      -                if ((err = lookupname(linker, UIO_SYSSPACE,
      849 +                if ((err = lookupname(interp, UIO_SYSSPACE,
 781  850                      FOLLOW, NULLVPP, &nvp)) != 0) {
 782      -                        uprintf("%s: not found.", brandlinker);
      851 +                        uprintf("%s: not found.", interp);
 783  852                          restoreexecenv(&origenv, &orig_sigaltstack);
      853 +                        kmem_free(interp, MAXPATHLEN);
 784  854                          return (err);
 785  855                  }
      856 +
      857 +                kmem_free(interp, MAXPATHLEN);
      858 +
 786  859                  if (args->to_model == DATAMODEL_NATIVE) {
 787  860                          err = mapexec_brand(nvp, args, &ehdr,
 788  861                              &uphdr_vaddr, &voffset, exec_file, &interp,
 789      -                            NULL, NULL, NULL, &lddata);
      862 +                            NULL, NULL, NULL, &lddata, NULL);
 790  863                  }
 791  864  #if defined(_LP64)
 792  865                  else {
 793  866                          Elf32_Ehdr ehdr32;
 794  867                          Elf32_Addr uphdr_vaddr32;
 795  868                          err = mapexec32_brand(nvp, args, &ehdr32,
 796  869                              &uphdr_vaddr32, &voffset, exec_file, &interp,
 797      -                            NULL, NULL, NULL, &lddata);
      870 +                            NULL, NULL, NULL, &lddata, NULL);
 798  871                          Ehdr32to64(&ehdr32, &ehdr);
 799  872  
 800  873                          if (uphdr_vaddr32 == (Elf32_Addr)-1)
 801  874                                  uphdr_vaddr = (Addr)-1;
 802  875                          else
 803  876                                  uphdr_vaddr = uphdr_vaddr32;
 804  877                  }
 805  878  #endif  /* _LP64 */
 806  879                  VN_RELE(nvp);
 807  880                  if (err != 0) {
 808  881                          restoreexecenv(&origenv, &orig_sigaltstack);
 809  882                          return (err);
 810  883                  }
 811  884  
 812  885                  /*
 813  886                   * Now that we know the base address of the brand's
 814  887                   * linker, place it in the aux vector.
 815  888                   */
 816  889                  sedp->sed_base = voffset;
 817  890                  sedp->sed_ldentry = voffset + ehdr.e_entry;
 818  891                  sedp->sed_lddata = voffset + lddata;
 819  892          } else {
 820  893                  /*
 821  894                   * This program has no interpreter. The brand library
 822  895                   * will jump to the address in the AT_SUN_BRAND_LDENTRY
 823  896                   * aux vector, so in this case, put the entry point of
 824  897                   * the main executable there.
 825  898                   */
 826  899                  if (ehdr.e_type == ET_EXEC) {
 827  900                          /*
 828  901                           * An executable with no interpreter, this must
 829  902                           * be a statically linked executable, which
 830  903                           * means we loaded it at the address specified
 831  904                           * in the elf header, in which case the e_entry
 832  905                           * field of the elf header is an absolute
 833  906                           * address.
 834  907                           */
 835  908                          sedp->sed_ldentry = ehdr.e_entry;
 836  909                          sedp->sed_entry = ehdr.e_entry;
 837  910                          sedp->sed_lddata = NULL;
 838  911                          sedp->sed_base = NULL;
 839  912                  } else {
 840  913                          /*
 841  914                           * A shared object with no interpreter, we use
 842  915                           * the calculated address from above.
 843  916                           */
 844  917                          sedp->sed_ldentry = sedp->sed_entry;
 845  918                          sedp->sed_entry = NULL;
 846  919                          sedp->sed_phdr = NULL;
 847  920                          sedp->sed_phent = NULL;
 848  921                          sedp->sed_phnum = NULL;
 849  922                          sedp->sed_lddata = NULL;
 850  923                          sedp->sed_base = voffset;
 851  924  
 852  925                          if (ehdr.e_type == ET_DYN) {
 853  926                                  /*
 854  927                                   * Delay setting the brkbase until the
 855  928                                   * first call to brk(); see elfexec()
 856  929                                   * for details.
 857  930                                   */
 858  931                                  env.ex_bssbase = (caddr_t)0;
 859  932                                  env.ex_brkbase = (caddr_t)0;
 860  933                                  env.ex_brksize = 0;
 861  934                          }
 862  935                  }
 863  936          }
 864  937  
 865  938          env.ex_magic = elfmagic;
 866  939          env.ex_vp = vp;
 867  940          setexecenv(&env);
 868  941  
 869  942          /*
 870  943           * It's time to manipulate the process aux vectors.  First
 871  944           * we need to update the AT_SUN_AUXFLAGS aux vector to set
 872  945           * the AF_SUN_NOPLM flag.
 873  946           */
 874  947          if (args->to_model == DATAMODEL_NATIVE) {
 875  948                  auxv_t          auxflags_auxv;
 876  949  
 877  950                  if (copyin(args->auxp_auxflags, &auxflags_auxv,
 878  951                      sizeof (auxflags_auxv)) != 0)
 879  952                          return (EFAULT);
 880  953  
 881  954                  ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
 882  955                  auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
 883  956                  if (copyout(&auxflags_auxv, args->auxp_auxflags,
 884  957                      sizeof (auxflags_auxv)) != 0)
 885  958                          return (EFAULT);
 886  959          }
 887  960  #if defined(_LP64)
 888  961          else {
 889  962                  auxv32_t        auxflags_auxv32;
 890  963  
 891  964                  if (copyin(args->auxp_auxflags, &auxflags_auxv32,
 892  965                      sizeof (auxflags_auxv32)) != 0)
 893  966                          return (EFAULT);
 894  967  
 895  968                  ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
 896  969                  auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
 897  970                  if (copyout(&auxflags_auxv32, args->auxp_auxflags,
 898  971                      sizeof (auxflags_auxv32)) != 0)
 899  972                          return (EFAULT);
 900  973          }
 901  974  #endif  /* _LP64 */
 902  975  
 903  976          /* Second, copy out the brand specific aux vectors. */
 904  977          if (args->to_model == DATAMODEL_NATIVE) {
 905  978                  auxv_t brand_auxv[] = {
 906  979                      { AT_SUN_BRAND_AUX1, 0 },
 907  980                      { AT_SUN_BRAND_AUX2, 0 },
 908  981                      { AT_SUN_BRAND_AUX3, 0 }
 909  982                  };
 910  983  
 911  984                  ASSERT(brand_auxv[0].a_type ==
 912  985                      AT_SUN_BRAND_COMMON_LDDATA);
 913  986                  brand_auxv[0].a_un.a_val = sed.sed_lddata;
 914  987  
 915  988                  if (copyout(&brand_auxv, args->auxp_brand,
 916  989                      sizeof (brand_auxv)) != 0)
 917  990                          return (EFAULT);
 918  991          }
 919  992  #if defined(_LP64)
 920  993          else {
 921  994                  auxv32_t brand_auxv32[] = {
 922  995                      { AT_SUN_BRAND_AUX1, 0 },
 923  996                      { AT_SUN_BRAND_AUX2, 0 },
 924  997                      { AT_SUN_BRAND_AUX3, 0 }
 925  998                  };
 926  999  
  
    | 
      ↓ open down ↓ | 
    119 lines elided | 
    
      ↑ open up ↑ | 
  
 927 1000                  ASSERT(brand_auxv32[0].a_type == AT_SUN_BRAND_COMMON_LDDATA);
 928 1001                  brand_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
 929 1002                  if (copyout(&brand_auxv32, args->auxp_brand,
 930 1003                      sizeof (brand_auxv32)) != 0)
 931 1004                          return (EFAULT);
 932 1005          }
 933 1006  #endif  /* _LP64 */
 934 1007  
 935 1008          /*
 936 1009           * Third, the /proc aux vectors set up by elfexec() point to
 937      -         * brand emulation library and it's linker.  Copy these to the
     1010 +         * brand emulation library and its linker.  Copy these to the
 938 1011           * /proc brand specific aux vector, and update the regular
 939      -         * /proc aux vectors to point to the executable (and it's
     1012 +         * /proc aux vectors to point to the executable (and its
 940 1013           * linker).  This will enable debuggers to access the
 941 1014           * executable via the usual /proc or elf notes aux vectors.
 942 1015           *
 943 1016           * The brand emulation library's linker will get it's aux
 944 1017           * vectors off the stack, and then update the stack with the
 945 1018           * executable's aux vectors before jumping to the executable's
 946 1019           * linker.
 947 1020           *
 948 1021           * Debugging the brand emulation library must be done from
 949 1022           * the global zone, where the librtld_db module knows how to
 950 1023           * fetch the brand specific aux vectors to access the brand
 951 1024           * emulation libraries linker.
 952 1025           */
 953 1026          for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
 954 1027                  ulong_t val;
 955 1028  
 956 1029                  switch (up->u_auxv[i].a_type) {
 957 1030                  case AT_SUN_BRAND_COMMON_LDDATA:
 958 1031                          up->u_auxv[i].a_un.a_val = sed.sed_lddata;
 959 1032                          continue;
 960 1033                  case AT_BASE:
 961 1034                          val = sedp->sed_base;
 962 1035                          break;
 963 1036                  case AT_ENTRY:
 964 1037                          val = sedp->sed_entry;
 965 1038                          break;
 966 1039                  case AT_PHDR:
 967 1040                          val = sedp->sed_phdr;
 968 1041                          break;
 969 1042                  case AT_PHENT:
 970 1043                          val = sedp->sed_phent;
 971 1044                          break;
 972 1045                  case AT_PHNUM:
 973 1046                          val = sedp->sed_phnum;
 974 1047                          break;
 975 1048                  case AT_SUN_LDDATA:
 976 1049                          val = sedp->sed_lddata;
 977 1050                          break;
 978 1051                  default:
 979 1052                          continue;
 980 1053                  }
 981 1054  
 982 1055                  up->u_auxv[i].a_un.a_val = val;
 983 1056                  if (val == NULL) {
 984 1057                          /* Hide the entry for static binaries */
 985 1058                          up->u_auxv[i].a_type = AT_IGNORE;
 986 1059                  }
 987 1060          }
 988 1061  
 989 1062          /*
 990 1063           * The last thing we do here is clear spd->spd_handler.  This
 991 1064           * is important because if we're already a branded process and
 992 1065           * if this exec succeeds, there is a window between when the
 993 1066           * exec() first returns to the userland of the new process and
 994 1067           * when our brand library get's initialized, during which we
 995 1068           * don't want system calls to be re-directed to our brand
 996 1069           * library since it hasn't been initialized yet.
 997 1070           */
 998 1071          spd->spd_handler = NULL;
 999 1072  
1000 1073          return (0);
1001 1074  }
1002 1075  
1003 1076  void
1004 1077  brand_solaris_exec(struct brand *pbrand)
1005 1078  {
1006 1079          brand_proc_data_t       *spd = curproc->p_brand_data;
1007 1080  
1008 1081          ASSERT(curproc->p_brand == pbrand);
1009 1082          ASSERT(curproc->p_brand_data != NULL);
1010 1083          ASSERT(ttolwp(curthread)->lwp_brand != NULL);
1011 1084  
1012 1085          /*
1013 1086           * We should only be called from exec(), when we know the process
1014 1087           * is single-threaded.
1015 1088           */
1016 1089          ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
1017 1090  
1018 1091          /* Upon exec, reset our lwp brand data. */
1019 1092          (void) brand_solaris_freelwp(ttolwp(curthread), pbrand);
1020 1093          (void) brand_solaris_initlwp(ttolwp(curthread), pbrand);
1021 1094  
1022 1095          /*
1023 1096           * Upon exec, reset all the proc brand data, except for the elf
1024 1097           * data associated with the executable we are exec'ing.
1025 1098           */
1026 1099          spd->spd_handler = NULL;
1027 1100  }
1028 1101  
1029 1102  int
1030 1103  brand_solaris_fini(char **emul_table, struct modlinkage *modlinkage,
1031 1104      struct brand *pbrand)
1032 1105  {
1033 1106          int err;
1034 1107  
1035 1108          /*
1036 1109           * If there are any zones using this brand, we can't allow it
1037 1110           * to be unloaded.
1038 1111           */
1039 1112          if (brand_zone_count(pbrand))
1040 1113                  return (EBUSY);
1041 1114  
1042 1115          kmem_free(*emul_table, NSYSCALL);
1043 1116          *emul_table = NULL;
1044 1117  
1045 1118          err = mod_remove(modlinkage);
1046 1119          if (err)
1047 1120                  cmn_err(CE_WARN, "Couldn't unload brand module");
1048 1121  
1049 1122          return (err);
1050 1123  }
1051 1124  
1052 1125  /*ARGSUSED*/
1053 1126  void
1054 1127  brand_solaris_forklwp(klwp_t *p, klwp_t *c, struct brand *pbrand)
1055 1128  {
1056 1129          ASSERT(p->lwp_procp->p_brand == pbrand);
1057 1130          ASSERT(c->lwp_procp->p_brand == pbrand);
1058 1131  
1059 1132          ASSERT(p->lwp_procp->p_brand_data != NULL);
1060 1133          ASSERT(c->lwp_procp->p_brand_data != NULL);
1061 1134  
1062 1135          /*
1063 1136           * Both LWPs have already had been initialized via
1064 1137           * brand_solaris_initlwp().
1065 1138           */
1066 1139          ASSERT(p->lwp_brand != NULL);
1067 1140          ASSERT(c->lwp_brand != NULL);
1068 1141  }
1069 1142  
1070 1143  /*ARGSUSED*/
  
    | 
      ↓ open down ↓ | 
    121 lines elided | 
    
      ↑ open up ↑ | 
  
1071 1144  void
1072 1145  brand_solaris_freelwp(klwp_t *l, struct brand *pbrand)
1073 1146  {
1074 1147          ASSERT(l->lwp_procp->p_brand == pbrand);
1075 1148          ASSERT(l->lwp_procp->p_brand_data != NULL);
1076 1149          ASSERT(l->lwp_brand != NULL);
1077 1150          l->lwp_brand = NULL;
1078 1151  }
1079 1152  
1080 1153  /*ARGSUSED*/
1081      -int
     1154 +void
1082 1155  brand_solaris_initlwp(klwp_t *l, struct brand *pbrand)
1083 1156  {
1084 1157          ASSERT(l->lwp_procp->p_brand == pbrand);
1085 1158          ASSERT(l->lwp_procp->p_brand_data != NULL);
1086 1159          ASSERT(l->lwp_brand == NULL);
1087 1160          l->lwp_brand = (void *)-1;
1088      -        return (0);
1089 1161  }
1090 1162  
1091 1163  /*ARGSUSED*/
1092 1164  void
1093 1165  brand_solaris_lwpexit(klwp_t *l, struct brand *pbrand)
1094 1166  {
1095      -        proc_t  *p = l->lwp_procp;
1096      -
1097 1167          ASSERT(l->lwp_procp->p_brand == pbrand);
1098 1168          ASSERT(l->lwp_procp->p_brand_data != NULL);
1099 1169          ASSERT(l->lwp_brand != NULL);
1100      -
1101      -        /*
1102      -         * We should never be called for the last thread in a process.
1103      -         * (That case is handled by brand_solaris_proc_exit().)
1104      -         * Therefore this lwp must be exiting from a multi-threaded
1105      -         * process.
1106      -         */
1107      -        ASSERT(p->p_tlist != p->p_tlist->t_forw);
1108      -
1109      -        l->lwp_brand = NULL;
1110 1170  }
1111 1171  
1112 1172  /*ARGSUSED*/
1113 1173  void
1114      -brand_solaris_proc_exit(struct proc *p, klwp_t *l, struct brand *pbrand)
     1174 +brand_solaris_proc_exit(struct proc *p, struct brand *pbrand)
1115 1175  {
1116 1176          ASSERT(p->p_brand == pbrand);
1117 1177          ASSERT(p->p_brand_data != NULL);
1118 1178  
1119      -        /*
1120      -         * When called from proc_exit(), we know that process is
1121      -         * single-threaded and free our lwp brand data.
1122      -         * otherwise just free p_brand_data and return.
1123      -         */
1124      -        if (l != NULL) {
1125      -                ASSERT(p->p_tlist == p->p_tlist->t_forw);
1126      -                ASSERT(p->p_tlist->t_lwp == l);
1127      -                (void) brand_solaris_freelwp(l, pbrand);
1128      -        }
1129      -
1130 1179          /* upon exit, free our proc brand data */
1131 1180          kmem_free(p->p_brand_data, sizeof (brand_proc_data_t));
1132 1181          p->p_brand_data = NULL;
1133 1182  }
1134 1183  
1135 1184  void
1136 1185  brand_solaris_setbrand(proc_t *p, struct brand *pbrand)
1137 1186  {
1138 1187          ASSERT(p->p_brand == pbrand);
1139 1188          ASSERT(p->p_brand_data == NULL);
1140 1189  
1141 1190          /*
1142 1191           * We should only be called from exec(), when we know the process
1143 1192           * is single-threaded.
1144 1193           */
1145 1194          ASSERT(p->p_tlist == p->p_tlist->t_forw);
1146 1195  
1147 1196          p->p_brand_data = kmem_zalloc(sizeof (brand_proc_data_t), KM_SLEEP);
1148      -        (void) brand_solaris_initlwp(p->p_tlist->t_lwp, pbrand);
1149 1197  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX