Page MenuHomeFreeBSD

D33704.id101477.diff
No OneTemporary

D33704.id101477.diff

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,14 @@
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 (error == 0 && mapsz >= maxv - vm_map_min(map)) {
uprintf("Excessive mapping size\n");
error = ENOEXEC;
}
@@ -1342,8 +1344,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 +1364,7 @@
map->anon_loc = addr;
}
+ entry = (u_long)hdr->e_entry + et_dyn_addr;
imgp->entry_addr = entry;
if (interp != NULL) {
@@ -1384,6 +1385,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 +2521,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 +2762,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;
-
- 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;
+ vm_offset_t val;
p = curproc;
#ifdef SCTL_MASK32
if (req->flags & SCTL_MASK32) {
- unsigned int val;
+ unsigned int val32;
- 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
@@ -824,8 +794,6 @@
p->p_flag |= P_EXEC;
if ((p->p_flag2 & P2_NOTRACE_EXEC) == 0)
p->p_flag2 &= ~P2_NOTRACE;
- if ((p->p_flag2 & P2_STKGAP_DISABLE_EXEC) == 0)
- p->p_flag2 &= ~P2_STKGAP_DISABLE;
if (p->p_flag & P_PPWAIT) {
p->p_flag &= ~(P_PPWAIT | P_PPTRACE);
cv_broadcast(&p->p_pwait);
@@ -1136,9 +1104,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 +1115,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 +1151,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 +1177,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_off, stack_top;
+ u_long ssiz;
+ int error, find_space;
+ 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 +1215,47 @@
} 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 (find_space == VMFS_ANY_SPACE) {
+ /* Randomize within the first page of the stack. */
+ arc4rand(&stack_off, sizeof(stack_off), 0);
+ stack_top -= rounddown2(stack_off % PAGE_SIZE, 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 +1589,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 +1611,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 +1668,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_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -500,8 +500,7 @@
p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE |
P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC |
P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP |
- P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_NO_NEW_PRIVS |
- P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC);
+ P2_NO_NEW_PRIVS | P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC);
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
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_procctl.c
===================================================================
--- sys/kern/kern_procctl.c
+++ sys/kern/kern_procctl.c
@@ -562,61 +562,6 @@
return (0);
}
-static int
-stackgap_ctl(struct thread *td, struct proc *p, void *data)
-{
- int state;
-
- PROC_LOCK_ASSERT(p, MA_OWNED);
- state = *(int *)data;
-
- if ((state & ~(PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE |
- PROC_STACKGAP_ENABLE_EXEC | PROC_STACKGAP_DISABLE_EXEC)) != 0)
- return (EINVAL);
- switch (state & (PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE)) {
- case PROC_STACKGAP_ENABLE:
- if ((p->p_flag2 & P2_STKGAP_DISABLE) != 0)
- return (EINVAL);
- break;
- case PROC_STACKGAP_DISABLE:
- p->p_flag2 |= P2_STKGAP_DISABLE;
- break;
- case 0:
- break;
- default:
- return (EINVAL);
- }
- switch (state & (PROC_STACKGAP_ENABLE_EXEC |
- PROC_STACKGAP_DISABLE_EXEC)) {
- case PROC_STACKGAP_ENABLE_EXEC:
- p->p_flag2 &= ~P2_STKGAP_DISABLE_EXEC;
- break;
- case PROC_STACKGAP_DISABLE_EXEC:
- p->p_flag2 |= P2_STKGAP_DISABLE_EXEC;
- break;
- case 0:
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-static int
-stackgap_status(struct thread *td, struct proc *p, void *data)
-{
- int d;
-
- PROC_LOCK_ASSERT(p, MA_OWNED);
-
- d = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE :
- PROC_STACKGAP_ENABLE;
- d |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ?
- PROC_STACKGAP_DISABLE_EXEC : PROC_STACKGAP_ENABLE_EXEC;
- *(int *)data = d;
- return (0);
-}
-
static int
wxmap_ctl(struct thread *td, struct proc *p, void *data)
{
@@ -822,18 +767,6 @@
.need_candebug = false,
.copyin_sz = 0, .copyout_sz = sizeof(int),
.exec = protmax_status, .copyout_on_error = false, },
- [PROC_STACKGAP_CTL] =
- { .lock_tree = PCTL_UNLOCKED, .one_proc = true,
- .esrch_is_einval = false, .no_nonnull_data = false,
- .need_candebug = true,
- .copyin_sz = sizeof(int), .copyout_sz = 0,
- .exec = stackgap_ctl, .copyout_on_error = false, },
- [PROC_STACKGAP_STATUS] =
- { .lock_tree = PCTL_UNLOCKED, .one_proc = true,
- .esrch_is_einval = false, .no_nonnull_data = false,
- .need_candebug = false,
- .copyin_sz = 0, .copyout_sz = sizeof(int),
- .exec = stackgap_status, .copyout_on_error = false, },
[PROC_NO_NEW_PRIVS_CTL] =
{ .lock_tree = PCTL_SLOCKED, .one_proc = true,
.esrch_is_einval = false, .no_nonnull_data = false,
@@ -870,14 +803,15 @@
int flags;
} x;
const struct procctl_cmd_info *cmd_info;
- int error, error1;
+ int com, error, error1;
- if (uap->com >= PROC_PROCCTL_MD_MIN)
- return (cpu_procctl(td, uap->idtype, uap->id,
- uap->com, uap->data));
- if (uap->com == 0 || uap->com >= nitems(procctl_cmds_info))
+ com = uap->com;
+ if (com >= PROC_PROCCTL_MD_MIN)
+ return (cpu_procctl(td, uap->idtype, uap->id, com, uap->data));
+ if (com < 0 || com >= nitems(procctl_cmds_info) ||
+ procctl_cmds_info[com].exec == NULL)
return (EINVAL);
- cmd_info = &procctl_cmds_info[uap->com];
+ cmd_info = &procctl_cmds_info[com];
bzero(&x, sizeof(x));
if (cmd_info->copyin_sz > 0) {
@@ -888,7 +822,7 @@
return (EINVAL);
}
- error = kern_procctl(td, uap->idtype, uap->id, uap->com, &x);
+ error = kern_procctl(td, uap->idtype, uap->id, com, &x);
if (cmd_info->copyout_sz > 0 && (error == 0 ||
cmd_info->copyout_on_error)) {
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
@@ -801,10 +801,10 @@
/* NT_FREEBSD_FEATURE_CTL desc[0] bits */
#define NT_FREEBSD_FCTL_ASLR_DISABLE 0x00000001
#define NT_FREEBSD_FCTL_PROTMAX_DISABLE 0x00000002
-#define NT_FREEBSD_FCTL_STKGAP_DISABLE 0x00000004
+/* was STKGAP_DISABLE, do not reuse 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/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -838,10 +838,6 @@
PROT_MAX. */
#define P2_PROTMAX_DISABLE 0x00000400 /* Force disable implied
PROT_MAX. */
-#define P2_STKGAP_DISABLE 0x00000800 /* Disable stack gap for
- MAP_STACK */
-#define P2_STKGAP_DISABLE_EXEC 0x00001000 /* Stack gap disabled
- after exec */
#define P2_ITSTOPPED 0x00002000
#define P2_PTRACEREQ 0x00004000 /* Active ptrace req */
#define P2_NO_NEW_PRIVS 0x00008000 /* Ignore setuid */
Index: sys/sys/procctl.h
===================================================================
--- sys/sys/procctl.h
+++ sys/sys/procctl.h
@@ -61,8 +61,8 @@
#define PROC_ASLR_STATUS 14 /* query ASLR status */
#define PROC_PROTMAX_CTL 15 /* en/dis implicit PROT_MAX */
#define PROC_PROTMAX_STATUS 16 /* query implicit PROT_MAX status */
-#define PROC_STACKGAP_CTL 17 /* en/dis stack gap on MAP_STACK */
-#define PROC_STACKGAP_STATUS 18 /* query stack gap */
+/* was PROC_STACKGAP_CTL 17 */
+/* was PROC_STACKGAP_STATUS 18 */
#define PROC_NO_NEW_PRIVS_CTL 19 /* disable setuid/setgid */
#define PROC_NO_NEW_PRIVS_STATUS 20 /* query suid/sgid disabled status */
#define PROC_WXMAP_CTL 21 /* control W^X */
@@ -140,11 +140,6 @@
#define PROC_PROTMAX_NOFORCE 3
#define PROC_PROTMAX_ACTIVE 0x80000000
-#define PROC_STACKGAP_ENABLE 0x0001
-#define PROC_STACKGAP_DISABLE 0x0002
-#define PROC_STACKGAP_ENABLE_EXEC 0x0004
-#define PROC_STACKGAP_DISABLE_EXEC 0x0008
-
#define PROC_NO_NEW_PRIVS_ENABLE 1
#define PROC_NO_NEW_PRIVS_DISABLE 2
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 */
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)
@@ -4496,7 +4494,7 @@
{
vm_map_entry_t new_entry, prev_entry;
vm_offset_t bot, gap_bot, gap_top, top;
- vm_size_t init_ssize, sgp;
+ vm_size_t init_ssize;
int orient, rv;
/*
@@ -4512,15 +4510,10 @@
if (max_ssize == 0 ||
!vm_map_range_valid(map, addrbos, addrbos + max_ssize))
return (KERN_INVALID_ADDRESS);
- sgp = ((curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 ||
- (curproc->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 :
- (vm_size_t)stack_guard_page * PAGE_SIZE;
- if (sgp >= max_ssize)
- return (KERN_INVALID_ARGUMENT);
init_ssize = growsize;
- if (max_ssize < init_ssize + sgp)
- init_ssize = max_ssize - sgp;
+ if (max_ssize < init_ssize)
+ init_ssize = max_ssize;
/* If addr is already mapped, no go */
if (vm_map_lookup_entry(map, addrbos, &prev_entry))
@@ -4570,20 +4563,8 @@
rv = vm_map_insert(map, NULL, 0, gap_bot, gap_top, VM_PROT_NONE,
VM_PROT_NONE, MAP_CREATE_GUARD | (orient == MAP_STACK_GROWS_DOWN ?
MAP_CREATE_STACK_GAP_DN : MAP_CREATE_STACK_GAP_UP));
- if (rv == KERN_SUCCESS) {
- /*
- * Gap can never successfully handle a fault, so
- * read-ahead logic is never used for it. Re-use
- * next_read of the gap entry to store
- * stack_guard_page for vm_map_growstack().
- */
- if (orient == MAP_STACK_GROWS_DOWN)
- vm_map_entry_pred(new_entry)->next_read = sgp;
- else
- vm_map_entry_succ(new_entry)->next_read = sgp;
- } else {
+ if (rv != KERN_SUCCESS)
(void)vm_map_delete(map, bot, top);
- }
return (rv);
}
@@ -4599,7 +4580,7 @@
struct vmspace *vm;
struct ucred *cred;
vm_offset_t gap_end, gap_start, grow_start;
- vm_size_t grow_amount, guard, max_grow;
+ vm_size_t grow_amount, max_grow;
rlim_t lmemlim, stacklim, vmemlim;
int rv, rv1;
bool gap_deleted, grow_down, is_procstack;
@@ -4650,13 +4631,7 @@
} else {
return (KERN_FAILURE);
}
- guard = ((curproc->p_flag2 & P2_STKGAP_DISABLE) != 0 ||
- (curproc->p_fctl0 & NT_FREEBSD_FCTL_STKGAP_DISABLE) != 0) ? 0 :
- gap_entry->next_read;
max_grow = gap_entry->end - gap_entry->start;
- if (guard > max_grow)
- return (KERN_NO_SPACE);
- max_grow -= guard;
if (grow_amount > max_grow)
return (KERN_NO_SPACE);
Index: usr.bin/elfctl/elfctl.c
===================================================================
--- usr.bin/elfctl/elfctl.c
+++ usr.bin/elfctl/elfctl.c
@@ -68,11 +68,8 @@
{ "noaslr", NT_FREEBSD_FCTL_ASLR_DISABLE, "Disable ASLR" },
{ "noprotmax", NT_FREEBSD_FCTL_PROTMAX_DISABLE,
"Disable implicit PROT_MAX" },
- { "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[] = {
Index: usr.bin/proccontrol/proccontrol.c
===================================================================
--- usr.bin/proccontrol/proccontrol.c
+++ usr.bin/proccontrol/proccontrol.c
@@ -44,7 +44,6 @@
MODE_TRACE,
MODE_TRAPCAP,
MODE_PROTMAX,
- MODE_STACKGAP,
MODE_NO_NEW_PRIVS,
MODE_WXMAP,
#ifdef PROC_KPTI_CTL
@@ -86,7 +85,7 @@
{
fprintf(stderr, "Usage: proccontrol -m (aslr|protmax|trace|trapcap|"
- "stackgap|nonewprivs|wxmap"KPTI_USAGE LA_USAGE") [-q] "
+ "nonewprivs|wxmap"KPTI_USAGE LA_USAGE") [-q] "
"[-s (enable|disable)] [-p pid | command]\n");
exit(1);
}
@@ -113,8 +112,6 @@
mode = MODE_TRACE;
else if (strcmp(optarg, "trapcap") == 0)
mode = MODE_TRAPCAP;
- else if (strcmp(optarg, "stackgap") == 0)
- mode = MODE_STACKGAP;
else if (strcmp(optarg, "nonewprivs") == 0)
mode = MODE_NO_NEW_PRIVS;
else if (strcmp(optarg, "wxmap") == 0)
@@ -177,9 +174,6 @@
case MODE_PROTMAX:
error = procctl(P_PID, pid, PROC_PROTMAX_STATUS, &arg);
break;
- case MODE_STACKGAP:
- error = procctl(P_PID, pid, PROC_STACKGAP_STATUS, &arg);
- break;
case MODE_NO_NEW_PRIVS:
error = procctl(P_PID, pid, PROC_NO_NEW_PRIVS_STATUS,
&arg);
@@ -257,26 +251,6 @@
else
printf(", not active\n");
break;
- case MODE_STACKGAP:
- switch (arg & (PROC_STACKGAP_ENABLE |
- PROC_STACKGAP_DISABLE)) {
- case PROC_STACKGAP_ENABLE:
- printf("enabled\n");
- break;
- case PROC_STACKGAP_DISABLE:
- printf("disabled\n");
- break;
- }
- switch (arg & (PROC_STACKGAP_ENABLE_EXEC |
- PROC_STACKGAP_DISABLE_EXEC)) {
- case PROC_STACKGAP_ENABLE_EXEC:
- printf("enabled after exec\n");
- break;
- case PROC_STACKGAP_DISABLE_EXEC:
- printf("disabled after exec\n");
- break;
- }
- break;
case MODE_NO_NEW_PRIVS:
switch (arg) {
case PROC_NO_NEW_PRIVS_ENABLE:
@@ -358,12 +332,6 @@
PROC_PROTMAX_FORCE_DISABLE;
error = procctl(P_PID, pid, PROC_PROTMAX_CTL, &arg);
break;
- case MODE_STACKGAP:
- arg = enable ? PROC_STACKGAP_ENABLE_EXEC :
- (PROC_STACKGAP_DISABLE |
- PROC_STACKGAP_DISABLE_EXEC);
- error = procctl(P_PID, pid, PROC_STACKGAP_CTL, &arg);
- break;
case MODE_NO_NEW_PRIVS:
arg = enable ? PROC_NO_NEW_PRIVS_ENABLE :
PROC_NO_NEW_PRIVS_DISABLE;

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 9:39 AM (19 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31340645
Default Alt Text
D33704.id101477.diff (50 KB)

Event Timeline