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 }
|