Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.


  52 #include <sys/lgrp.h>
  53 #include <sys/vtrace.h>
  54 #include <sys/exec.h>
  55 #include <sys/exechdr.h>
  56 #include <sys/kmem.h>
  57 #include <sys/prsystm.h>
  58 #include <sys/modctl.h>
  59 #include <sys/vmparam.h>
  60 #include <sys/door.h>
  61 #include <sys/schedctl.h>
  62 #include <sys/utrap.h>
  63 #include <sys/systeminfo.h>
  64 #include <sys/stack.h>
  65 #include <sys/rctl.h>
  66 #include <sys/dtrace.h>
  67 #include <sys/lwpchan_impl.h>
  68 #include <sys/pool.h>
  69 #include <sys/sdt.h>
  70 #include <sys/brand.h>
  71 #include <sys/klpd.h>

  72 
  73 #include <c2/audit.h>
  74 
  75 #include <vm/hat.h>
  76 #include <vm/anon.h>
  77 #include <vm/as.h>
  78 #include <vm/seg.h>
  79 #include <vm/seg_vn.h>
  80 
  81 #define PRIV_RESET              0x01    /* needs to reset privs */
  82 #define PRIV_SETID              0x02    /* needs to change uids */
  83 #define PRIV_SETUGID            0x04    /* is setuid/setgid/forced privs */
  84 #define PRIV_INCREASE           0x08    /* child runs with more privs */
  85 #define MAC_FLAGS               0x10    /* need to adjust MAC flags */
  86 #define PRIV_FORCED             0x20    /* has forced privileges */
  87 
  88 static int execsetid(struct vnode *, struct vattr *, uid_t *, uid_t *,
  89     priv_set_t *, cred_t *, const char *);
  90 static int hold_execsw(struct execsw *);
  91 
  92 uint_t auxv_hwcap = 0;  /* auxv AT_SUN_HWCAP value; determined on the fly */
  93 uint_t auxv_hwcap_2 = 0;        /* AT_SUN_HWCAP2 */
  94 #if defined(_SYSCALL32_IMPL)
  95 uint_t auxv_hwcap32 = 0;        /* 32-bit version of auxv_hwcap */
  96 uint_t auxv_hwcap32_2 = 0;      /* 32-bit version of auxv_hwcap2 */
  97 #endif
  98 
  99 #define PSUIDFLAGS              (SNOCD|SUGID)
 100 
 101 /*















 102  * exece() - system call wrapper around exec_common()
 103  */
 104 int
 105 exece(const char *fname, const char **argp, const char **envp)
 106 {
 107         int error;
 108 
 109         error = exec_common(fname, argp, envp, EBA_NONE);
 110         return (error ? (set_errno(error)) : 0);
 111 }
 112 
 113 int
 114 exec_common(const char *fname, const char **argp, const char **envp,
 115     int brand_action)
 116 {
 117         vnode_t *vp = NULL, *dir = NULL, *tmpvp = NULL;
 118         proc_t *p = ttoproc(curthread);
 119         klwp_t *lwp = ttolwp(curthread);
 120         struct user *up = PTOU(p);
 121         long execsz;            /* temporary count of exec size */


 543         int level,
 544         long *execsz,
 545         caddr_t exec_file,
 546         struct cred *cred,
 547         int brand_action)
 548 {
 549         struct vnode *vp, *execvp = NULL;
 550         proc_t *pp = ttoproc(curthread);
 551         struct execsw *eswp;
 552         int error = 0;
 553         int suidflags = 0;
 554         ssize_t resid;
 555         uid_t uid, gid;
 556         struct vattr vattr;
 557         char magbuf[MAGIC_BYTES];
 558         int setid;
 559         cred_t *oldcred, *newcred = NULL;
 560         int privflags = 0;
 561         int setidfl;
 562         priv_set_t fset;



 563 
 564         /*
 565          * If the SNOCD or SUGID flag is set, turn it off and remember the
 566          * previous setting so we can restore it if we encounter an error.
 567          */
 568         if (level == 0 && (pp->p_flag & PSUIDFLAGS)) {
 569                 mutex_enter(&pp->p_lock);
 570                 suidflags = pp->p_flag & PSUIDFLAGS;
 571                 pp->p_flag &= ~PSUIDFLAGS;
 572                 mutex_exit(&pp->p_lock);
 573         }
 574 
 575         if ((error = execpermissions(*vpp, &vattr, args)) != 0)
 576                 goto bad_noclose;
 577 
 578         /* need to open vnode for stateful file systems */
 579         if ((error = VOP_OPEN(vpp, FREAD, CRED(), NULL)) != 0)
 580                 goto bad_noclose;
 581         vp = *vpp;
 582 


 643                                 priv_intersect(&CR_OPPRIV(cred), &fset);
 644                         }
 645                         priv_intersect(&CR_LPRIV(cred), &CR_IPRIV(cred));
 646                         CR_EPRIV(cred) = CR_PPRIV(cred) = CR_IPRIV(cred);
 647                         if (privflags & PRIV_FORCED) {
 648                                 priv_set_PA(cred);
 649                                 priv_union(&fset, &CR_EPRIV(cred));
 650                                 priv_union(&fset, &CR_PPRIV(cred));
 651                         }
 652                         priv_adjust_PA(cred);
 653                 }
 654         } else if (level == 0 && args->pfcred != NULL) {
 655                 newcred = cred = args->pfcred;
 656                 privflags |= PRIV_INCREASE;
 657                 /* pfcred is not forced to adhere to these settings */
 658                 priv_intersect(&CR_LPRIV(cred), &CR_IPRIV(cred));
 659                 CR_EPRIV(cred) = CR_PPRIV(cred) = CR_IPRIV(cred);
 660                 priv_adjust_PA(cred);
 661         }
 662 



 663         /* SunOS 4.x buy-back */
 664         if ((vp->v_vfsp->vfs_flag & VFS_NOSETUID) &&
 665             (vattr.va_mode & (VSUID|VSGID))) {
 666                 char path[MAXNAMELEN];
 667                 refstr_t *mntpt = NULL;
 668                 int ret = -1;
 669 
 670                 bzero(path, sizeof (path));
 671                 zone_hold(pp->p_zone);
 672 
 673                 ret = vnodetopath(pp->p_zone->zone_rootvp, vp, path,
 674                     sizeof (path), cred);
 675 
 676                 /* fallback to mountpoint if a path can't be found */
 677                 if ((ret != 0) || (ret == 0 && path[0] == '\0'))
 678                         mntpt = vfs_getmntpoint(vp->v_vfsp);
 679 
 680                 if (mntpt == NULL)
 681                         zcmn_err(pp->p_zone->zone_id, CE_NOTE,
 682                             "!uid %d: setuid execution not allowed, "


 703                                     exec_file);
 704                 }
 705 
 706                 if (mntpt != NULL)
 707                         refstr_rele(mntpt);
 708 
 709                 zone_rele(pp->p_zone);
 710         }
 711 
 712         /*
 713          * execsetid() told us whether or not we had to change the
 714          * credentials of the process.  In privflags, it told us
 715          * whether we gained any privileges or executed a set-uid executable.
 716          */
 717         setid = (privflags & (PRIV_SETUGID|PRIV_INCREASE|PRIV_FORCED));
 718 
 719         /*
 720          * Use /etc/system variable to determine if the stack
 721          * should be marked as executable by default.
 722          */
 723         if (noexec_user_stack)

 724                 args->stk_prot &= ~PROT_EXEC;
 725 
 726         args->execswp = eswp; /* Save execsw pointer in uarg for exec_func */
 727         args->ex_vp = vp;
 728 
 729         /*
 730          * Traditionally, the setid flags told the sub processes whether
 731          * the file just executed was set-uid or set-gid; this caused
 732          * some confusion as the 'setid' flag did not match the SUGID
 733          * process flag which is only set when the uids/gids do not match.
 734          * A script set-gid/set-uid to the real uid/gid would start with
 735          * /dev/fd/X but an executable would happily trust LD_LIBRARY_PATH.
 736          * Now we flag those cases where the calling process cannot
 737          * be trusted to influence the newly exec'ed process, either
 738          * because it runs with more privileges or when the uids/gids
 739          * do in fact not match.
 740          * This also makes the runtime linker agree with the on exec
 741          * values of SNOCD and SUGID.
 742          */
 743         setidfl = 0;


 789                 oruid = pp->p_cred->cr_ruid;
 790 
 791                 if (newcred != NULL) {
 792                         /*
 793                          * Free the old credentials, and set the new ones.
 794                          * Do this for both the process and the (single) thread.
 795                          */
 796                         crfree(pp->p_cred);
 797                         pp->p_cred = cred;   /* cred already held for proc */
 798                         crhold(cred);           /* hold new cred for thread */
 799                         /*
 800                          * DTrace accesses t_cred in probe context.  t_cred
 801                          * must always be either NULL, or point to a valid,
 802                          * allocated cred structure.
 803                          */
 804                         oldcred = curthread->t_cred;
 805                         curthread->t_cred = cred;
 806                         crfree(oldcred);
 807 
 808                         if (priv_basic_test >= 0 &&
 809                             !PRIV_ISASSERT(&CR_IPRIV(newcred),
 810                             priv_basic_test)) {
 811                                 pid_t pid = pp->p_pid;
 812                                 char *fn = PTOU(pp)->u_comm;
 813 
 814                                 cmn_err(CE_WARN, "%s[%d]: exec: basic_test "
 815                                     "privilege removed from E/I", fn, pid);
 816                         }
 817                 }
 818                 /*
 819                  * On emerging from a successful exec(), the saved
 820                  * uid and gid equal the effective uid and gid.
 821                  */
 822                 cred->cr_suid = cred->cr_uid;
 823                 cred->cr_sgid = cred->cr_gid;
 824 
 825                 /*
 826                  * If the real and effective ids do not match, this
 827                  * is a setuid process that should not dump core.
 828                  * The group comparison is tricky; we prevent the code
 829                  * from flagging SNOCD when executing with an effective gid


 859                                 args->traceinval = 1;
 860                 }
 861                 if (pp->p_proc_flag & P_PR_PTRACE)
 862                         psignal(pp, SIGTRAP);
 863                 if (args->traceinval)
 864                         prinvalidate(&pp->p_user);
 865         }
 866         if (execvp)
 867                 VN_RELE(execvp);
 868         return (0);
 869 
 870 bad:
 871         (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL);
 872 
 873 bad_noclose:
 874         if (newcred != NULL)
 875                 crfree(newcred);
 876         if (error == 0)
 877                 error = ENOEXEC;
 878 
 879         if (suidflags) {
 880                 mutex_enter(&pp->p_lock);

 881                 pp->p_flag |= suidflags;
 882                 mutex_exit(&pp->p_lock);
 883         }







 884         return (error);
 885 }
 886 
 887 extern char *execswnames[];
 888 
 889 struct execsw *
 890 allocate_execsw(char *name, char *magic, size_t magic_size)
 891 {
 892         int i, j;
 893         char *ename;
 894         char *magicp;
 895 
 896         mutex_enter(&execsw_lock);
 897         for (i = 0; i < nexectype; i++) {
 898                 if (execswnames[i] == NULL) {
 899                         ename = kmem_alloc(strlen(name) + 1, KM_SLEEP);
 900                         (void) strcpy(ename, name);
 901                         execswnames[i] = ename;
 902                         /*
 903                          * Set the magic number last so that we


1770                                     AT_SUN_EMULATOR, (long)&ustrp[*--offp])
1771                 } else {
1772                         auxv32_t **a = (auxv32_t **)auxvpp;
1773                         ADDAUX(*a,
1774                             AT_SUN_PLATFORM, (int)(uintptr_t)&ustrp[*--offp])
1775                         ADDAUX(*a,
1776                             AT_SUN_EXECNAME, (int)(uintptr_t)&ustrp[*--offp])
1777                         if (args->brandname != NULL)
1778                                 ADDAUX(*a, AT_SUN_BRANDNAME,
1779                                     (int)(uintptr_t)&ustrp[*--offp])
1780                         if (args->emulator != NULL)
1781                                 ADDAUX(*a, AT_SUN_EMULATOR,
1782                                     (int)(uintptr_t)&ustrp[*--offp])
1783                 }
1784         }
1785 
1786         return (0);
1787 }
1788 
1789 /*






































1790  * Initialize a new user stack with the specified arguments and environment.
1791  * The initial user stack layout is as follows:
1792  *
1793  *      User Stack
1794  *      +---------------+ <--- curproc->p_usrstack
1795  *      |               |
1796  *      | slew          |
1797  *      |               |
1798  *      +---------------+
1799  *      | NULL          |
1800  *      +---------------+
1801  *      |               |
1802  *      | auxv strings  |
1803  *      |               |
1804  *      +---------------+
1805  *      |               |
1806  *      | envp strings  |
1807  *      |               |
1808  *      +---------------+
1809  *      |               |


1999         p->p_datprot = args->dat_prot;
2000 
2001         /*
2002          * Reset resource controls such that all controls are again active as
2003          * well as appropriate to the potentially new address model for the
2004          * process.
2005          */
2006         e.rcep_p.proc = p;
2007         e.rcep_t = RCENTITY_PROCESS;
2008         rctl_set_reset(p->p_rctls, p, &e);
2009 
2010         /* Too early to call map_pgsz for the heap */
2011         if (use_stk_lpg) {
2012                 p->p_stkpageszc = page_szc(map_pgsz(MAPPGSZ_STK, p, 0, 0, 0));
2013         }
2014 
2015         mutex_enter(&p->p_lock);
2016         p->p_flag |= SAUTOLPG;       /* kernel controls page sizes */
2017         mutex_exit(&p->p_lock);
2018 
2019         /*
2020          * Some platforms may choose to randomize real stack start by adding a
2021          * small slew (not more than a few hundred bytes) to the top of the
2022          * stack. This helps avoid cache thrashing when identical processes
2023          * simultaneously share caches that don't provide enough associativity
2024          * (e.g. sun4v systems). In this case stack slewing makes the same hot
2025          * stack variables in different processes to live in different cache
2026          * sets increasing effective associativity.
2027          */
2028         sp_slew = exec_get_spslew();
2029         ASSERT(P2PHASE(sp_slew, args->stk_align) == 0);


2030         exec_set_sp(size + sp_slew);
2031 
2032         as = as_alloc();
2033         p->p_as = as;
2034         as->a_proc = p;
2035         if (p->p_model == DATAMODEL_ILP32 || args->addr32)
2036                 as->a_userlimit = (caddr_t)USERLIMIT32;
2037         (void) hat_setup(as->a_hat, HAT_ALLOC);
2038         hat_join_srd(as->a_hat, args->ex_vp);
2039 
2040         /*
2041          * Finally, write out the contents of the new stack.
2042          */
2043         error = stk_copyout(args, usrstack - sp_slew, auxvpp, up);
2044         kmem_free(args->stk_base, args->stk_size);
2045         return (error);
2046 }


  52 #include <sys/lgrp.h>
  53 #include <sys/vtrace.h>
  54 #include <sys/exec.h>
  55 #include <sys/exechdr.h>
  56 #include <sys/kmem.h>
  57 #include <sys/prsystm.h>
  58 #include <sys/modctl.h>
  59 #include <sys/vmparam.h>
  60 #include <sys/door.h>
  61 #include <sys/schedctl.h>
  62 #include <sys/utrap.h>
  63 #include <sys/systeminfo.h>
  64 #include <sys/stack.h>
  65 #include <sys/rctl.h>
  66 #include <sys/dtrace.h>
  67 #include <sys/lwpchan_impl.h>
  68 #include <sys/pool.h>
  69 #include <sys/sdt.h>
  70 #include <sys/brand.h>
  71 #include <sys/klpd.h>
  72 #include <sys/random.h>
  73 
  74 #include <c2/audit.h>
  75 
  76 #include <vm/hat.h>
  77 #include <vm/anon.h>
  78 #include <vm/as.h>
  79 #include <vm/seg.h>
  80 #include <vm/seg_vn.h>
  81 
  82 #define PRIV_RESET              0x01    /* needs to reset privs */
  83 #define PRIV_SETID              0x02    /* needs to change uids */
  84 #define PRIV_SETUGID            0x04    /* is setuid/setgid/forced privs */
  85 #define PRIV_INCREASE           0x08    /* child runs with more privs */
  86 #define MAC_FLAGS               0x10    /* need to adjust MAC flags */
  87 #define PRIV_FORCED             0x20    /* has forced privileges */
  88 
  89 static int execsetid(struct vnode *, struct vattr *, uid_t *, uid_t *,
  90     priv_set_t *, cred_t *, const char *);
  91 static int hold_execsw(struct execsw *);
  92 
  93 uint_t auxv_hwcap = 0;  /* auxv AT_SUN_HWCAP value; determined on the fly */
  94 uint_t auxv_hwcap_2 = 0;        /* AT_SUN_HWCAP2 */
  95 #if defined(_SYSCALL32_IMPL)
  96 uint_t auxv_hwcap32 = 0;        /* 32-bit version of auxv_hwcap */
  97 uint_t auxv_hwcap32_2 = 0;      /* 32-bit version of auxv_hwcap2 */
  98 #endif
  99 
 100 #define PSUIDFLAGS              (SNOCD|SUGID)
 101 
 102 /*
 103  * These are consumed within the specific exec modules, but are defined here
 104  * because
 105  *
 106  * 1) The exec modules are unloadable, which would make this near useless.
 107  *
 108  * 2) We want them to be common across all of them, should more than ELF come
 109  *    to support them.
 110  *
 111  * All must be powers of 2.
 112  */
 113 size_t aslr_max_brk_skew = 16 * 1024 * 1024; /* 16MB */
 114 #pragma weak exec_stackgap = aslr_max_stack_skew /* Old, compatible name */
 115 size_t aslr_max_stack_skew = 64 * 1024; /* 64KB */
 116 
 117 /*
 118  * exece() - system call wrapper around exec_common()
 119  */
 120 int
 121 exece(const char *fname, const char **argp, const char **envp)
 122 {
 123         int error;
 124 
 125         error = exec_common(fname, argp, envp, EBA_NONE);
 126         return (error ? (set_errno(error)) : 0);
 127 }
 128 
 129 int
 130 exec_common(const char *fname, const char **argp, const char **envp,
 131     int brand_action)
 132 {
 133         vnode_t *vp = NULL, *dir = NULL, *tmpvp = NULL;
 134         proc_t *p = ttoproc(curthread);
 135         klwp_t *lwp = ttolwp(curthread);
 136         struct user *up = PTOU(p);
 137         long execsz;            /* temporary count of exec size */


 559         int level,
 560         long *execsz,
 561         caddr_t exec_file,
 562         struct cred *cred,
 563         int brand_action)
 564 {
 565         struct vnode *vp, *execvp = NULL;
 566         proc_t *pp = ttoproc(curthread);
 567         struct execsw *eswp;
 568         int error = 0;
 569         int suidflags = 0;
 570         ssize_t resid;
 571         uid_t uid, gid;
 572         struct vattr vattr;
 573         char magbuf[MAGIC_BYTES];
 574         int setid;
 575         cred_t *oldcred, *newcred = NULL;
 576         int privflags = 0;
 577         int setidfl;
 578         priv_set_t fset;
 579         secflagset_t old_secflags;
 580 
 581         secflags_copy(&old_secflags, &pp->p_secflags.psf_effective);
 582 
 583         /*
 584          * If the SNOCD or SUGID flag is set, turn it off and remember the
 585          * previous setting so we can restore it if we encounter an error.
 586          */
 587         if (level == 0 && (pp->p_flag & PSUIDFLAGS)) {
 588                 mutex_enter(&pp->p_lock);
 589                 suidflags = pp->p_flag & PSUIDFLAGS;
 590                 pp->p_flag &= ~PSUIDFLAGS;
 591                 mutex_exit(&pp->p_lock);
 592         }
 593 
 594         if ((error = execpermissions(*vpp, &vattr, args)) != 0)
 595                 goto bad_noclose;
 596 
 597         /* need to open vnode for stateful file systems */
 598         if ((error = VOP_OPEN(vpp, FREAD, CRED(), NULL)) != 0)
 599                 goto bad_noclose;
 600         vp = *vpp;
 601 


 662                                 priv_intersect(&CR_OPPRIV(cred), &fset);
 663                         }
 664                         priv_intersect(&CR_LPRIV(cred), &CR_IPRIV(cred));
 665                         CR_EPRIV(cred) = CR_PPRIV(cred) = CR_IPRIV(cred);
 666                         if (privflags & PRIV_FORCED) {
 667                                 priv_set_PA(cred);
 668                                 priv_union(&fset, &CR_EPRIV(cred));
 669                                 priv_union(&fset, &CR_PPRIV(cred));
 670                         }
 671                         priv_adjust_PA(cred);
 672                 }
 673         } else if (level == 0 && args->pfcred != NULL) {
 674                 newcred = cred = args->pfcred;
 675                 privflags |= PRIV_INCREASE;
 676                 /* pfcred is not forced to adhere to these settings */
 677                 priv_intersect(&CR_LPRIV(cred), &CR_IPRIV(cred));
 678                 CR_EPRIV(cred) = CR_PPRIV(cred) = CR_IPRIV(cred);
 679                 priv_adjust_PA(cred);
 680         }
 681 
 682         /* The new image gets the inheritable secflags as its secflags */
 683         secflags_promote(pp);
 684 
 685         /* SunOS 4.x buy-back */
 686         if ((vp->v_vfsp->vfs_flag & VFS_NOSETUID) &&
 687             (vattr.va_mode & (VSUID|VSGID))) {
 688                 char path[MAXNAMELEN];
 689                 refstr_t *mntpt = NULL;
 690                 int ret = -1;
 691 
 692                 bzero(path, sizeof (path));
 693                 zone_hold(pp->p_zone);
 694 
 695                 ret = vnodetopath(pp->p_zone->zone_rootvp, vp, path,
 696                     sizeof (path), cred);
 697 
 698                 /* fallback to mountpoint if a path can't be found */
 699                 if ((ret != 0) || (ret == 0 && path[0] == '\0'))
 700                         mntpt = vfs_getmntpoint(vp->v_vfsp);
 701 
 702                 if (mntpt == NULL)
 703                         zcmn_err(pp->p_zone->zone_id, CE_NOTE,
 704                             "!uid %d: setuid execution not allowed, "


 725                                     exec_file);
 726                 }
 727 
 728                 if (mntpt != NULL)
 729                         refstr_rele(mntpt);
 730 
 731                 zone_rele(pp->p_zone);
 732         }
 733 
 734         /*
 735          * execsetid() told us whether or not we had to change the
 736          * credentials of the process.  In privflags, it told us
 737          * whether we gained any privileges or executed a set-uid executable.
 738          */
 739         setid = (privflags & (PRIV_SETUGID|PRIV_INCREASE|PRIV_FORCED));
 740 
 741         /*
 742          * Use /etc/system variable to determine if the stack
 743          * should be marked as executable by default.
 744          */
 745         if ((noexec_user_stack != 0) ||
 746             secflag_enabled(pp, PROC_SEC_NOEXECSTACK))
 747                 args->stk_prot &= ~PROT_EXEC;
 748 
 749         args->execswp = eswp; /* Save execsw pointer in uarg for exec_func */
 750         args->ex_vp = vp;
 751 
 752         /*
 753          * Traditionally, the setid flags told the sub processes whether
 754          * the file just executed was set-uid or set-gid; this caused
 755          * some confusion as the 'setid' flag did not match the SUGID
 756          * process flag which is only set when the uids/gids do not match.
 757          * A script set-gid/set-uid to the real uid/gid would start with
 758          * /dev/fd/X but an executable would happily trust LD_LIBRARY_PATH.
 759          * Now we flag those cases where the calling process cannot
 760          * be trusted to influence the newly exec'ed process, either
 761          * because it runs with more privileges or when the uids/gids
 762          * do in fact not match.
 763          * This also makes the runtime linker agree with the on exec
 764          * values of SNOCD and SUGID.
 765          */
 766         setidfl = 0;


 812                 oruid = pp->p_cred->cr_ruid;
 813 
 814                 if (newcred != NULL) {
 815                         /*
 816                          * Free the old credentials, and set the new ones.
 817                          * Do this for both the process and the (single) thread.
 818                          */
 819                         crfree(pp->p_cred);
 820                         pp->p_cred = cred;   /* cred already held for proc */
 821                         crhold(cred);           /* hold new cred for thread */
 822                         /*
 823                          * DTrace accesses t_cred in probe context.  t_cred
 824                          * must always be either NULL, or point to a valid,
 825                          * allocated cred structure.
 826                          */
 827                         oldcred = curthread->t_cred;
 828                         curthread->t_cred = cred;
 829                         crfree(oldcred);
 830 
 831                         if (priv_basic_test >= 0 &&
 832                             !PRIV_ISMEMBER(&CR_IPRIV(newcred),
 833                             priv_basic_test)) {
 834                                 pid_t pid = pp->p_pid;
 835                                 char *fn = PTOU(pp)->u_comm;
 836 
 837                                 cmn_err(CE_WARN, "%s[%d]: exec: basic_test "
 838                                     "privilege removed from E/I", fn, pid);
 839                         }
 840                 }
 841                 /*
 842                  * On emerging from a successful exec(), the saved
 843                  * uid and gid equal the effective uid and gid.
 844                  */
 845                 cred->cr_suid = cred->cr_uid;
 846                 cred->cr_sgid = cred->cr_gid;
 847 
 848                 /*
 849                  * If the real and effective ids do not match, this
 850                  * is a setuid process that should not dump core.
 851                  * The group comparison is tricky; we prevent the code
 852                  * from flagging SNOCD when executing with an effective gid


 882                                 args->traceinval = 1;
 883                 }
 884                 if (pp->p_proc_flag & P_PR_PTRACE)
 885                         psignal(pp, SIGTRAP);
 886                 if (args->traceinval)
 887                         prinvalidate(&pp->p_user);
 888         }
 889         if (execvp)
 890                 VN_RELE(execvp);
 891         return (0);
 892 
 893 bad:
 894         (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, cred, NULL);
 895 
 896 bad_noclose:
 897         if (newcred != NULL)
 898                 crfree(newcred);
 899         if (error == 0)
 900                 error = ENOEXEC;
 901 

 902         mutex_enter(&pp->p_lock);
 903         if (suidflags) {
 904                 pp->p_flag |= suidflags;

 905         }
 906         /*
 907          * Restore the effective secflags, to maintain the invariant they
 908          * never change for a given process
 909          */
 910         secflags_copy(&pp->p_secflags.psf_effective, &old_secflags);
 911         mutex_exit(&pp->p_lock);
 912 
 913         return (error);
 914 }
 915 
 916 extern char *execswnames[];
 917 
 918 struct execsw *
 919 allocate_execsw(char *name, char *magic, size_t magic_size)
 920 {
 921         int i, j;
 922         char *ename;
 923         char *magicp;
 924 
 925         mutex_enter(&execsw_lock);
 926         for (i = 0; i < nexectype; i++) {
 927                 if (execswnames[i] == NULL) {
 928                         ename = kmem_alloc(strlen(name) + 1, KM_SLEEP);
 929                         (void) strcpy(ename, name);
 930                         execswnames[i] = ename;
 931                         /*
 932                          * Set the magic number last so that we


1799                                     AT_SUN_EMULATOR, (long)&ustrp[*--offp])
1800                 } else {
1801                         auxv32_t **a = (auxv32_t **)auxvpp;
1802                         ADDAUX(*a,
1803                             AT_SUN_PLATFORM, (int)(uintptr_t)&ustrp[*--offp])
1804                         ADDAUX(*a,
1805                             AT_SUN_EXECNAME, (int)(uintptr_t)&ustrp[*--offp])
1806                         if (args->brandname != NULL)
1807                                 ADDAUX(*a, AT_SUN_BRANDNAME,
1808                                     (int)(uintptr_t)&ustrp[*--offp])
1809                         if (args->emulator != NULL)
1810                                 ADDAUX(*a, AT_SUN_EMULATOR,
1811                                     (int)(uintptr_t)&ustrp[*--offp])
1812                 }
1813         }
1814 
1815         return (0);
1816 }
1817 
1818 /*
1819  * Though the actual stack base is constant, slew the %sp by a random aligned
1820  * amount in [0,aslr_max_stack_skew).  Mostly, this makes life slightly more
1821  * complicated for buffer overflows hoping to overwrite the return address.
1822  *
1823  * On some platforms this helps avoid cache thrashing when identical processes
1824  * simultaneously share caches that don't provide enough associativity
1825  * (e.g. sun4v systems). In this case stack slewing makes the same hot stack
1826  * variables in different processes live in different cache sets increasing
1827  * effective associativity.
1828  */
1829 size_t
1830 exec_get_spslew(void)
1831 {
1832 #ifdef sun4v
1833         static uint_t sp_color_stride = 16;
1834         static uint_t sp_color_mask = 0x1f;
1835         static uint_t sp_current_color = (uint_t)-1;
1836 #endif
1837         size_t off;
1838 
1839         ASSERT(ISP2(aslr_max_stack_skew));
1840 
1841         if ((aslr_max_stack_skew == 0) ||
1842             !secflag_enabled(curproc, PROC_SEC_ASLR)) {
1843 #ifdef sun4v
1844                 uint_t spcolor = atomic_inc_32_nv(&sp_current_color);
1845                 return ((size_t)((spcolor & sp_color_mask) *
1846                     SA(sp_color_stride)));
1847 #else
1848                 return (0);
1849 #endif
1850         }
1851 
1852         (void) random_get_pseudo_bytes((uint8_t *)&off, sizeof (off));
1853         return (SA(P2PHASE(off, aslr_max_stack_skew)));
1854 }
1855 
1856 /*
1857  * Initialize a new user stack with the specified arguments and environment.
1858  * The initial user stack layout is as follows:
1859  *
1860  *      User Stack
1861  *      +---------------+ <--- curproc->p_usrstack
1862  *      |               |
1863  *      | slew          |
1864  *      |               |
1865  *      +---------------+
1866  *      | NULL          |
1867  *      +---------------+
1868  *      |               |
1869  *      | auxv strings  |
1870  *      |               |
1871  *      +---------------+
1872  *      |               |
1873  *      | envp strings  |
1874  *      |               |
1875  *      +---------------+
1876  *      |               |


2066         p->p_datprot = args->dat_prot;
2067 
2068         /*
2069          * Reset resource controls such that all controls are again active as
2070          * well as appropriate to the potentially new address model for the
2071          * process.
2072          */
2073         e.rcep_p.proc = p;
2074         e.rcep_t = RCENTITY_PROCESS;
2075         rctl_set_reset(p->p_rctls, p, &e);
2076 
2077         /* Too early to call map_pgsz for the heap */
2078         if (use_stk_lpg) {
2079                 p->p_stkpageszc = page_szc(map_pgsz(MAPPGSZ_STK, p, 0, 0, 0));
2080         }
2081 
2082         mutex_enter(&p->p_lock);
2083         p->p_flag |= SAUTOLPG;       /* kernel controls page sizes */
2084         mutex_exit(&p->p_lock);
2085 









2086         sp_slew = exec_get_spslew();
2087         ASSERT(P2PHASE(sp_slew, args->stk_align) == 0);
2088         /* Be certain we don't underflow */
2089         VERIFY((curproc->p_usrstack - (size + sp_slew)) < curproc->p_usrstack);
2090         exec_set_sp(size + sp_slew);
2091 
2092         as = as_alloc();
2093         p->p_as = as;
2094         as->a_proc = p;
2095         if (p->p_model == DATAMODEL_ILP32 || args->addr32)
2096                 as->a_userlimit = (caddr_t)USERLIMIT32;
2097         (void) hat_setup(as->a_hat, HAT_ALLOC);
2098         hat_join_srd(as->a_hat, args->ex_vp);
2099 
2100         /*
2101          * Finally, write out the contents of the new stack.
2102          */
2103         error = stk_copyout(args, usrstack - sp_slew, auxvpp, up);
2104         kmem_free(args->stk_base, args->stk_size);
2105         return (error);
2106 }