Index: lib/libthr/thread/thr_init.c =================================================================== --- lib/libthr/thread/thr_init.c +++ lib/libthr/thread/thr_init.c @@ -61,7 +61,7 @@ #include "libc_private.h" #include "thr_private.h" -char *_stacktop; +char *_usrstack; struct pthread *_thr_initial; int _libthr_debug; int _thread_event_mask; @@ -388,7 +388,7 @@ * resource limits, so this stack needs an explicitly mapped * red zone to protect the thread stack that is just beyond. */ - if (mmap(_stacktop - _thr_stack_initial - + if (mmap(_usrstack - _thr_stack_initial - _thr_guard_default, _thr_guard_default, 0, MAP_ANON, -1, 0) == MAP_FAILED) PANIC("Cannot allocate red zone for initial thread"); @@ -402,7 +402,7 @@ * actually free() it; it just puts it in the free * stack queue for later reuse. */ - thread->attr.stackaddr_attr = _stacktop - _thr_stack_initial; + thread->attr.stackaddr_attr = _usrstack - _thr_stack_initial; thread->attr.stacksize_attr = _thr_stack_initial; thread->attr.guardsize_attr = _thr_guard_default; thread->attr.flags |= THR_STACK_USER; @@ -427,7 +427,7 @@ thread->attr.prio = sched_param.sched_priority; #ifdef _PTHREAD_FORCED_UNWIND - thread->unwind_stackend = _stacktop; + thread->unwind_stackend = _usrstack; #endif /* Others cleared to zero by thr_alloc() */ @@ -464,13 +464,10 @@ __thr_malloc_init(); /* Find the stack top */ mib[0] = CTL_KERN; - mib[1] = KERN_STACKTOP; - len = sizeof (_stacktop); - if (sysctl(mib, 2, &_stacktop, &len, NULL, 0) == -1) { - mib[1] = KERN_USRSTACK; - if (sysctl(mib, 2, &_stacktop, &len, NULL, 0) == -1) - PANIC("Cannot get kern.usrstack from sysctl"); - } + mib[1] = KERN_USRSTACK; + len = sizeof (_usrstack); + if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) + PANIC("Cannot get kern.usrstack from sysctl"); env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN"); env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN"); if (env_bigstack != NULL || env_splitstack == NULL) { Index: lib/libthr/thread/thr_private.h =================================================================== --- lib/libthr/thread/thr_private.h +++ lib/libthr/thread/thr_private.h @@ -724,7 +724,7 @@ * Global variables for the pthread kernel. */ -extern char *_stacktop __hidden; +extern char *_usrstack __hidden; /* For debugger */ extern int _libthr_debug; Index: lib/libthr/thread/thr_stack.c =================================================================== --- lib/libthr/thread/thr_stack.c +++ lib/libthr/thread/thr_stack.c @@ -149,20 +149,17 @@ { int mib[2]; struct rlimit rlim; - u_long stacktop; + u_long usrstack; size_t len; mib[0] = CTL_KERN; - mib[1] = KERN_STACKTOP; - len = sizeof(stacktop); - if (sysctl(mib, nitems(mib), &stacktop, &len, NULL, 0) == -1) { - mib[1] = KERN_USRSTACK; - if (sysctl(mib, nitems(mib), &stacktop, &len, NULL, 0) == -1) - return; - } + mib[1] = KERN_USRSTACK; + len = sizeof(usrstack); + if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1) + return; if (getrlimit(RLIMIT_STACK, &rlim) == -1) return; - mprotect((void *)(uintptr_t)(stacktop - rlim.rlim_cur), + mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), rlim.rlim_cur, _rtld_get_stack_prot()); } @@ -215,7 +212,7 @@ /* * Use the garbage collector lock for synchronization of the - * spare stack lists and allocations from stacktop. + * spare stack lists and allocations from usrstack. */ THREAD_LIST_WRLOCK(curthread); /* @@ -251,11 +248,11 @@ } else { /* - * Allocate a stack from or below stacktop, depending + * Allocate a stack from or below usrstack, depending * on the LIBPTHREAD_BIGSTACK_MAIN env variable. */ if (last_stack == NULL) - last_stack = _stacktop - _thr_stack_initial - + last_stack = _usrstack - _thr_stack_initial - _thr_guard_default; /* Allocate a new stack. */ Index: share/man/man7/security.7 =================================================================== --- share/man/man7/security.7 +++ share/man/man7/security.7 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 28, 2021 +.Dd January 14, 2022 .Dt SECURITY 7 .Os .Sh NAME @@ -1062,19 +1062,19 @@ .It Dv kern.elf32.aslr.honor_sbrk Makes ASLR less aggressive and more compatible with old binaries relying on the sbrk area. -.It Dv kern.elf32.aslr.stack_gap -If ASLR is enabled for a binary, a non-zero value creates a randomized -stack gap between strings and the end of the aux vector. -The value is the maximum percentage of main stack to waste on the gap. -Cannot be greater than 50, i.e., at most half of the stack. +.It Dv kern.elf32.aslr.stack +If ASLR is enabled for a binary, a non-zero value enables randomization +of the stack. +Otherwise, the stack is mapped at a fixed location determined by the +process ABI. .It Dv kern.elf64.aslr.enable 64bit binaries ASLR control. .It Dv kern.elf64.aslr.pie_enable 64bit PIE binaries ASLR control. .It Dv kern.elf64.aslr.honor_sbrk 64bit binaries ASLR sbrk compatibility control. -.It Dv kern.elf64.aslr.stack_gap -Controls stack gap for 64bit binaries. +.It Dv kern.elf64.aslr.stack +Controls stack randomization for 64bit binaries. .It Dv kern.elf32.nxstack Enables non-executable stack for 32bit processes. Enabled by default if supported by hardware and corresponding binary. Index: sys/amd64/amd64/elf_machdep.c =================================================================== --- sys/amd64/amd64/elf_machdep.c +++ sys/amd64/amd64/elf_machdep.c @@ -75,6 +75,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS_LA48, .sv_usrstack = USRSTACK_LA48, .sv_psstrings = PS_STRINGS_LA48, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, @@ -91,7 +92,6 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, - .sv_stackgap = elf64_stackgap, .sv_onexec_old = exec_onexec_old, .sv_onexit = exit_onexit, .sv_set_fork_retval = x86_set_fork_retval, @@ -117,6 +117,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS_LA57, .sv_usrstack = USRSTACK_LA57, .sv_psstrings = PS_STRINGS_LA57, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, @@ -133,7 +134,6 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, - .sv_stackgap = elf64_stackgap, .sv_onexec_old = exec_onexec_old, .sv_onexit = exit_onexit, .sv_set_fork_retval= x86_set_fork_retval, Index: sys/amd64/ia32/ia32_signal.c =================================================================== --- sys/amd64/ia32/ia32_signal.c +++ sys/amd64/ia32/ia32_signal.c @@ -422,7 +422,7 @@ } regs->tf_rsp = (uintptr_t)fp; - regs->tf_rip = p->p_sysent->sv_psstrings - + regs->tf_rip = PROC_PS_STRINGS(p) - (_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) + VDSO_IA32_OSIGCODE_OFFSET; regs->tf_rflags &= ~(PSL_T | PSL_D); Index: sys/amd64/ia32/ia32_syscall.c =================================================================== --- sys/amd64/ia32/ia32_syscall.c +++ sys/amd64/ia32/ia32_syscall.c @@ -270,7 +270,7 @@ bzero(&uap, sizeof(uap)); uap.start = 0; uap.num = 1; - lcall_addr = curproc->p_sysent->sv_psstrings - + lcall_addr = PROC_PS_STRINGS(curproc) - (_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) + VDSO_LCALL_TRAMP_OFFSET; bzero(&desc, sizeof(desc)); Index: sys/amd64/linux/linux_sysvec.c =================================================================== --- sys/amd64/linux/linux_sysvec.c +++ sys/amd64/linux/linux_sysvec.c @@ -359,7 +359,7 @@ struct proc *p; p = imgp->proc; - arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + arginfo = (struct ps_strings *)PROC_PS_STRINGS(p); destp = (uintptr_t)arginfo; if (imgp->execpath != NULL && imgp->auxargs != NULL) { @@ -776,6 +776,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS_LA48, .sv_usrstack = LINUX_USRSTACK_LA48, .sv_psstrings = LINUX_PS_STRINGS_LA48, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = linux_copyout_auxargs, .sv_copyout_strings = linux_copyout_strings, Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== --- sys/amd64/linux32/linux32_sysvec.c +++ sys/amd64/linux32/linux32_sysvec.c @@ -937,6 +937,7 @@ .sv_maxuser = LINUX32_MAXUSER, .sv_usrstack = LINUX32_USRSTACK, .sv_psstrings = LINUX32_PS_STRINGS, + .sv_psstringssz = sizeof(struct linux32_ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = linux_copyout_auxargs, .sv_copyout_strings = linux_copyout_strings, Index: sys/arm/arm/elf_machdep.c =================================================================== --- sys/arm/arm/elf_machdep.c +++ sys/arm/arm/elf_machdep.c @@ -81,6 +81,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, Index: sys/arm/arm/exec_machdep.c =================================================================== --- sys/arm/arm/exec_machdep.c +++ sys/arm/arm/exec_machdep.c @@ -340,7 +340,7 @@ if (sysent->sv_sigcode_base != 0) tf->tf_usr_lr = (register_t)sysent->sv_sigcode_base; else - tf->tf_usr_lr = (register_t)(sysent->sv_psstrings - + tf->tf_usr_lr = (register_t)(PROC_PS_STRINGS(p) - *(sysent->sv_szsigcode)); /* Set the mode to enter in the signal handler */ #if __ARM_ARCH >= 7 Index: sys/arm64/arm64/elf32_machdep.c =================================================================== --- sys/arm64/arm64/elf32_machdep.c +++ sys/arm64/arm64/elf32_machdep.c @@ -99,6 +99,7 @@ .sv_maxuser = FREEBSD32_MAXUSER, .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, + .sv_psstringssz = sizeof(struct freebsd32_ps_strings), .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_auxargs = elf32_freebsd_copyout_auxargs, .sv_copyout_strings = freebsd32_copyout_strings, Index: sys/arm64/arm64/elf_machdep.c =================================================================== --- sys/arm64/arm64/elf_machdep.c +++ sys/arm64/arm64/elf_machdep.c @@ -77,6 +77,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, @@ -93,7 +94,6 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, - .sv_stackgap = elf64_stackgap, .sv_hwcap = &elf_hwcap, .sv_hwcap2 = &elf_hwcap2, .sv_onexec_old = exec_onexec_old, Index: sys/arm64/arm64/freebsd32_machdep.c =================================================================== --- sys/arm64/arm64/freebsd32_machdep.c +++ sys/arm64/arm64/freebsd32_machdep.c @@ -390,7 +390,7 @@ if (sysent->sv_sigcode_base != 0) tf->tf_x[14] = (register_t)sysent->sv_sigcode_base; else - tf->tf_x[14] = (register_t)(sysent->sv_psstrings - + tf->tf_x[14] = (register_t)(PROC_PS_STRINGS(p) - *(sysent->sv_szsigcode)); /* Set the mode to enter in the signal handler */ if ((register_t)catcher & 1) Index: sys/arm64/linux/linux_sysvec.c =================================================================== --- sys/arm64/linux/linux_sysvec.c +++ sys/arm64/linux/linux_sysvec.c @@ -256,7 +256,7 @@ int argc, envc, error; p = imgp->proc; - arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + arginfo = (struct ps_strings *)PROC_PS_STRINGS(p); destp = (uintptr_t)arginfo; if (imgp->execpath != NULL && imgp->auxargs != NULL) { @@ -519,6 +519,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = LINUX_USRSTACK, .sv_psstrings = LINUX_PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_auxargs = linux_copyout_auxargs, .sv_copyout_strings = linux_copyout_strings, Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c +++ sys/compat/freebsd32/freebsd32_misc.c @@ -3404,7 +3404,7 @@ sysent = imgp->sysent; - arginfo = (struct freebsd32_ps_strings *)sysent->sv_psstrings; + arginfo = (struct freebsd32_ps_strings *)PROC_PS_STRINGS(imgp->proc); imgp->ps_strings = arginfo; destp = (uintptr_t)arginfo; @@ -3464,8 +3464,6 @@ destp = rounddown2(destp, sizeof(uint32_t)); ustringp = destp; - exec_stackgap(imgp, &destp); - if (imgp->auxargs) { /* * Allocate room on the stack for the ELF auxargs @@ -3656,7 +3654,6 @@ case PROC_ASLR_CTL: case PROC_PROTMAX_CTL: case PROC_SPROTECT: - case PROC_STACKGAP_CTL: case PROC_TRACE_CTL: case PROC_TRAPCAP_CTL: case PROC_NO_NEW_PRIVS_CTL: @@ -3691,7 +3688,6 @@ break; case PROC_ASLR_STATUS: case PROC_PROTMAX_STATUS: - case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: case PROC_NO_NEW_PRIVS_STATUS: @@ -3724,7 +3720,6 @@ break; case PROC_ASLR_STATUS: case PROC_PROTMAX_STATUS: - case PROC_STACKGAP_STATUS: case PROC_TRACE_STATUS: case PROC_TRAPCAP_STATUS: case PROC_NO_NEW_PRIVS_STATUS: Index: sys/compat/ia32/ia32_sysvec.c =================================================================== --- sys/compat/ia32/ia32_sysvec.c +++ sys/compat/ia32/ia32_sysvec.c @@ -121,6 +121,7 @@ .sv_maxuser = FREEBSD32_MAXUSER, .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, + .sv_psstringssz = sizeof(struct freebsd32_ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = elf32_freebsd_copyout_auxargs, .sv_copyout_strings = freebsd32_copyout_strings, @@ -137,7 +138,6 @@ .sv_schedtail = NULL, .sv_thread_detach = NULL, .sv_trap = NULL, - .sv_stackgap = elf32_stackgap, .sv_onexec_old = exec_onexec_old, .sv_onexit = exit_onexit, .sv_set_fork_retval = x86_set_fork_retval, Index: sys/i386/i386/elf_machdep.c =================================================================== --- sys/i386/i386/elf_machdep.c +++ sys/i386/i386/elf_machdep.c @@ -70,6 +70,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, Index: sys/i386/i386/exec_machdep.c =================================================================== --- sys/i386/i386/exec_machdep.c +++ sys/i386/i386/exec_machdep.c @@ -238,7 +238,7 @@ szosigcode; } else { /* a.out sysentvec does not use shared page */ - regs->tf_eip = p->p_sysent->sv_psstrings - szosigcode; + regs->tf_eip = PROC_PS_STRINGS(p) - szosigcode; } regs->tf_eflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucodesel; @@ -523,7 +523,7 @@ regs->tf_esp = (int)sfp; regs->tf_eip = p->p_sysent->sv_sigcode_base; if (regs->tf_eip == 0) - regs->tf_eip = p->p_sysent->sv_psstrings - szsigcode; + regs->tf_eip = PROC_PS_STRINGS(p) - szsigcode; regs->tf_eflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; Index: sys/i386/linux/imgact_linux.c =================================================================== --- sys/i386/linux/imgact_linux.c +++ sys/i386/linux/imgact_linux.c @@ -213,6 +213,10 @@ vmspace->vm_daddr = (caddr_t)(void *)(uintptr_t)(virtual_offset + a_out->a_text); + error = exec_map_stack(imgp); + if (error != 0) + goto fail; + /* Fill in image_params */ imgp->interpreted = 0; imgp->entry_addr = a_out->a_entry; Index: sys/i386/linux/linux_sysvec.c =================================================================== --- sys/i386/linux/linux_sysvec.c +++ sys/i386/linux/linux_sysvec.c @@ -212,7 +212,7 @@ p = imgp->proc; issetugid = imgp->proc->p_flag & P_SUGID ? 1 : 0; - arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + arginfo = (struct ps_strings *)PROC_PS_STRINGS(p); args = (Elf32_Auxargs *)imgp->auxargs; argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); @@ -290,7 +290,7 @@ struct proc *p; p = imgp->proc; - arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; + arginfo = (struct ps_strings *)PROC_PS_STRINGS(p); destp = (uintptr_t)arginfo; if (imgp->execpath != NULL && imgp->auxargs != NULL) { @@ -845,6 +845,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = LINUX_USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = exec_copyout_strings, .sv_setregs = linux_exec_setregs, @@ -885,6 +886,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = LINUX_USRSTACK, .sv_psstrings = LINUX_PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = linux_copyout_auxargs, .sv_copyout_strings = linux_copyout_strings, Index: sys/kern/imgact_aout.c =================================================================== --- sys/kern/imgact_aout.c +++ sys/kern/imgact_aout.c @@ -89,6 +89,7 @@ .sv_maxuser = AOUT32_USRSTACK, .sv_usrstack = AOUT32_USRSTACK, .sv_psstrings = AOUT32_PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, @@ -139,6 +140,7 @@ .sv_maxuser = AOUT32_USRSTACK, .sv_usrstack = AOUT32_USRSTACK, .sv_psstrings = AOUT32_PS_STRINGS, + .sv_psstringssz = sizeof(struct freebsd32_ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = freebsd32_copyout_strings, .sv_setregs = ia32_setregs, @@ -348,6 +350,10 @@ vmspace->vm_daddr = (caddr_t) (uintptr_t) (virtual_offset + a_out->a_text); + error = exec_map_stack(imgp); + if (error != 0) + return (error); + /* Fill in image_params */ imgp->interpreted = 0; imgp->entry_addr = a_out->a_entry; Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -201,11 +201,11 @@ &__elfN(aslr_honor_sbrk), 0, __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) ": assume sbrk is used"); -static int __elfN(aslr_stack_gap) = 0; -SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, stack_gap, CTLFLAG_RW, - &__elfN(aslr_stack_gap), 0, +static int __elfN(aslr_stack) = 1; +SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, stack, CTLFLAG_RWTUN, + &__elfN(aslr_stack), 0, __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE)) - ": maximum percentage of main stack to waste on a random gap"); + ": enable stack randomization"); static int __elfN(sigfastblock) = 1; SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, sigfastblock, @@ -1301,6 +1301,8 @@ if (!__elfN(aslr_honor_sbrk) || (imgp->proc->p_flag2 & P2_ASLR_IGNSTART) != 0) imgp->map_flags |= MAP_ASLR_IGNSTART; + if (__elfN(aslr_stack)) + imgp->map_flags |= MAP_ASLR_STACK; } if ((!__elfN(allow_wx) && (fctl0 & NT_FREEBSD_FCTL_WXNEEDED) == 0 && @@ -1309,14 +1311,16 @@ imgp->map_flags |= MAP_WXORX; error = exec_new_vmspace(imgp, sv); - vmspace = imgp->proc->p_vmspace; - map = &vmspace->vm_map; imgp->proc->p_sysent = sv; imgp->proc->p_elf_brandinfo = brand_info; - maxv = vm_map_max(map) - lim_max(td, RLIMIT_STACK); - if (mapsz >= maxv - vm_map_min(map)) { + vmspace = imgp->proc->p_vmspace; + map = &vmspace->vm_map; + maxv = sv->sv_usrstack; + if ((imgp->map_flags & MAP_ASLR_STACK) == 0) + maxv -= lim_max(td, RLIMIT_STACK); + if (error == 0 && mapsz >= maxv - vm_map_min(map)) { uprintf("Excessive mapping size\n"); error = ENOEXEC; } @@ -1342,8 +1346,6 @@ if (error != 0) goto ret; - entry = (u_long)hdr->e_entry + et_dyn_addr; - /* * We load the dynamic linker where a userland call * to mmap(0, ...) would put it. The rationale behind this @@ -1364,6 +1366,7 @@ map->anon_loc = addr; } + entry = (u_long)hdr->e_entry + et_dyn_addr; imgp->entry_addr = entry; if (interp != NULL) { @@ -1384,6 +1387,10 @@ } else addr = et_dyn_addr; + error = exec_map_stack(imgp); + if (error != 0) + goto ret; + /* * Construct auxargs table (used by the copyout_auxargs routine) */ @@ -2516,9 +2523,9 @@ KASSERT(*sizep == size, ("invalid size")); structsize = sizeof(ps_strings); #if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 - ps_strings = PTROUT(p->p_sysent->sv_psstrings); + ps_strings = PTROUT(PROC_PS_STRINGS(p)); #else - ps_strings = p->p_sysent->sv_psstrings; + ps_strings = PROC_PS_STRINGS(p); #endif sbuf_bcat(sb, &structsize, sizeof(structsize)); sbuf_bcat(sb, &ps_strings, sizeof(ps_strings)); @@ -2757,22 +2764,3 @@ flags |= PF_W; return (flags); } - -vm_size_t -__elfN(stackgap)(struct image_params *imgp, uintptr_t *stack_base) -{ - uintptr_t range, rbase, gap; - int pct; - - pct = __elfN(aslr_stack_gap); - if (pct == 0) - return (0); - if (pct > 50) - pct = 50; - range = imgp->eff_stack_sz * pct / 100; - arc4rand(&rbase, sizeof(rbase), 0); - gap = rbase % range; - gap &= ~(sizeof(u_long) - 1); - *stack_base -= gap; - return (gap); -} Index: sys/kern/init_main.c =================================================================== --- sys/kern/init_main.c +++ sys/kern/init_main.c @@ -424,6 +424,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_strings = NULL, .sv_setregs = NULL, Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -119,7 +119,6 @@ static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS); static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS); -static int sysctl_kern_stacktop(SYSCTL_HANDLER_ARGS); static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS); static int do_execve(struct thread *td, struct image_args *args, struct mac *mac_p, struct vmspace *oldvmspace); @@ -134,10 +133,6 @@ CTLFLAG_CAPRD|CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_usrstack, "LU", "Top of process stack"); -SYSCTL_PROC(_kern, KERN_STACKTOP, stacktop, CTLTYPE_ULONG | CTLFLAG_RD | - CTLFLAG_CAPRD | CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_stacktop, "LU", - "Top of process stack with stack gap."); - SYSCTL_PROC(_kern, OID_AUTO, stackprot, CTLTYPE_INT|CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, 0, sysctl_kern_stackprot, "I", "Stack memory permissions"); @@ -165,62 +160,37 @@ sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS) { struct proc *p; - int error; + vm_offset_t ps_strings; p = curproc; #ifdef SCTL_MASK32 if (req->flags & SCTL_MASK32) { unsigned int val; - val = (unsigned int)p->p_sysent->sv_psstrings; - error = SYSCTL_OUT(req, &val, sizeof(val)); - } else + val = (unsigned int)PROC_PS_STRINGS(p); + return (SYSCTL_OUT(req, &val, sizeof(val))); + } #endif - error = SYSCTL_OUT(req, &p->p_sysent->sv_psstrings, - sizeof(p->p_sysent->sv_psstrings)); - return error; + ps_strings = PROC_PS_STRINGS(p); + return (SYSCTL_OUT(req, &ps_strings, sizeof(ps_strings))); } static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS) { struct proc *p; - int error; + vm_offset_t val; p = curproc; #ifdef SCTL_MASK32 if (req->flags & SCTL_MASK32) { - unsigned int val; - val = (unsigned int)p->p_sysent->sv_usrstack; - error = SYSCTL_OUT(req, &val, sizeof(val)); - } else -#endif - error = SYSCTL_OUT(req, &p->p_sysent->sv_usrstack, - sizeof(p->p_sysent->sv_usrstack)); - return (error); -} - -static int -sysctl_kern_stacktop(SYSCTL_HANDLER_ARGS) -{ - vm_offset_t stacktop; - struct proc *p; - int error; + unsigned int val32; - p = curproc; -#ifdef SCTL_MASK32 - if (req->flags & SCTL_MASK32) { - unsigned int val; - - val = (unsigned int)(p->p_sysent->sv_usrstack - - p->p_vmspace->vm_stkgap); - error = SYSCTL_OUT(req, &val, sizeof(val)); - } else -#endif - { - stacktop = p->p_sysent->sv_usrstack - p->p_vmspace->vm_stkgap; - error = SYSCTL_OUT(req, &stacktop, sizeof(stacktop)); + val32 = round_page((unsigned int)p->p_vmspace->vm_stacktop); + return (SYSCTL_OUT(req, &val32, sizeof(val32))); } - return (error); +#endif + val = round_page(p->p_vmspace->vm_stacktop); + return (SYSCTL_OUT(req, &val, sizeof(val))); } static int @@ -1136,9 +1106,8 @@ } /* - * Destroy old address space, and allocate a new stack. - * The new stack is only sgrowsiz large because it is grown - * automatically on a page fault. + * Run down the current address space and install a new one. Map the shared + * page and compute the new image's stack size. */ int exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) @@ -1148,11 +1117,8 @@ struct vmspace *vmspace = p->p_vmspace; struct thread *td = curthread; vm_object_t obj; - struct rlimit rlim_stack; - vm_offset_t sv_minuser, stack_addr; + vm_offset_t sv_minuser; vm_map_t map; - vm_prot_t stack_prot; - u_long ssiz; imgp->vmspace_destroyed = true; imgp->sysent = sv; @@ -1187,7 +1153,7 @@ */ vm_map_lock(map); vm_map_modflags(map, 0, MAP_WIREFUTURE | MAP_ASLR | - MAP_ASLR_IGNSTART | MAP_WXORX); + MAP_ASLR_IGNSTART | MAP_ASLR_STACK | MAP_WXORX); vm_map_unlock(map); } else { error = vmspace_exec(p, sv_minuser, sv->sv_maxuser); @@ -1213,7 +1179,28 @@ } } - /* Allocate a new stack */ + return (sv->sv_onexec != NULL ? sv->sv_onexec(p, imgp) : 0); +} + +/* + * Compute the stack size limit and map the main process stack. + */ +int +exec_map_stack(struct image_params *imgp) +{ + struct rlimit rlim_stack; + struct sysentvec *sv; + struct proc *p; + vm_map_t map; + struct vmspace *vmspace; + vm_offset_t stack_addr, stack_top; + u_long ssiz; + int error, find_space, stack_off; + vm_prot_t stack_prot; + + p = imgp->proc; + sv = p->p_sysent; + if (imgp->stack_sz != 0) { ssiz = trunc_page(imgp->stack_sz); PROC_LOCK(p); @@ -1230,30 +1217,46 @@ } else { ssiz = maxssiz; } - imgp->eff_stack_sz = lim_cur(curthread, RLIMIT_STACK); - if (ssiz < imgp->eff_stack_sz) - imgp->eff_stack_sz = ssiz; - stack_addr = sv->sv_usrstack - ssiz; - stack_prot = obj != NULL && imgp->stack_prot != 0 ? + + vmspace = p->p_vmspace; + map = &vmspace->vm_map; + + stack_prot = sv->sv_shared_page_obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot : sv->sv_stackprot; - error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz, stack_prot, - VM_PROT_ALL, MAP_STACK_GROWS_DOWN); + if ((map->flags & MAP_ASLR_STACK) != 0) { + stack_addr = round_page((vm_offset_t)p->p_vmspace->vm_daddr + + lim_max(curthread, RLIMIT_DATA)); + find_space = VMFS_ANY_SPACE; + } else { + stack_addr = sv->sv_usrstack - ssiz; + find_space = VMFS_NO_SPACE; + } + error = vm_map_find(map, NULL, 0, &stack_addr, (vm_size_t)ssiz, + sv->sv_usrstack, find_space, stack_prot, VM_PROT_ALL, + MAP_STACK_GROWS_DOWN); if (error != KERN_SUCCESS) { uprintf("exec_new_vmspace: mapping stack size %#jx prot %#x " - "failed mach error %d errno %d\n", (uintmax_t)ssiz, + "failed, mach error %d errno %d\n", (uintmax_t)ssiz, stack_prot, error, vm_mmap_to_errno(error)); return (vm_mmap_to_errno(error)); } - vmspace->vm_stkgap = 0; + + stack_top = stack_addr + ssiz; + if ((map->flags & MAP_ASLR_STACK) != 0) { + /* Randomize within the first page of the stack. */ + arc4rand(&stack_off, sizeof(stack_off), 0); + stack_top -= rounddown2(stack_off & PAGE_MASK, sizeof(void *)); + } /* * vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they * are still used to enforce the stack rlimit on the process stack. */ - vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT; vmspace->vm_maxsaddr = (char *)stack_addr; + vmspace->vm_stacktop = stack_top; + vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT; - return (sv->sv_onexec != NULL ? sv->sv_onexec(p, imgp) : 0); + return (0); } /* @@ -1587,21 +1590,6 @@ return (args->endp); } -void -exec_stackgap(struct image_params *imgp, uintptr_t *dp) -{ - struct proc *p = imgp->proc; - - if (imgp->sysent->sv_stackgap == NULL || - (p->p_fctl0 & (NT_FREEBSD_FCTL_ASLR_DISABLE | - NT_FREEBSD_FCTL_ASG_DISABLE)) != 0 || - (imgp->map_flags & MAP_ASLR) == 0) { - p->p_vmspace->vm_stkgap = 0; - return; - } - p->p_vmspace->vm_stkgap = imgp->sysent->sv_stackgap(imgp, dp); -} - /* * Copy strings out to the new process address space, constructing new arg * and env vector tables. Return a pointer to the base so that it can be used @@ -1624,9 +1612,8 @@ p = imgp->proc; sysent = p->p_sysent; - arginfo = (struct ps_strings *)sysent->sv_psstrings; - destp = (uintptr_t)arginfo; - imgp->ps_strings = arginfo; + destp = PROC_PS_STRINGS(p); + arginfo = imgp->ps_strings = (void *)destp; /* * Install sigcode. @@ -1682,8 +1669,6 @@ destp = rounddown2(destp, sizeof(void *)); ustringp = destp; - exec_stackgap(imgp, &destp); - if (imgp->auxargs) { /* * Allocate room on the stack for the ELF auxargs Index: sys/kern/kern_proc.c =================================================================== --- sys/kern/kern_proc.c +++ sys/kern/kern_proc.c @@ -1838,8 +1838,8 @@ int i, error; error = 0; - if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss, - sizeof(pss)) != sizeof(pss)) + if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != + sizeof(pss)) return (ENOMEM); switch (type) { case PROC_ARG: @@ -1914,8 +1914,8 @@ if (SV_PROC_FLAG(p, SV_ILP32) != 0) return (get_proc_vector32(td, p, proc_vectorp, vsizep, type)); #endif - if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss, - sizeof(pss)) != sizeof(pss)) + if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) != + sizeof(pss)) return (ENOMEM); switch (type) { case PROC_ARG: @@ -2980,13 +2980,13 @@ * process. */ ps_strings32 = SV_PROC_FLAG(p, SV_ILP32) != 0 ? - PTROUT(p->p_sysent->sv_psstrings) : 0; + PTROUT(PROC_PS_STRINGS(p)) : 0; PROC_UNLOCK(p); error = SYSCTL_OUT(req, &ps_strings32, sizeof(ps_strings32)); return (error); } #endif - ps_strings = p->p_sysent->sv_psstrings; + ps_strings = PROC_PS_STRINGS(p); PROC_UNLOCK(p); error = SYSCTL_OUT(req, &ps_strings, sizeof(ps_strings)); return (error); @@ -3103,9 +3103,9 @@ *sv->sv_szsigcode : (uintptr_t)sv->sv_szsigcode); } else { - kst32.ksigtramp_start = sv->sv_psstrings - + kst32.ksigtramp_start = PROC_PS_STRINGS(p) - *sv->sv_szsigcode; - kst32.ksigtramp_end = sv->sv_psstrings; + kst32.ksigtramp_end = PROC_PS_STRINGS(p); } } PROC_UNLOCK(p); @@ -3120,9 +3120,9 @@ ((sv->sv_flags & SV_DSO_SIG) == 0 ? *sv->sv_szsigcode : (uintptr_t)sv->sv_szsigcode); } else { - kst.ksigtramp_start = (char *)sv->sv_psstrings - + kst.ksigtramp_start = (char *)PROC_PS_STRINGS(p) - *sv->sv_szsigcode; - kst.ksigtramp_end = (char *)sv->sv_psstrings; + kst.ksigtramp_end = (char *)PROC_PS_STRINGS(p); } PROC_UNLOCK(p); error = SYSCTL_OUT(req, &kst, sizeof(kst)); Index: sys/kern/kern_resource.c =================================================================== --- sys/kern/kern_resource.c +++ sys/kern/kern_resource.c @@ -672,9 +672,6 @@ if (limp->rlim_max < 0) limp->rlim_max = RLIM_INFINITY; - if (which == RLIMIT_STACK && limp->rlim_cur != RLIM_INFINITY) - limp->rlim_cur += p->p_vmspace->vm_stkgap; - oldssiz.rlim_cur = 0; newlim = lim_alloc(); PROC_LOCK(p); Index: sys/powerpc/powerpc/elf32_machdep.c =================================================================== --- sys/powerpc/powerpc/elf32_machdep.c +++ sys/powerpc/powerpc/elf32_machdep.c @@ -109,6 +109,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS32, .sv_usrstack = FREEBSD32_USRSTACK, .sv_psstrings = FREEBSD32_PS_STRINGS, + .sv_psstringssz = sizeof(struct freebsd32_ps_strings), .sv_copyout_strings = freebsd32_copyout_strings, .sv_setregs = ppc32_setregs, .sv_syscallnames = freebsd32_syscallnames, @@ -117,6 +118,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_copyout_strings = exec_copyout_strings, .sv_setregs = exec_setregs, .sv_syscallnames = syscallnames, Index: sys/powerpc/powerpc/elf64_machdep.c =================================================================== --- sys/powerpc/powerpc/elf64_machdep.c +++ sys/powerpc/powerpc/elf64_machdep.c @@ -78,6 +78,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, @@ -119,6 +120,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_ALL, .sv_copyout_auxargs = __elfN(powerpc_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, Index: sys/riscv/riscv/elf_machdep.c =================================================================== --- sys/riscv/riscv/elf_machdep.c +++ sys/riscv/riscv/elf_machdep.c @@ -81,6 +81,7 @@ .sv_maxuser = VM_MAXUSER_ADDRESS, .sv_usrstack = USRSTACK, .sv_psstrings = PS_STRINGS, + .sv_psstringssz = sizeof(struct ps_strings), .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, .sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs), .sv_copyout_strings = exec_copyout_strings, Index: sys/riscv/riscv/exec_machdep.c =================================================================== --- sys/riscv/riscv/exec_machdep.c +++ sys/riscv/riscv/exec_machdep.c @@ -409,7 +409,7 @@ if (sysent->sv_sigcode_base != 0) tf->tf_ra = (register_t)sysent->sv_sigcode_base; else - tf->tf_ra = (register_t)(sysent->sv_psstrings - + tf->tf_ra = (register_t)(PROC_PS_STRINGS(p) - *(sysent->sv_szsigcode)); CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_sepc, Index: sys/sys/elf_common.h =================================================================== --- sys/sys/elf_common.h +++ sys/sys/elf_common.h @@ -804,7 +804,7 @@ #define NT_FREEBSD_FCTL_STKGAP_DISABLE 0x00000004 #define NT_FREEBSD_FCTL_WXNEEDED 0x00000008 #define NT_FREEBSD_FCTL_LA48 0x00000010 -#define NT_FREEBSD_FCTL_ASG_DISABLE 0x00000020 /* ASLR STACK GAP Disable */ +/* was ASG_DISABLE, do not reuse 0x00000020 */ /* Values for n_type. Used in core files. */ #define NT_PRSTATUS 1 /* Process status. */ Index: sys/sys/exec.h =================================================================== --- sys/sys/exec.h +++ sys/sys/exec.h @@ -87,6 +87,8 @@ * Prefer the kern.ps_strings or kern.proc.ps_strings sysctls to this constant. */ #define PS_STRINGS (USRSTACK - sizeof(struct ps_strings)) +#define PROC_PS_STRINGS(p) \ + ((p)->p_vmspace->vm_stacktop - (p)->p_sysent->sv_psstringssz) int exec_map_first_page(struct image_params *); void exec_unmap_first_page(struct image_params *); Index: sys/sys/imgact.h =================================================================== --- sys/sys/imgact.h +++ sys/sys/imgact.h @@ -83,7 +83,6 @@ int pagesizeslen; vm_prot_t stack_prot; u_long stack_sz; - u_long eff_stack_sz; struct ucred *newcred; /* new credentials if changing */ #define IMGACT_SHELL 0x1 #define IMGACT_BINMISC 0x2 @@ -114,12 +113,12 @@ void exec_cleanup(struct thread *td, struct vmspace *); int exec_copyout_strings(struct image_params *, uintptr_t *); void exec_free_args(struct image_args *); +int exec_map_stack(struct image_params *); int exec_new_vmspace(struct image_params *, struct sysentvec *); void exec_setregs(struct thread *, struct image_params *, uintptr_t); int exec_shell_imgact(struct image_params *); int exec_copyin_args(struct image_args *, const char *, enum uio_seg, char **, char **); -void exec_stackgap(struct image_params *imgp, uintptr_t *dp); int pre_execve(struct thread *td, struct vmspace **oldvmspace); void post_execve(struct thread *td, int error, struct vmspace *oldvmspace); #endif Index: sys/sys/imgact_elf.h =================================================================== --- sys/sys/imgact_elf.h +++ sys/sys/imgact_elf.h @@ -118,7 +118,6 @@ int __elfN(freebsd_fixup)(uintptr_t *, struct image_params *); int __elfN(coredump)(struct thread *, struct vnode *, off_t, int); size_t __elfN(populate_note)(int, void *, void *, size_t, void **); -vm_size_t __elfN(stackgap)(struct image_params *, uintptr_t *); int __elfN(freebsd_copyout_auxargs)(struct image_params *, uintptr_t); void __elfN(puthdr)(struct thread *, void *, size_t, int, size_t, int); void __elfN(prepare_notes)(struct thread *, struct note_info_list *, Index: sys/sys/sysctl.h =================================================================== --- sys/sys/sysctl.h +++ sys/sys/sysctl.h @@ -976,7 +976,6 @@ #define KERN_HOSTUUID 36 /* string: host UUID identifier */ #define KERN_ARND 37 /* int: from arc4rand() */ #define KERN_MAXPHYS 38 /* int: MAXPHYS value */ -#define KERN_STACKTOP 39 /* int: USRSTACK - stack gap */ /* * KERN_PROC subtypes */ Index: sys/sys/sysent.h =================================================================== --- sys/sys/sysent.h +++ sys/sys/sysent.h @@ -120,7 +120,6 @@ void (*sv_elf_core_prepare_notes)(struct thread *, struct note_info_list *, size_t *); int (*sv_imgact_try)(struct image_params *); - vm_size_t (*sv_stackgap)(struct image_params *, uintptr_t *); int (*sv_copyout_auxargs)(struct image_params *, uintptr_t); int sv_minsigstksz; /* minimum signal stack size */ @@ -128,6 +127,7 @@ vm_offset_t sv_maxuser; /* VM_MAXUSER_ADDRESS */ vm_offset_t sv_usrstack; /* USRSTACK */ vm_offset_t sv_psstrings; /* PS_STRINGS */ + size_t sv_psstringssz; /* PS_STRINGS size */ int sv_stackprot; /* vm protection for stack */ int (*sv_copyout_strings)(struct image_params *, uintptr_t *); Index: sys/vm/vm_map.h =================================================================== --- sys/vm/vm_map.h +++ sys/vm/vm_map.h @@ -223,12 +223,13 @@ * vm_flags_t values */ #define MAP_WIREFUTURE 0x01 /* wire all future pages */ -#define MAP_BUSY_WAKEUP 0x02 +#define MAP_BUSY_WAKEUP 0x02 /* thread(s) waiting on busy state */ #define MAP_IS_SUB_MAP 0x04 /* has parent */ #define MAP_ASLR 0x08 /* enabled ASLR */ -#define MAP_ASLR_IGNSTART 0x10 -#define MAP_REPLENISH 0x20 +#define MAP_ASLR_IGNSTART 0x10 /* ASLR ignores data segment */ +#define MAP_REPLENISH 0x20 /* kmapent zone needs to be refilled */ #define MAP_WXORX 0x40 /* enforce W^X */ +#define MAP_ASLR_STACK 0x80 /* stack location is randomized */ #ifdef _KERNEL #if defined(KLD_MODULE) && !defined(KLD_TIED) @@ -293,7 +294,7 @@ caddr_t vm_taddr; /* (c) user virtual address of text */ caddr_t vm_daddr; /* (c) user virtual address of data */ caddr_t vm_maxsaddr; /* user VA at max stack growth */ - vm_size_t vm_stkgap; /* stack gap size in bytes */ + vm_offset_t vm_stacktop; /* top of the stack, may not be page-aligned */ u_int vm_refcnt; /* number of references */ /* * Keep the PMAP last, so that CPU-specific variations of that Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -343,7 +343,6 @@ vm->vm_taddr = 0; vm->vm_daddr = 0; vm->vm_maxsaddr = 0; - vm->vm_stkgap = 0; return (vm); } @@ -4264,7 +4263,6 @@ vm2->vm_taddr = vm1->vm_taddr; vm2->vm_daddr = vm1->vm_daddr; vm2->vm_maxsaddr = vm1->vm_maxsaddr; - vm2->vm_stkgap = vm1->vm_stkgap; vm_map_lock(old_map); if (old_map->busy) vm_map_wait_busy(old_map); @@ -4283,7 +4281,7 @@ new_map->anon_loc = old_map->anon_loc; new_map->flags |= old_map->flags & (MAP_ASLR | MAP_ASLR_IGNSTART | - MAP_WXORX); + MAP_ASLR_STACK | MAP_WXORX); VM_MAP_ENTRY_FOREACH(old_entry, old_map) { if ((old_entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) Index: usr.bin/elfctl/elfctl.c =================================================================== --- usr.bin/elfctl/elfctl.c +++ usr.bin/elfctl/elfctl.c @@ -71,8 +71,6 @@ { "nostackgap", NT_FREEBSD_FCTL_STKGAP_DISABLE, "Disable stack gap" }, { "wxneeded", NT_FREEBSD_FCTL_WXNEEDED, "Requires W+X mappings" }, { "la48", NT_FREEBSD_FCTL_LA48, "amd64: Limit user VA to 48bit" }, - { "noaslrstkgap", NT_FREEBSD_FCTL_ASG_DISABLE, - "Disable ASLR stack gap" }, }; static struct option long_opts[] = {