Print this page
OS-5015 PT_INTERP headers should be permitted after PT_LOAD headers
OS-5451 comm page should not break i86xpv
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-5192 need faster clock_gettime
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
Reviewed by: Ryan Zezeski <ryan@zinascii.com>
OS-5293 lx brand: prelink(8)'d binaries core dump before main()
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-5072 lxbrand support PT_GNU_STACK
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-5202 Support AT_SECURE & AT_*ID in LX
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4824 Unlike Linux, nested interpreters don't work
(LX changes only, the rest were upstreamed...)
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Cody Mello <cody.mello@joyent.com>
OS-3735 modstubs MAXNARG is too low.
OS-3733 Verify b_native_exec exists before calling it
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4128 programs that lack PT_PHDR are not properly loaded
OS-4141 freeing phdrs induces bad kmem_free() in elfexec()
backout OS-4141: needs more work
backout OS-4128: needs more work
OS-4141 freeing phdrs induces bad kmem_free() in elfexec()
OS-4128 programs that lack PT_PHDR are not properly loaded
OS-3696 lx brand: G-Portugol programs core dump
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-3517 lx brand: branded zones don't interpret .interp section
OS-3405 lx brand: socket() fails for PF_INET6
OS-3382 lxbrand 64bit gettimeofday depends on vsyscall or vdso
OS-3280 need a way to specify the root of a native system in the lx brand
OS-3279 lx brand should allow delegated datasets
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-2949 add support for AT_RANDOM aux vector entry
OS-2877 lx_librtld_db falls to load due to NULL DT_DEBUG

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/exec/elf/elf.c
          +++ new/usr/src/uts/common/exec/elf/elf.c
↓ open down ↓ 18 lines elided ↑ open up ↑
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  
  26   26  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  27   27  /*        All Rights Reserved   */
  28   28  /*
  29      - * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
       29 + * Copyright 2016 Joyent, Inc.
  30   30   */
  31   31  
  32   32  #include <sys/types.h>
  33   33  #include <sys/param.h>
  34   34  #include <sys/thread.h>
  35   35  #include <sys/sysmacros.h>
  36   36  #include <sys/signal.h>
  37   37  #include <sys/cred.h>
  38   38  #include <sys/user.h>
  39   39  #include <sys/errno.h>
↓ open down ↓ 19 lines elided ↑ open up ↑
  59   59  #include <sys/vmparam.h>
  60   60  #include <sys/machelf.h>
  61   61  #include <sys/shm_impl.h>
  62   62  #include <sys/archsystm.h>
  63   63  #include <sys/fasttrap.h>
  64   64  #include <sys/brand.h>
  65   65  #include "elf_impl.h"
  66   66  #include <sys/sdt.h>
  67   67  #include <sys/siginfo.h>
  68   68  
       69 +#if defined(__x86)
       70 +#include <sys/comm_page_util.h>
       71 +#endif /* defined(__x86) */
       72 +
       73 +
  69   74  extern int at_flags;
  70   75  
  71   76  #define ORIGIN_STR      "ORIGIN"
  72   77  #define ORIGIN_STR_SIZE 6
  73   78  
  74   79  static int getelfhead(vnode_t *, cred_t *, Ehdr *, int *, int *, int *);
  75   80  static int getelfphdr(vnode_t *, cred_t *, const Ehdr *, int, caddr_t *,
  76   81      ssize_t *);
  77   82  static int getelfshdr(vnode_t *, cred_t *, const Ehdr *, int, int, caddr_t *,
  78   83      ssize_t *, caddr_t *, ssize_t *);
