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
↓ 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>
↓ 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;
↓ 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 */
↓ 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,
↓ 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          /*
↓ 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) {
↓ 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
↓ 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