Page MenuHomeFreeBSD

D33704.id100769.diff
No OneTemporary

D33704.id100769.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: 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,
@@ -117,6 +118,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,
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 = p->p_psstrings -
(_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 = curproc->p_psstrings -
(_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 *)p->p_psstrings;
destp = (uintptr_t)arginfo;
if (imgp->execpath != NULL && imgp->auxargs != NULL) {
@@ -774,6 +774,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)(p->p_psstrings -
*(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,
Index: sys/arm64/arm64/exec_machdep.c
===================================================================
--- sys/arm64/arm64/exec_machdep.c
+++ sys/arm64/arm64/exec_machdep.c
@@ -604,7 +604,7 @@
if (sysent->sv_sigcode_base != 0)
tf->tf_lr = (register_t)sysent->sv_sigcode_base;
else
- tf->tf_lr = (register_t)(sysent->sv_psstrings -
+ tf->tf_lr = (register_t)(p->p_psstrings -
*(sysent->sv_szsigcode));
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_elr,
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)(p->p_psstrings -
*(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 *)p->p_psstrings;
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 *)imgp->proc->p_psstrings;
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
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,
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 = p->p_psstrings - 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 = p->p_psstrings - szsigcode;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
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 *)p->p_psstrings;
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 *)p->p_psstrings;
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,
@@ -353,6 +355,7 @@
imgp->entry_addr = a_out->a_entry;
imgp->proc->p_sysent = &aout_sysvec;
+ imgp->proc->p_psstrings = aout_sysvec.sv_psstrings;
return (0);
}
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -201,8 +201,24 @@
&__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,
+/*
+ * Stack randomization is incompatible with binaries that assume PS_STRINGS is
+ * at a fixed location.
+ */
+#if __ELF_WORD_SIZE == 32
+#define STACK_GAP_DEFAULT 0
+#ifdef COMPAT_43
+#define STACK_GAP_FLAG CTLFLAG_RD
+#else
+#define STACK_GAP_FLAG CTLFLAG_RW
+#endif
+#else
+#define STACK_GAP_DEFAULT 3
+#define STACK_GAP_FLAG CTLFLAG_RW
+#endif
+
+static int __elfN(aslr_stack_gap) = STACK_GAP_DEFAULT;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, stack_gap, STACK_GAP_FLAG,
&__elfN(aslr_stack_gap), 0,
__XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
": maximum percentage of main stack to waste on a random gap");
@@ -1309,14 +1325,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_psstrings = rounddown2(imgp->stack_top, sizeof(void *)) -
+ sv->sv_psstringssz;
imgp->proc->p_elf_brandinfo = brand_info;
+ vmspace = imgp->proc->p_vmspace;
+ map = &vmspace->vm_map;
maxv = vm_map_max(map) - lim_max(td, RLIMIT_STACK);
- if (mapsz >= maxv - vm_map_min(map)) {
+ if (error == 0 && mapsz >= maxv - vm_map_min(map)) {
uprintf("Excessive mapping size\n");
error = ENOEXEC;
}
@@ -2516,9 +2534,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(p->p_psstrings);
#else
- ps_strings = p->p_sysent->sv_psstrings;
+ ps_strings = p->p_psstrings;
#endif
sbuf_bcat(sb, &structsize, sizeof(structsize));
sbuf_bcat(sb, &ps_strings, sizeof(ps_strings));
@@ -2758,7 +2776,7 @@
return (flags);
}
-vm_size_t
+void
__elfN(stackgap)(struct image_params *imgp, uintptr_t *stack_base)
{
uintptr_t range, rbase, gap;
@@ -2766,7 +2784,7 @@
pct = __elfN(aslr_stack_gap);
if (pct == 0)
- return (0);
+ return;
if (pct > 50)
pct = 50;
range = imgp->eff_stack_sz * pct / 100;
@@ -2774,5 +2792,4 @@
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");
@@ -171,12 +166,12 @@
#ifdef SCTL_MASK32
if (req->flags & SCTL_MASK32) {
unsigned int val;
- val = (unsigned int)p->p_sysent->sv_psstrings;
+ val = (unsigned int)p->p_psstrings;
error = SYSCTL_OUT(req, &val, sizeof(val));
} else
#endif
- error = SYSCTL_OUT(req, &p->p_sysent->sv_psstrings,
- sizeof(p->p_sysent->sv_psstrings));
+ error = SYSCTL_OUT(req, &p->p_psstrings,
+ sizeof(p->p_psstrings));
return error;
}
@@ -184,43 +179,19 @@
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;
-
- 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));
+ unsigned int val32;
+ val32 = round_page((unsigned int)p->p_psstrings +
+ p->p_sysent->sv_psstringssz);
+ return (SYSCTL_OUT(req, &val32, sizeof(val32)));
}
- return (error);
+#endif
+ val = round_page(p->p_psstrings + p->p_sysent->sv_psstringssz);
+ return (SYSCTL_OUT(req, &val, sizeof(val)));
}
static int
@@ -1233,7 +1204,20 @@
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;
+
+ /* Partially randomize the top the of the stack. */
+ stack_addr = sv->sv_usrstack;
+ exec_stackgap(imgp, &stack_addr);
+ stack_addr = round_page(stack_addr - ssiz);
+
+ if (stack_addr + ssiz != sv->sv_usrstack) {
+ error = vm_map_fixed(map, NULL, 0, stack_addr + ssiz,
+ sv->sv_usrstack - (stack_addr + ssiz), VM_PROT_NONE,
+ VM_PROT_NONE, MAP_CREATE_GUARD);
+ if (error != KERN_SUCCESS)
+ return (vm_mmap_to_errno(error));
+ }
+
stack_prot = 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,
@@ -1244,7 +1228,7 @@
stack_prot, error, vm_mmap_to_errno(error));
return (vm_mmap_to_errno(error));
}
- vmspace->vm_stkgap = 0;
+ imgp->stack_top = stack_addr + ssiz;
/*
* vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they
@@ -1595,11 +1579,9 @@
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;
+ (imgp->map_flags & MAP_ASLR) == 0)
return;
- }
- p->p_vmspace->vm_stkgap = imgp->sysent->sv_stackgap(imgp, dp);
+ imgp->sysent->sv_stackgap(imgp, dp);
}
/*
@@ -1624,9 +1606,8 @@
p = imgp->proc;
sysent = p->p_sysent;
- arginfo = (struct ps_strings *)sysent->sv_psstrings;
- destp = (uintptr_t)arginfo;
- imgp->ps_strings = arginfo;
+ destp = p->p_psstrings;
+ arginfo = imgp->ps_strings = (void *)destp;
/*
* Install sigcode.
@@ -1683,8 +1664,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,7 +1838,7 @@
int i, error;
error = 0;
- if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
+ if (proc_readmem(td, p, (vm_offset_t)p->p_psstrings, &pss,
sizeof(pss)) != sizeof(pss))
return (ENOMEM);
switch (type) {
@@ -1914,7 +1914,7 @@
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,
+ if (proc_readmem(td, p, (vm_offset_t)p->p_psstrings, &pss,
sizeof(pss)) != sizeof(pss))
return (ENOMEM);
switch (type) {
@@ -2980,13 +2980,13 @@
* process.
*/
ps_strings32 = SV_PROC_FLAG(p, SV_ILP32) != 0 ?
- PTROUT(p->p_sysent->sv_psstrings) : 0;
+ PTROUT(p->p_psstrings) : 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 = (uintptr_t)p->p_psstrings;
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 = p->p_psstrings -
*sv->sv_szsigcode;
- kst32.ksigtramp_end = sv->sv_psstrings;
+ kst32.ksigtramp_end = p->p_psstrings;
}
}
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 *)p->p_psstrings -
*sv->sv_szsigcode;
- kst.ksigtramp_end = (char *)sv->sv_psstrings;
+ kst.ksigtramp_end = (char *)p->p_psstrings;
}
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/kern/kern_thread.c
===================================================================
--- sys/kern/kern_thread.c
+++ sys/kern/kern_thread.c
@@ -101,7 +101,7 @@
"struct proc KBI p_filemon");
_Static_assert(offsetof(struct proc, p_comm) == 0x3e0,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x4c8,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x4d0,
"struct proc KBI p_emuldata");
#endif
#ifdef __i386__
@@ -121,7 +121,7 @@
"struct proc KBI p_filemon");
_Static_assert(offsetof(struct proc, p_comm) == 0x284,
"struct proc KBI p_comm");
-_Static_assert(offsetof(struct proc, p_emuldata) == 0x310,
+_Static_assert(offsetof(struct proc, p_emuldata) == 0x314,
"struct proc KBI p_emuldata");
#endif
Index: sys/mips/mips/elf_machdep.c
===================================================================
--- sys/mips/mips/elf_machdep.c
+++ sys/mips/mips/elf_machdep.c
@@ -73,6 +73,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/mips/mips/freebsd32_machdep.c
===================================================================
--- sys/mips/mips/freebsd32_machdep.c
+++ sys/mips/mips/freebsd32_machdep.c
@@ -94,6 +94,7 @@
.sv_maxuser = ((vm_offset_t)0x80000000),
.sv_usrstack = FREEBSD32_USRSTACK,
.sv_psstrings = FREEBSD32_PS_STRINGS,
+ .sv_psstringssz = sizeof(freebsd32_ps_strings),
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_strings = freebsd32_copyout_strings,
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)(p->p_psstrings -
*(sysent->sv_szsigcode));
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_sepc,
Index: sys/sys/imgact.h
===================================================================
--- sys/sys/imgact.h
+++ sys/sys/imgact.h
@@ -82,6 +82,7 @@
void *pagesizes;
int pagesizeslen;
vm_prot_t stack_prot;
+ uintptr_t stack_top;
u_long stack_sz;
u_long eff_stack_sz;
struct ucred *newcred; /* new credentials if changing */
Index: sys/sys/imgact_elf.h
===================================================================
--- sys/sys/imgact_elf.h
+++ sys/sys/imgact_elf.h
@@ -118,7 +118,7 @@
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 *);
+void __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
@@ -703,6 +703,7 @@
char p_comm[MAXCOMLEN + 1]; /* (x) Process name. */
struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */
struct pargs *p_args; /* (c) Process arguments. */
+ vm_offset_t p_psstrings; /* (c) PS_STRINGS address. */
rlim_t p_cpulimit; /* (c) Current CPU limit in seconds. */
signed char p_nice; /* (c) Process "nice" value. */
int p_fibnum; /* in this routing domain XXX MRT */
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,7 @@
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 *);
+ void (*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 +128,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
@@ -293,7 +293,6 @@
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 */
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);
}
@@ -4266,7 +4265,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);

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 17, 3:34 AM (10 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29788658
Default Alt Text
D33704.id100769.diff (32 KB)

Event Timeline