↓ open down ↓ 77 lines elided ↑ open up ↑
 156  161          if (phdrp->p_memsz < PT_SUNWDTRACE_SIZE ||
 157  162              (phdrp->p_flags & (PF_R | PF_W | PF_X)) != (PF_R | PF_W | PF_X))
 158  163                  return (-1);
 159  164  
 160  165          args->thrptr = phdrp->p_vaddr + base;
 161  166  
 162  167          return (0);
 163  168  }
 164  169  
 165  170  /*
 166      - * Map in the executable pointed to by vp. Returns 0 on success.
      171 + * Map in the executable pointed to by vp. Returns 0 on success.  Note that
      172 + * this function currently has the maximum number of arguments allowed by
      173 + * modstubs on x86 (MAXNARG)!  Do _not_ add to this function signature without
      174 + * adding to MAXNARG.  (Better yet, do not add to this monster of a function
      175 + * signature!)
 167  176   */
 168  177  int
 169  178  mapexec_brand(vnode_t *vp, uarg_t *args, Ehdr *ehdr, Addr *uphdr_vaddr,
 170      -    intptr_t *voffset, caddr_t exec_file, int *interp, caddr_t *bssbase,
 171      -    caddr_t *brkbase, size_t *brksize, uintptr_t *lddatap)
      179 +    intptr_t *voffset, caddr_t exec_file, char **interpp, caddr_t *bssbase,
      180 +    caddr_t *brkbase, size_t *brksize, uintptr_t *lddatap, uintptr_t *minaddrp)
 172  181  {
 173  182          size_t          len;
 174  183          struct vattr    vat;
 175  184          caddr_t         phdrbase = NULL;
 176  185          ssize_t         phdrsize;
 177  186          int             nshdrs, shstrndx, nphdrs;
 178  187          int             error = 0;
 179  188          Phdr            *uphdr = NULL;
 180  189          Phdr            *junk = NULL;
 181  190          Phdr            *dynphdr = NULL;
 182  191          Phdr            *dtrphdr = NULL;
      192 +        char            *interp = NULL;
 183  193          uintptr_t       lddata;
 184  194          long            execsz;
 185  195          intptr_t        minaddr;
 186  196  
 187  197          if (lddatap != NULL)
 188  198                  *lddatap = NULL;
 189  199  
      200 +        if (minaddrp != NULL)
      201 +                *minaddrp = NULL;
      202 +
 190  203          if (error = execpermissions(vp, &vat, args)) {
 191  204                  uprintf("%s: Cannot execute %s\n", exec_file, args->pathname);
 192  205                  return (error);
 193  206          }
 194  207  
 195  208          if ((error = getelfhead(vp, CRED(), ehdr, &nshdrs, &shstrndx,
 196  209              &nphdrs)) != 0 ||
 197  210              (error = getelfphdr(vp, CRED(), ehdr, nphdrs, &phdrbase,
 198  211              &phdrsize)) != 0) {
 199  212                  uprintf("%s: Cannot read %s\n", exec_file, args->pathname);
↓ open down ↓ 5 lines elided ↑ open up ↑
 205  218                  kmem_free(phdrbase, phdrsize);
 206  219                  return (ENOEXEC);
 207  220          }
 208  221          if (lddatap != NULL)
 209  222                  *lddatap = lddata;
 210  223  
 211  224          if (error = mapelfexec(vp, ehdr, nphdrs, phdrbase, &uphdr, &dynphdr,
 212  225              &junk, &dtrphdr, NULL, bssbase, brkbase, voffset, &minaddr,
 213  226              len, &execsz, brksize)) {
 214  227                  uprintf("%s: Cannot map %s\n", exec_file, args->pathname);
      228 +                if (uphdr != NULL && uphdr->p_flags == 0)
      229 +                        kmem_free(uphdr, sizeof (Phdr));
 215  230                  kmem_free(phdrbase, phdrsize);
 216  231                  return (error);
 217  232          }
 218  233  
      234 +        if (minaddrp != NULL)
      235 +                *minaddrp = minaddr;
      236 +
 219  237          /*
 220      -         * Inform our caller if the executable needs an interpreter.
      238 +         * If the executable requires an interpreter, determine its name.
 221  239           */
 222      -        *interp = (dynphdr == NULL) ? 0 : 1;
      240 +        if (dynphdr != NULL) {
      241 +                ssize_t resid;
 223  242  
      243 +                if (dynphdr->p_filesz > MAXPATHLEN || dynphdr->p_filesz == 0) {
      244 +                        uprintf("%s: Invalid interpreter\n", exec_file);
      245 +                        kmem_free(phdrbase, phdrsize);
      246 +                        return (ENOEXEC);
      247 +                }
      248 +
      249 +                interp = kmem_alloc(MAXPATHLEN, KM_SLEEP);
      250 +
      251 +                if ((error = vn_rdwr(UIO_READ, vp, interp, dynphdr->p_filesz,
      252 +                    (offset_t)dynphdr->p_offset, UIO_SYSSPACE, 0,
      253 +                    (rlim64_t)0, CRED(), &resid)) != 0 || resid != 0 ||
      254 +                    interp[dynphdr->p_filesz - 1] != '\0') {
      255 +                        uprintf("%s: Cannot obtain interpreter pathname\n",
      256 +                            exec_file);
      257 +                        kmem_free(interp, MAXPATHLEN);
      258 +                        kmem_free(phdrbase, phdrsize);
      259 +                        return (error != 0 ? error : ENOEXEC);
      260 +                }
      261 +        }
      262 +
 224  263          /*
 225  264           * If this is a statically linked executable, voffset should indicate
 226  265           * the address of the executable itself (it normally holds the address
 227  266           * of the interpreter).
 228  267           */
 229      -        if (ehdr->e_type == ET_EXEC && *interp == 0)
      268 +        if (ehdr->e_type == ET_EXEC && interp == NULL)
 230  269                  *voffset = minaddr;
 231  270  
      271 +        /*
      272 +         * If the caller has asked for the interpreter name, return it (it's
      273 +         * up to the caller to free it); if the caller hasn't asked for it,
      274 +         * free it ourselves.
      275 +         */
      276 +        if (interpp != NULL) {
      277 +                *interpp = interp;
      278 +        } else if (interp != NULL) {
      279 +                kmem_free(interp, MAXPATHLEN);
      280 +        }
      281 +
 232  282          if (uphdr != NULL) {
 233  283                  *uphdr_vaddr = uphdr->p_vaddr;
      284 +
      285 +                if (uphdr->p_flags == 0)
      286 +                        kmem_free(uphdr, sizeof (Phdr));
      287 +        } else if (ehdr->e_type == ET_DYN) {
      288 +                /*
      289 +                 * If we don't have a uphdr, we'll apply the logic found
      290 +                 * in mapelfexec() and use the p_vaddr of the first PT_LOAD
      291 +                 * section as the base address of the object.
      292 +                 */
      293 +                Phdr *phdr = (Phdr *)phdrbase;
      294 +                int i, hsize = ehdr->e_phentsize;
      295 +
      296 +                for (i = nphdrs; i > 0; i--) {
      297 +                        if (phdr->p_type == PT_LOAD) {
      298 +                                *uphdr_vaddr = (uintptr_t)phdr->p_vaddr +
      299 +                                    ehdr->e_phoff;
      300 +                                break;
      301 +                        }
      302 +
      303 +                        phdr = (Phdr *)((caddr_t)phdr + hsize);
      304 +                }
      305 +
      306 +                /*
      307 +                 * If we don't have a PT_LOAD segment, we should have returned
      308 +                 * ENOEXEC when elfsize() returned 0, above.
      309 +                 */
      310 +                VERIFY(i > 0);
 234  311          } else {
 235  312                  *uphdr_vaddr = (Addr)-1;
 236  313          }
 237  314  
 238  315          kmem_free(phdrbase, phdrsize);
 239  316          return (error);
 240  317  }
 241  318  
 242  319  /*ARGSUSED*/
 243  320  int
 244  321  elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
 245  322      int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred,
 246      -    int brand_action)
      323 +    int *brand_action)
 247  324  {
 248  325          caddr_t         phdrbase = NULL;
 249  326          caddr_t         bssbase = 0;
 250  327          caddr_t         brkbase = 0;
 251  328          size_t          brksize = 0;
 252      -        ssize_t         dlnsize;
      329 +        ssize_t         dlnsize, nsize = 0;
 253  330          aux_entry_t     *aux;
 254  331          int             error;
 255  332          ssize_t         resid;
 256  333          int             fd = -1;
 257  334          intptr_t        voffset;
 258  335          Phdr            *dyphdr = NULL;
 259  336          Phdr            *stphdr = NULL;
 260  337          Phdr            *uphdr = NULL;
 261  338          Phdr            *junk = NULL;
 262  339          size_t          len;
↓ open down ↓ 3 lines elided ↑ open up ↑
 266  343          Phdr            *phdrp;
 267  344          Phdr            *dataphdrp = NULL;
 268  345          Phdr            *dtrphdr;
 269  346          Phdr            *capphdr = NULL;
 270  347          Cap             *cap = NULL;
 271  348          ssize_t         capsize;
 272  349          int             hasu = 0;
 273  350          int             hasauxv = 0;
 274  351          int             hasdy = 0;
 275  352          int             branded = 0;
      353 +        int             dynuphdr = 0;
 276  354  
 277  355          struct proc *p = ttoproc(curthread);
 278  356          struct user *up = PTOU(p);
 279  357          struct bigwad {
 280  358                  Ehdr    ehdr;
 281  359                  aux_entry_t     elfargs[__KERN_NAUXV_IMPL];
 282  360                  char            dl_name[MAXPATHLEN];
 283  361                  char            pathbuf[MAXPATHLEN];
 284  362                  struct vattr    vattr;
 285  363                  struct execenv  exenv;
↓ open down ↓ 34 lines elided ↑ open up ↑
 320  398           * exec_args(), so it will know what it is copying to on new stack.
 321  399           * Now that we know whether we are exec-ing a 32-bit or 64-bit
 322  400           * executable, we can set execsz with the appropriate NCARGS.
 323  401           */
 324  402  #ifdef  _LP64
 325  403          if (ehdrp->e_ident[EI_CLASS] == ELFCLASS32) {
 326  404                  args->to_model = DATAMODEL_ILP32;
 327  405                  *execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS32-1);
 328  406          } else {
 329  407                  args->to_model = DATAMODEL_LP64;
 330      -                args->stk_prot &= ~PROT_EXEC;
      408 +                if (!args->stk_prot_override) {
      409 +                        args->stk_prot &= ~PROT_EXEC;
      410 +                }
 331  411  #if defined(__i386) || defined(__amd64)
 332  412                  args->dat_prot &= ~PROT_EXEC;
 333  413  #endif
 334  414                  *execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS64-1);
 335  415          }
 336  416  #else   /* _LP64 */
 337  417          args->to_model = DATAMODEL_ILP32;
 338  418          *execsz = btopr(SINCR) + btopr(SSIZE) + btopr(NCARGS-1);
 339  419  #endif  /* _LP64 */
 340  420  
 341  421          /*
 342      -         * We delay invoking the brand callback until we've figured out
 343      -         * what kind of elf binary we're trying to run, 32-bit or 64-bit.
 344      -         * We do this because now the brand library can just check
 345      -         * args->to_model to see if the target is 32-bit or 64-bit without
 346      -         * having do duplicate all the code above.
      422 +         * We delay invoking the brand callback until we've figured out what
      423 +         * kind of elf binary we're trying to run, 32-bit or 64-bit.  We do this
      424 +         * because now the brand library can just check args->to_model to see if
      425 +         * the target is 32-bit or 64-bit without having do duplicate all the
      426 +         * code above.
 347  427           *
      428 +         * We also give the brand a chance to indicate that based on the ELF
      429 +         * OSABI of the target binary it should become unbranded and optionally
      430 +         * indicate that it should be treated as existing in a specific prefix.
      431 +         *
      432 +         * Note that if a brand opts to go down this route it does not actually
      433 +         * end up being debranded. In other words, future programs that exec
      434 +         * will still be considered for branding unless this escape hatch is
      435 +         * used. Consider the case of lx brand for example. If a user runs
      436 +         * /native/usr/sbin/dtrace -c /bin/ls, the isaexec and normal executable
      437 +         * of DTrace that's in /native will take this escape hatch and be run
      438 +         * and interpreted using the normal system call table; however, the
      439 +         * execution of a non-illumos binary in the form of /bin/ls will still
      440 +         * be branded and be subject to all of the normal actions of the brand.
      441 +         *
 348  442           * The level checks associated with brand handling below are used to
 349  443           * prevent a loop since the brand elfexec function typically comes back
 350  444           * through this function. We must check <= here since the nested
 351  445           * handling in the #! interpreter code will increment the level before
 352  446           * calling gexec to run the final elfexec interpreter.
 353  447           */
      448 +        if ((level <= INTP_MAXDEPTH) && (*brand_action != EBA_NATIVE) &&
      449 +            (PROC_IS_BRANDED(p)) && (BROP(p)->b_native_exec != NULL)) {
      450 +                if (BROP(p)->b_native_exec(ehdrp->e_ident[EI_OSABI],
      451 +                    &args->brand_nroot) == B_TRUE) {
      452 +                        ASSERT(ehdrp->e_ident[EI_OSABI]);
      453 +                        *brand_action = EBA_NATIVE;
      454 +                        /* Add one for the trailing '/' in the path */
      455 +                        if (args->brand_nroot != NULL)
      456 +                                nsize = strlen(args->brand_nroot) + 1;
      457 +                }
      458 +        }
      459 +
 354  460          if ((level <= INTP_MAXDEPTH) &&
 355      -            (brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
      461 +            (*brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
 356  462                  error = BROP(p)->b_elfexec(vp, uap, args,
 357  463                      idatap, level + 1, execsz, setid, exec_file, cred,
 358  464                      brand_action);
 359  465                  goto out;
 360  466          }
 361  467  
 362  468          /*
 363  469           * Determine aux size now so that stack can be built
 364  470           * in one shot (except actual copyout of aux image),
 365  471           * determine any non-default stack protections,
↓ open down ↓ 50 lines elided ↑ open up ↑
 416  522           * ISA-specific types (included in __KERN_NAUXV_IMPL).
 417  523           */
 418  524          if (hasauxv) {
 419  525                  /*
 420  526                   * If a AUX vector is being built - the base AUX
 421  527                   * entries are:
 422  528                   *
 423  529                   *      AT_BASE
 424  530                   *      AT_FLAGS
 425  531                   *      AT_PAGESZ
      532 +                 *      AT_RANDOM
 426  533                   *      AT_SUN_AUXFLAGS
 427  534                   *      AT_SUN_HWCAP
 428  535                   *      AT_SUN_HWCAP2
 429  536                   *      AT_SUN_PLATFORM (added in stk_copyout)
 430  537                   *      AT_SUN_EXECNAME (added in stk_copyout)
 431  538                   *      AT_NULL
 432  539                   *
 433      -                 * total == 9
      540 +                 * total == 10
 434  541                   */
 435  542                  if (hasdy && hasu) {
 436  543                          /*
 437  544                           * Has PT_INTERP & PT_PHDR - the auxvectors that
 438  545                           * will be built are:
 439  546                           *
 440  547                           *      AT_PHDR
 441  548                           *      AT_PHENT
 442  549                           *      AT_PHNUM
 443  550                           *      AT_ENTRY
 444  551                           *      AT_LDDATA
 445  552                           *
 446  553                           * total = 5
 447  554                           */
 448      -                        args->auxsize = (9 + 5) * sizeof (aux_entry_t);
      555 +                        args->auxsize = (10 + 5) * sizeof (aux_entry_t);
 449  556                  } else if (hasdy) {
 450  557                          /*
 451  558                           * Has PT_INTERP but no PT_PHDR
 452  559                           *
 453  560                           *      AT_EXECFD
 454  561                           *      AT_LDDATA
 455  562                           *
 456  563                           * total = 2
 457  564                           */
 458      -                        args->auxsize = (9 + 2) * sizeof (aux_entry_t);
      565 +                        args->auxsize = (10 + 2) * sizeof (aux_entry_t);
 459  566                  } else {
 460      -                        args->auxsize = 9 * sizeof (aux_entry_t);
      567 +                        args->auxsize = 10 * sizeof (aux_entry_t);
 461  568                  }
 462  569          } else {
 463  570                  args->auxsize = 0;
 464  571          }
 465  572  
 466  573          /*
 467  574           * If this binary is using an emulator, we need to add an
 468  575           * AT_SUN_EMULATOR aux entry.
 469  576           */
 470  577          if (args->emulator != NULL)
 471  578                  args->auxsize += sizeof (aux_entry_t);
 472  579  
 473      -        if ((brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
      580 +        /*
      581 +         * If this is a native binary that's been given a modified interpreter
      582 +         * root, inform it that the native system exists at that root.
      583 +         */
      584 +        if (args->brand_nroot != NULL) {
      585 +                args->auxsize += sizeof (aux_entry_t);
      586 +        }
      587 +
      588 +
      589 +        /*
      590 +         * On supported kernels (x86_64) make room in the auxv for the
      591 +         * AT_SUN_COMMPAGE entry.  This will go unpopulated on i86xpv systems
      592 +         * which do not provide such functionality.
      593 +         */
      594 +#if defined(__amd64)
      595 +        args->auxsize += sizeof (aux_entry_t);
      596 +#endif /* defined(__amd64) */
      597 +
      598 +        /*
      599 +         * If we have user credentials, we'll supply the following entries:
      600 +         *      AT_SUN_UID
      601 +         *      AT_SUN_RUID
      602 +         *      AT_SUN_GID
      603 +         *      AT_SUN_RGID
      604 +         */
      605 +        if (cred != NULL) {
      606 +                args->auxsize += 4 * sizeof (aux_entry_t);
      607 +        }
      608 +
      609 +        if ((*brand_action != EBA_NATIVE) && (PROC_IS_BRANDED(p))) {
 474  610                  branded = 1;
 475  611                  /*
 476      -                 * We will be adding 4 entries to the aux vectors.  One for
 477      -                 * the the brandname and 3 for the brand specific aux vectors.
      612 +                 * We will be adding 5 entries to the aux vectors.  One for
      613 +                 * the the brandname and 4 for the brand specific aux vectors.
 478  614                   */
 479      -                args->auxsize += 4 * sizeof (aux_entry_t);
      615 +                args->auxsize += 5 * sizeof (aux_entry_t);
 480  616          }
 481  617  
 482  618          /* Hardware/Software capabilities */
 483  619          if (capphdr != NULL &&
 484  620              (capsize = capphdr->p_filesz) > 0 &&
 485  621              capsize <= 16 * sizeof (*cap)) {
 486  622                  int ncaps = capsize / sizeof (*cap);
 487  623                  Cap *cp;
 488  624  
 489  625                  cap = kmem_alloc(capsize, KM_SLEEP);
↓ open down ↓ 37 lines elided ↑ open up ↑
 527  663          else
 528  664                  len = 0;
 529  665  
 530  666          dtrphdr = NULL;
 531  667  
 532  668          if ((error = mapelfexec(vp, ehdrp, nphdrs, phdrbase, &uphdr, &dyphdr,
 533  669              &stphdr, &dtrphdr, dataphdrp, &bssbase, &brkbase, &voffset, NULL,
 534  670              len, execsz, &brksize)) != 0)
 535  671                  goto bad;
 536  672  
      673 +        if (uphdr != NULL) {
      674 +                /*
      675 +                 * Our uphdr has been dynamically allocated if (and only if)
      676 +                 * its program header flags are clear.
      677 +                 */
      678 +                dynuphdr = (uphdr->p_flags == 0);
      679 +        }
      680 +
 537  681          if (uphdr != NULL && dyphdr == NULL)
 538  682                  goto bad;
 539  683  
 540  684          if (dtrphdr != NULL && dtrace_safe_phdr(dtrphdr, args, voffset) != 0) {
 541  685                  uprintf("%s: Bad DTrace phdr in %s\n", exec_file, exec_file);
 542  686                  goto bad;
 543  687          }
 544  688  
 545  689          if (dyphdr != NULL) {
 546  690                  size_t          len;
 547  691                  uintptr_t       lddata;
 548  692                  char            *p;
 549  693                  struct vnode    *nvp;
 550  694  
 551      -                dlnsize = dyphdr->p_filesz;
      695 +                dlnsize = dyphdr->p_filesz + nsize;
 552  696  
 553  697                  if (dlnsize > MAXPATHLEN || dlnsize <= 0)
 554  698                          goto bad;
 555  699  
      700 +                if (nsize != 0) {
      701 +                        bcopy(args->brand_nroot, dlnp, nsize - 1);
      702 +                        dlnp[nsize - 1] = '/';
      703 +                }
      704 +
 556  705                  /*
 557  706                   * Read in "interpreter" pathname.
 558  707                   */
 559      -                if ((error = vn_rdwr(UIO_READ, vp, dlnp, dyphdr->p_filesz,
 560      -                    (offset_t)dyphdr->p_offset, UIO_SYSSPACE, 0, (rlim64_t)0,
 561      -                    CRED(), &resid)) != 0) {
      708 +                if ((error = vn_rdwr(UIO_READ, vp, dlnp + nsize,
      709 +                    dyphdr->p_filesz, (offset_t)dyphdr->p_offset, UIO_SYSSPACE,
      710 +                    0, (rlim64_t)0, CRED(), &resid)) != 0) {
 562  711                          uprintf("%s: Cannot obtain interpreter pathname\n",
 563  712                              exec_file);
 564  713                          goto bad;
 565  714                  }
 566  715  
 567  716                  if (resid != 0 || dlnp[dlnsize - 1] != '\0')
 568  717                          goto bad;
 569  718  
 570  719                  /*
 571  720                   * Search for '$ORIGIN' token in interpreter path.
↓ open down ↓ 124 lines elided ↑ open up ↑
 696  845                   * enough to map the "interpreter".
 697  846                   */
 698  847                  if ((len = elfsize(ehdrp, nphdrs, phdrbase, &lddata)) == 0) {
 699  848                          VN_RELE(nvp);
 700  849                          uprintf("%s: Nothing to load in %s\n", exec_file, dlnp);
 701  850                          goto bad;
 702  851                  }
 703  852  
 704  853                  dtrphdr = NULL;
 705  854  
 706      -                error = mapelfexec(nvp, ehdrp, nphdrs, phdrbase, &junk, &junk,
      855 +                error = mapelfexec(nvp, ehdrp, nphdrs, phdrbase, NULL, &junk,
 707  856                      &junk, &dtrphdr, NULL, NULL, NULL, &voffset, NULL, len,
 708  857                      execsz, NULL);
      858 +
 709  859                  if (error || junk != NULL) {
 710  860                          VN_RELE(nvp);
 711  861                          uprintf("%s: Cannot map %s\n", exec_file, dlnp);
 712  862                          goto bad;
 713  863                  }
 714  864  
 715  865                  /*
 716  866                   * We use the DTrace program header to initialize the
 717  867                   * architecture-specific user per-LWP location. The dtrace
 718  868                   * fasttrap provider requires ready access to per-LWP scratch
↓ open down ↓ 6 lines elided ↑ open up ↑
 725  875                          uprintf("%s: Bad DTrace phdr in %s\n", exec_file, dlnp);
 726  876                          goto bad;
 727  877                  }
 728  878  
 729  879                  VN_RELE(nvp);
 730  880                  ADDAUX(aux, AT_SUN_LDDATA, voffset + lddata)
 731  881          }
 732  882  
 733  883          if (hasauxv) {
 734  884                  int auxf = AF_SUN_HWCAPVERIFY;
      885 +
 735  886                  /*
 736      -                 * Note: AT_SUN_PLATFORM and AT_SUN_EXECNAME were filled in via
      887 +                 * Note: AT_SUN_PLATFORM and AT_RANDOM were filled in via
 737  888                   * exec_args()
 738  889                   */
 739  890                  ADDAUX(aux, AT_BASE, voffset)
 740  891                  ADDAUX(aux, AT_FLAGS, at_flags)
 741  892                  ADDAUX(aux, AT_PAGESZ, PAGESIZE)
 742  893                  /*
 743  894                   * Linker flags. (security)
 744  895                   * p_flag not yet set at this time.
 745  896                   * We rely on gexec() to provide us with the information.
 746  897                   * If the application is set-uid but this is not reflected
↓ open down ↓ 8 lines elided ↑ open up ↑
 755  906                   * If we're running a native process from within a branded
 756  907                   * zone under pfexec then we clear the AF_SUN_SETUGID flag so
 757  908                   * that the native ld.so.1 is able to link with the native
 758  909                   * libraries instead of using the brand libraries that are
 759  910                   * installed in the zone.  We only do this for processes
 760  911                   * which we trust because we see they are already running
 761  912                   * under pfexec (where uid != euid).  This prevents a
 762  913                   * malicious user within the zone from crafting a wrapper to
 763  914                   * run native suid commands with unsecure libraries interposed.
 764  915                   */
 765      -                if ((brand_action == EBA_NATIVE) && (PROC_IS_BRANDED(p) &&
      916 +                if ((*brand_action == EBA_NATIVE) && (PROC_IS_BRANDED(p) &&
 766  917                      (setid &= ~EXECSETID_SETID) != 0))
 767  918                          auxf &= ~AF_SUN_SETUGID;
 768  919  
 769  920                  /*
 770  921                   * Record the user addr of the auxflags aux vector entry
 771  922                   * since brands may optionally want to manipulate this field.
 772  923                   */
 773  924                  args->auxp_auxflags =
 774  925                      (char *)((char *)args->stackend +
 775  926                      ((char *)&aux->a_type -
 776  927                      (char *)bigwad->elfargs));
 777  928                  ADDAUX(aux, AT_SUN_AUXFLAGS, auxf);
      929 +
 778  930                  /*
      931 +                 * Record information about the real and effective user and
      932 +                 * group IDs.
      933 +                 */
      934 +                if (cred != NULL) {
      935 +                        ADDAUX(aux, AT_SUN_UID, crgetuid(cred));
      936 +                        ADDAUX(aux, AT_SUN_RUID, crgetruid(cred));
      937 +                        ADDAUX(aux, AT_SUN_GID, crgetgid(cred));
      938 +                        ADDAUX(aux, AT_SUN_RGID, crgetrgid(cred));
      939 +                }
      940 +
      941 +                /*
 779  942                   * Hardware capability flag word (performance hints)
 780  943                   * Used for choosing faster library routines.
 781  944                   * (Potentially different between 32-bit and 64-bit ABIs)
 782  945                   */
 783  946  #if defined(_LP64)
 784  947                  if (args->to_model == DATAMODEL_NATIVE) {
 785  948                          ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap)
 786  949                          ADDAUX(aux, AT_SUN_HWCAP2, auxv_hwcap_2)
 787  950                  } else {
 788  951                          ADDAUX(aux, AT_SUN_HWCAP, auxv_hwcap32)
↓ open down ↓ 8 lines elided ↑ open up ↑
 797  960                           * Reserve space for the brand-private aux vectors,
 798  961                           * and record the user addr of that space.
 799  962                           */
 800  963                          args->auxp_brand =
 801  964                              (char *)((char *)args->stackend +
 802  965                              ((char *)&aux->a_type -
 803  966                              (char *)bigwad->elfargs));
 804  967                          ADDAUX(aux, AT_SUN_BRAND_AUX1, 0)
 805  968                          ADDAUX(aux, AT_SUN_BRAND_AUX2, 0)
 806  969                          ADDAUX(aux, AT_SUN_BRAND_AUX3, 0)
      970 +                        ADDAUX(aux, AT_SUN_BRAND_AUX4, 0)
 807  971                  }
 808  972  
      973 +                /*
      974 +                 * Add the comm page auxv entry, mapping it in if needed.
      975 +                 */
      976 +#if defined(__amd64)
      977 +                if (args->commpage != NULL ||
      978 +                    (args->commpage = (uintptr_t)comm_page_mapin()) != NULL) {
      979 +                        ADDAUX(aux, AT_SUN_COMMPAGE, args->commpage)
      980 +                } else {
      981 +                        /*
      982 +                         * If the comm page cannot be mapped, pad out the auxv
      983 +                         * to satisfy later size checks.
      984 +                         */
      985 +                        ADDAUX(aux, AT_NULL, 0)
      986 +                }
      987 +#endif /* defined(__amd64) */
      988 +
 809  989                  ADDAUX(aux, AT_NULL, 0)
 810  990                  postfixsize = (char *)aux - (char *)bigwad->elfargs;
 811  991  
 812  992                  /*
 813  993                   * We make assumptions above when we determine how many aux
 814  994                   * vector entries we will be adding. However, if we have an
 815  995                   * invalid elf file, it is possible that mapelfexec might
 816  996                   * behave differently (but not return an error), in which case
 817  997                   * the number of aux entries we actually add will be different.
 818  998                   * We detect that now and error out.
↓ open down ↓ 19 lines elided ↑ open up ↑
 838 1018              (roundlimit < limit && *execsz > limit)) {
 839 1019                  mutex_enter(&p->p_lock);
 840 1020                  (void) rctl_action(rctlproc_legacy[RLIMIT_VMEM], p->p_rctls, p,
 841 1021                      RCA_SAFE);
 842 1022                  mutex_exit(&p->p_lock);
 843 1023                  error = ENOMEM;
 844 1024                  goto bad;
 845 1025          }
 846 1026  
 847 1027          bzero(up->u_auxv, sizeof (up->u_auxv));
     1028 +        up->u_commpagep = args->commpage;
 848 1029          if (postfixsize) {
 849 1030                  int num_auxv;
 850 1031  
 851 1032                  /*
 852 1033                   * Copy the aux vector to the user stack.
 853 1034                   */
 854 1035                  error = execpoststack(args, bigwad->elfargs, postfixsize);
 855 1036                  if (error)
 856 1037                          goto bad;
 857 1038  
↓ open down ↓ 46 lines elided ↑ open up ↑
 904 1085  
 905 1086  bad:
 906 1087          if (fd != -1)           /* did we open the a.out yet */
 907 1088                  (void) execclose(fd);
 908 1089  
 909 1090          psignal(p, SIGKILL);
 910 1091  
 911 1092          if (error == 0)
 912 1093                  error = ENOEXEC;
 913 1094  out:
     1095 +        if (dynuphdr)
     1096 +                kmem_free(uphdr, sizeof (Phdr));
 914 1097          if (phdrbase != NULL)
 915 1098                  kmem_free(phdrbase, phdrsize);
 916 1099          if (cap != NULL)
 917 1100                  kmem_free(cap, capsize);
 918 1101          kmem_free(bigwad, sizeof (struct bigwad));
 919 1102          return (error);
 920 1103  }
 921 1104  
 922 1105  /*
 923 1106   * Compute the memory size requirement for the ELF file.
↓ open down ↓ 246 lines elided ↑ open up ↑
1170 1353  
1171 1354          /*
1172 1355           * Make sure the strtab is null-terminated to make sure we
1173 1356           * don't run off the end of the table.
1174 1357           */
1175 1358          (*shstrbasep)[*shstrsizep - 1] = '\0';
1176 1359  
1177 1360          return (0);
1178 1361  }
1179 1362  
     1363 +
     1364 +#ifdef _ELF32_COMPAT
     1365 +int
     1366 +elf32readhdr(vnode_t *vp, cred_t *credp, Ehdr *ehdrp, int *nphdrs,
     1367 +    caddr_t *phbasep, ssize_t *phsizep)
     1368 +#else
     1369 +int
     1370 +elfreadhdr(vnode_t *vp, cred_t *credp, Ehdr *ehdrp, int *nphdrs,
     1371 +    caddr_t *phbasep, ssize_t *phsizep)
     1372 +#endif
     1373 +{
     1374 +        int error, nshdrs, shstrndx;
     1375 +
     1376 +        if ((error = getelfhead(vp, credp, ehdrp, &nshdrs, &shstrndx,
     1377 +            nphdrs)) != 0 ||
     1378 +            (error = getelfphdr(vp, credp, ehdrp, *nphdrs, phbasep,
     1379 +            phsizep)) != 0) {
     1380 +                return (error);
     1381 +        }
     1382 +        return (0);
     1383 +}
     1384 +
     1385 +
1180 1386  static int
1181 1387  mapelfexec(
1182 1388          vnode_t *vp,
1183 1389          Ehdr *ehdr,
1184 1390          int nphdrs,
1185 1391          caddr_t phdrbase,
1186 1392          Phdr **uphdr,
1187 1393          Phdr **dyphdr,
1188 1394          Phdr **stphdr,
1189 1395          Phdr **dtphdr,
1190 1396          Phdr *dataphdrp,
1191 1397          caddr_t *bssbase,
1192 1398          caddr_t *brkbase,
1193 1399          intptr_t *voffset,
1194 1400          intptr_t *minaddr,
1195 1401          size_t len,
1196 1402          long *execsz,
1197 1403          size_t *brksize)
1198 1404  {
1199 1405          Phdr *phdr;
1200      -        int i, prot, error;
     1406 +        int i, prot, error, lastprot = 0;
1201 1407          caddr_t addr = NULL;
1202 1408          size_t zfodsz;
1203 1409          int ptload = 0;
1204 1410          int page;
1205 1411          off_t offset;
1206 1412          int hsize = ehdr->e_phentsize;
1207 1413          caddr_t mintmp = (caddr_t)-1;
     1414 +        uintptr_t lastaddr = NULL;
1208 1415          extern int use_brk_lpg;
1209 1416  
1210 1417          if (ehdr->e_type == ET_DYN) {
1211      -                /*
1212      -                 * Obtain the virtual address of a hole in the
1213      -                 * address space to map the "interpreter".
1214      -                 */
1215      -                map_addr(&addr, len, (offset_t)0, 1, 0);
1216      -                if (addr == NULL)
1217      -                        return (ENOMEM);
1218      -                *voffset = (intptr_t)addr;
     1418 +                caddr_t vaddr;
1219 1419  
1220 1420                  /*
1221      -                 * Calculate the minimum vaddr so it can be subtracted out.
1222      -                 * According to the ELF specification, since PT_LOAD sections
1223      -                 * must be sorted by increasing p_vaddr values, this is
1224      -                 * guaranteed to be the first PT_LOAD section.
     1421 +                 * Despite the fact that mmapobj(2) refuses to load them, we
     1422 +                 * need to support executing ET_DYN objects that have a
     1423 +                 * non-NULL p_vaddr.  When found in the wild, these objects
     1424 +                 * are likely to be due to an old (and largely obviated) Linux
     1425 +                 * facility, prelink(8), that rewrites shared objects to
     1426 +                 * prefer specific (disjoint) virtual address ranges.  (Yes,
     1427 +                 * this is putatively for performance -- and yes, it has
     1428 +                 * limited applicability, many edge conditions and grisly
     1429 +                 * failure modes; even for Linux, it's insane.)  As ELF
     1430 +                 * mandates that the PT_LOAD segments be in p_vaddr order, we
     1431 +                 * find the lowest p_vaddr by finding the first PT_LOAD
     1432 +                 * segment.
1225 1433                   */
1226 1434                  phdr = (Phdr *)phdrbase;
1227 1435                  for (i = nphdrs; i > 0; i--) {
1228 1436                          if (phdr->p_type == PT_LOAD) {
1229      -                                *voffset -= (uintptr_t)phdr->p_vaddr;
     1437 +                                addr = (caddr_t)(uintptr_t)phdr->p_vaddr;
1230 1438                                  break;
1231 1439                          }
1232 1440                          phdr = (Phdr *)((caddr_t)phdr + hsize);
1233 1441                  }
1234 1442  
     1443 +                /*
     1444 +                 * We have a non-zero p_vaddr in the first PT_LOAD segment --
     1445 +                 * presumably because we're directly executing a prelink(8)'d
     1446 +                 * ld-linux.so.  While we could correctly execute such an
     1447 +                 * object without locating it at its desired p_vaddr (it is,
     1448 +                 * after all, still relocatable), our inner antiquarian
     1449 +                 * derives a perverse pleasure in accommodating the steampunk
     1450 +                 * prelink(8) contraption -- goggles on!
     1451 +                 */
     1452 +                if ((vaddr = addr) != NULL) {
     1453 +                        if (as_gap(curproc->p_as, len,
     1454 +                            &addr, &len, AH_LO, NULL) == -1 || addr != vaddr) {
     1455 +                                addr = NULL;
     1456 +                        }
     1457 +                }
     1458 +
     1459 +                if (addr == NULL) {
     1460 +                        /*
     1461 +                         * We either have a NULL p_vaddr (the common case, by
     1462 +                         * many orders of magnitude) or we have a non-NULL
     1463 +                         * p_vaddr and we were unable to obtain the specified
     1464 +                         * VA range (presumably because it's an illegal
     1465 +                         * address).  Either way, obtain an address in which
     1466 +                         * to map the interpreter.
     1467 +                         */
     1468 +                        map_addr(&addr, len, (offset_t)0, 1, 0);
     1469 +                        if (addr == NULL)
     1470 +                                return (ENOMEM);
     1471 +                }
     1472 +
     1473 +                /*
     1474 +                 * Our voffset is the difference between where we landed and
     1475 +                 * where we wanted to be.
     1476 +                 */
     1477 +                *voffset = (uintptr_t)addr - (uintptr_t)vaddr;
1235 1478          } else {
1236 1479                  *voffset = 0;
1237 1480          }
     1481 +
1238 1482          phdr = (Phdr *)phdrbase;
1239 1483          for (i = nphdrs; i > 0; i--) {
1240 1484                  switch (phdr->p_type) {
1241 1485                  case PT_LOAD:
1242      -                        if ((*dyphdr != NULL) && (*uphdr == NULL))
1243      -                                return (0);
1244      -
1245 1486                          ptload = 1;
1246 1487                          prot = PROT_USER;
1247 1488                          if (phdr->p_flags & PF_R)
1248 1489                                  prot |= PROT_READ;
1249 1490                          if (phdr->p_flags & PF_W)
1250 1491                                  prot |= PROT_WRITE;
1251 1492                          if (phdr->p_flags & PF_X)
1252 1493                                  prot |= PROT_EXEC;
1253 1494  
1254 1495                          addr = (caddr_t)((uintptr_t)phdr->p_vaddr + *voffset);
1255 1496  
     1497 +                        if ((*dyphdr != NULL) && uphdr != NULL &&
     1498 +                            (*uphdr == NULL)) {
     1499 +                                /*
     1500 +                                 * The PT_PHDR program header is, strictly
     1501 +                                 * speaking, optional.  If we find that this
     1502 +                                 * is missing, we will determine the location
     1503 +                                 * of the program headers based on the address
     1504 +                                 * of the lowest PT_LOAD segment (namely, this
     1505 +                                 * one):  we subtract the p_offset to get to
     1506 +                                 * the ELF header and then add back the program
     1507 +                                 * header offset to get to the program headers.
     1508 +                                 * We then cons up a Phdr that corresponds to
     1509 +                                 * the (missing) PT_PHDR, setting the flags
     1510 +                                 * to 0 to denote that this is artificial and
     1511 +                                 * should (must) be freed by the caller.
     1512 +                                 */
     1513 +                                Phdr *cons;
     1514 +
     1515 +                                cons = kmem_zalloc(sizeof (Phdr), KM_SLEEP);
     1516 +
     1517 +                                cons->p_flags = 0;
     1518 +                                cons->p_type = PT_PHDR;
     1519 +                                cons->p_vaddr = ((uintptr_t)addr -
     1520 +                                    phdr->p_offset) + ehdr->e_phoff;
     1521 +
     1522 +                                *uphdr = cons;
     1523 +                        }
     1524 +
1256 1525                          /*
1257 1526                           * Keep track of the segment with the lowest starting
1258 1527                           * address.
1259 1528                           */
1260 1529                          if (addr < mintmp)
1261 1530                                  mintmp = addr;
1262 1531  
     1532 +                        /*
     1533 +                         * Segments need not correspond to page boundaries:
     1534 +                         * they are permitted to share a page.  If two PT_LOAD
     1535 +                         * segments share the same page, and the permissions
     1536 +                         * of the segments differ, the behavior is historically
     1537 +                         * that the permissions of the latter segment are used
     1538 +                         * for the page that the two segments share.  This is
     1539 +                         * also historically a non-issue:  binaries generated
     1540 +                         * by most anything will make sure that two PT_LOAD
     1541 +                         * segments with differing permissions don't actually
     1542 +                         * share any pages.  However, there exist some crazy
     1543 +                         * things out there (including at least an obscure
     1544 +                         * Portuguese teaching language called G-Portugol) that
     1545 +                         * actually do the wrong thing and expect it to work:
     1546 +                         * they have a segment with execute permission share
     1547 +                         * a page with a subsequent segment that does not
     1548 +                         * have execute permissions and expect the resulting
     1549 +                         * shared page to in fact be executable.  To accommodate
     1550 +                         * such broken link editors, we take advantage of a
     1551 +                         * latitude explicitly granted to the loader:  it is
     1552 +                         * permitted to make _any_ PT_LOAD segment executable
     1553 +                         * (provided that it is readable or writable).  If we
     1554 +                         * see that we're sharing a page and that the previous
     1555 +                         * page was executable, we will add execute permissions
     1556 +                         * to our segment.
     1557 +                         */
     1558 +                        if (btop(lastaddr) == btop((uintptr_t)addr) &&
     1559 +                            (phdr->p_flags & (PF_R | PF_W)) &&
     1560 +                            (lastprot & PROT_EXEC)) {
     1561 +                                prot |= PROT_EXEC;
     1562 +                        }
     1563 +
     1564 +                        lastaddr = (uintptr_t)addr + phdr->p_filesz;
     1565 +                        lastprot = prot;
     1566 +
1263 1567                          zfodsz = (size_t)phdr->p_memsz - phdr->p_filesz;
1264 1568  
1265 1569                          offset = phdr->p_offset;
1266 1570                          if (((uintptr_t)offset & PAGEOFFSET) ==
1267 1571                              ((uintptr_t)addr & PAGEOFFSET) &&
1268 1572                              (!(vp->v_flag & VNOMAP))) {
1269 1573                                  page = 1;
1270 1574                          } else {
1271 1575                                  page = 0;
1272 1576                          }
↓ open down ↓ 44 lines elided ↑ open up ↑
1317 1621                                  *bssbase = addr + phdr->p_filesz;
1318 1622                          }
1319 1623                          if (brkbase != NULL && addr >= *brkbase) {
1320 1624                                  *brkbase = addr + phdr->p_memsz;
1321 1625                          }
1322 1626  
1323 1627                          *execsz += btopr(phdr->p_memsz);
1324 1628                          break;
1325 1629  
1326 1630                  case PT_INTERP:
1327      -                        if (ptload)
1328      -                                goto bad;
     1631 +                        /*
     1632 +                         * The ELF specification is unequivocal about the
     1633 +                         * PT_INTERP program header with respect to any PT_LOAD
     1634 +                         * program header:  "If it is present, it must precede
     1635 +                         * any loadable segment entry." Linux, however, makes
     1636 +                         * no attempt to enforce this -- which has allowed some
     1637 +                         * binary editing tools to get away with generating
     1638 +                         * invalid ELF binaries in the respect that PT_INTERP
     1639 +                         * occurs after the first PT_LOAD program header.  This
     1640 +                         * is unfortunate (and of course, disappointing) but
     1641 +                         * it's no worse than that: there is no reason that we
     1642 +                         * can't process the PT_INTERP entry (if present) after
     1643 +                         * one or more PT_LOAD entries.  We therefore
     1644 +                         * deliberately do not check ptload here and always
     1645 +                         * store dyphdr to be the PT_INTERP program header.
     1646 +                         */
1329 1647                          *dyphdr = phdr;
1330 1648                          break;
1331 1649  
1332 1650                  case PT_SHLIB:
1333 1651                          *stphdr = phdr;
1334 1652                          break;
1335 1653  
1336 1654                  case PT_PHDR:
1337      -                        if (ptload)
     1655 +                        if (ptload || phdr->p_flags == 0)
1338 1656                                  goto bad;
1339      -                        *uphdr = phdr;
     1657 +
     1658 +                        if (uphdr != NULL)
     1659 +                                *uphdr = phdr;
     1660 +
1340 1661                          break;
1341 1662  
1342 1663                  case PT_NULL:
1343 1664                  case PT_DYNAMIC:
1344 1665                  case PT_NOTE:
1345 1666                          break;
1346 1667  
1347 1668                  case PT_SUNWDTRACE:
1348 1669                          if (dtphdr != NULL)
1349 1670                                  *dtphdr = phdr;
↓ open down ↓ 828 lines elided ↑ open up ↑
2178 2499  };
2179 2500  
2180 2501  static struct modlexec modlexec = {
2181 2502          &mod_execops, "exec module for elf", &esw
2182 2503  };
2183 2504  
2184 2505  #ifdef  _LP64
2185 2506  extern int elf32exec(vnode_t *vp, execa_t *uap, uarg_t *args,
2186 2507                          intpdata_t *idatap, int level, long *execsz,
2187 2508                          int setid, caddr_t exec_file, cred_t *cred,
2188      -                        int brand_action);
     2509 +                        int *brand_action);
2189 2510  extern int elf32core(vnode_t *vp, proc_t *p, cred_t *credp,
2190 2511                          rlim64_t rlimit, int sig, core_content_t content);
2191 2512  
2192 2513  static struct execsw esw32 = {
2193 2514          elf32magicstr,
2194 2515          0,
2195 2516          5,
2196 2517          elf32exec,
2197 2518          elf32core
2198 2519  };
↓ open down ↓ 34 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX