Page MenuHomeFreeBSD

D35349.id106568.diff
No OneTemporary

D35349.id106568.diff

Index: sys/amd64/amd64/exec_machdep.c
===================================================================
--- sys/amd64/amd64/exec_machdep.c
+++ sys/amd64/amd64/exec_machdep.c
@@ -77,6 +77,7 @@
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
#include <vm/pmap.h>
+#include <vm/vm_map.h>
#ifdef DDB
#ifndef KDB
@@ -203,7 +204,7 @@
fpstate_drop(td);
regs->tf_rsp = (long)sfp;
- regs->tf_rip = p->p_sysent->sv_sigcode_base;
+ regs->tf_rip = PROC_SIGCODE(p);
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
Index: sys/amd64/ia32/ia32_signal.c
===================================================================
--- sys/amd64/ia32/ia32_signal.c
+++ sys/amd64/ia32/ia32_signal.c
@@ -535,7 +535,7 @@
}
regs->tf_rsp = (uintptr_t)sfp;
- regs->tf_rip = p->p_sysent->sv_sigcode_base +
+ regs->tf_rip = PROC_SIGCODE(p) +
VDSO_FREEBSD4_IA32_SIGCODE_OFFSET - VDSO_IA32_SIGCODE_OFFSET;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
@@ -670,7 +670,7 @@
fpstate_drop(td);
regs->tf_rsp = (uintptr_t)sfp;
- regs->tf_rip = p->p_sysent->sv_sigcode_base;
+ regs->tf_rip = PROC_SIGCODE(p);
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
Index: sys/amd64/linux/linux_sysvec.c
===================================================================
--- sys/amd64/linux/linux_sysvec.c
+++ sys/amd64/linux/linux_sysvec.c
@@ -772,7 +772,7 @@
tkoff = kern_timekeep_base - linux_vdso_base;
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
- *ktimekeep_base = sv->sv_timekeep_base;
+ *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset;
tkoff = kern_tsc_selector - linux_vdso_base;
ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
Index: sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -924,7 +924,7 @@
tkoff = kern_timekeep_base - linux_vdso_base;
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
- *ktimekeep_base = sv->sv_timekeep_base;
+ *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset;
tkoff = kern_tsc_selector - linux_vdso_base;
ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
Index: sys/arm/arm/exec_machdep.c
===================================================================
--- sys/arm/arm/exec_machdep.c
+++ sys/arm/arm/exec_machdep.c
@@ -346,8 +346,8 @@
tf->tf_pc = (register_t)catcher;
tf->tf_usr_sp = (register_t)fp;
sysent = p->p_sysent;
- if (sysent->sv_sigcode_base != 0)
- tf->tf_usr_lr = (register_t)sysent->sv_sigcode_base;
+ if (sysent->sv_shared_page_base != 0)
+ tf->tf_usr_lr = (register_t)PROC_SIGCODE(p);
else
tf->tf_usr_lr = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
Index: sys/arm64/arm64/exec_machdep.c
===================================================================
--- sys/arm64/arm64/exec_machdep.c
+++ sys/arm64/arm64/exec_machdep.c
@@ -50,6 +50,8 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
#include <machine/armreg.h>
#include <machine/kdb.h>
@@ -626,7 +628,7 @@
tf->tf_x[2] = (register_t)&fp->sf_uc;
tf->tf_x[8] = (register_t)catcher;
tf->tf_sp = (register_t)fp;
- tf->tf_elr = (register_t)p->p_sysent->sv_sigcode_base;
+ tf->tf_elr = (register_t)PROC_SIGCODE(p);
/* Clear the single step flag while in the signal handler */
if ((td->td_pcb->pcb_flags & PCB_SINGLE_STEP) != 0) {
Index: sys/arm64/arm64/freebsd32_machdep.c
===================================================================
--- sys/arm64/arm64/freebsd32_machdep.c
+++ sys/arm64/arm64/freebsd32_machdep.c
@@ -418,8 +418,8 @@
tf->tf_elr = (register_t)catcher;
tf->tf_x[13] = (register_t)fp;
sysent = p->p_sysent;
- if (sysent->sv_sigcode_base != 0)
- tf->tf_x[14] = (register_t)sysent->sv_sigcode_base;
+ if (sysent->sv_shared_page_base != 0)
+ tf->tf_x[14] = (register_t)PROC_SIGCODE(p);
else
tf->tf_x[14] = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
Index: sys/arm64/linux/linux_sysvec.c
===================================================================
--- sys/arm64/linux/linux_sysvec.c
+++ sys/arm64/linux/linux_sysvec.c
@@ -619,7 +619,7 @@
tkoff = kern_timekeep_base - linux_vdso_base;
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
- *ktimekeep_base = sv->sv_timekeep_base;
+ *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset;
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -3525,7 +3525,7 @@
/*
* Install sigcode.
*/
- if (sysent->sv_sigcode_base == 0) {
+ if (sysent->sv_shared_page_base == 0) {
szsigcode = *sysent->sv_szsigcode;
destp -= szsigcode;
destp = rounddown2(destp, sizeof(uint32_t));
Index: sys/i386/i386/exec_machdep.c
===================================================================
--- sys/i386/i386/exec_machdep.c
+++ sys/i386/i386/exec_machdep.c
@@ -237,8 +237,8 @@
}
regs->tf_esp = (int)fp;
- if (p->p_sysent->sv_sigcode_base != 0) {
- regs->tf_eip = p->p_sysent->sv_sigcode_base + szsigcode -
+ if (p->p_sysent->sv_shared_page_base != 0) {
+ regs->tf_eip = PROC_SIGCODE(p) + szsigcode -
szosigcode;
} else {
/* a.out sysentvec does not use shared page */
@@ -363,7 +363,7 @@
}
regs->tf_esp = (int)sfp;
- regs->tf_eip = p->p_sysent->sv_sigcode_base + szsigcode -
+ regs->tf_eip = PROC_SIGCODE(p) + szsigcode -
szfreebsd4_sigcode;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
@@ -525,7 +525,7 @@
}
regs->tf_esp = (int)sfp;
- regs->tf_eip = p->p_sysent->sv_sigcode_base;
+ regs->tf_eip = PROC_SIGCODE(p);
if (regs->tf_eip == 0)
regs->tf_eip = PROC_PS_STRINGS(p) - szsigcode;
regs->tf_eflags &= ~(PSL_T | PSL_D);
Index: sys/i386/linux/linux_sysvec.c
===================================================================
--- sys/i386/linux/linux_sysvec.c
+++ sys/i386/linux/linux_sysvec.c
@@ -866,7 +866,7 @@
tkoff = kern_timekeep_base - linux_vdso_base;
ktimekeep_base = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
- *ktimekeep_base = sv->sv_timekeep_base;
+ *ktimekeep_base = sv->sv_shared_page_base + sv->sv_timekeep_offset;
tkoff = kern_tsc_selector - linux_vdso_base;
ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -209,6 +209,12 @@
__XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
": enable stack address randomization");
+static int __elfN(aslr_shared_page) = __ELF_WORD_SIZE == 64;
+SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, shared_page, CTLFLAG_RWTUN,
+ &__elfN(aslr_shared_page), 0,
+ __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
+ ": enable shared page address randomization");
+
static int __elfN(sigfastblock) = 1;
SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, sigfastblock,
CTLFLAG_RWTUN, &__elfN(sigfastblock), 0,
@@ -1305,6 +1311,8 @@
imgp->map_flags |= MAP_ASLR_IGNSTART;
if (__elfN(aslr_stack))
imgp->map_flags |= MAP_ASLR_STACK;
+ if (__elfN(aslr_shared_page))
+ imgp->map_flags |= MAP_ASLR_SHARED_PAGE;
}
if ((!__elfN(allow_wx) && (fctl0 & NT_FREEBSD_FCTL_WXNEEDED) == 0 &&
@@ -1433,11 +1441,14 @@
{
Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
Elf_Auxinfo *argarray, *pos;
+ struct vmspace *vmspace;
int error;
argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
+ vmspace = imgp->proc->p_vmspace;
+
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
@@ -1461,9 +1472,9 @@
AUXARGS_ENTRY_PTR(pos, AT_PAGESIZES, imgp->pagesizes);
AUXARGS_ENTRY(pos, AT_PAGESIZESLEN, imgp->pagesizeslen);
}
- if (imgp->sysent->sv_timekeep_base != 0) {
+ if ((imgp->sysent->sv_flags & SV_TIMEKEEP) != 0) {
AUXARGS_ENTRY(pos, AT_TIMEKEEP,
- imgp->sysent->sv_timekeep_base);
+ vmspace->vm_sp_base + imgp->sysent->sv_timekeep_offset);
}
AUXARGS_ENTRY(pos, AT_STACKPROT, imgp->sysent->sv_shared_page_obj
!= NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
@@ -1479,10 +1490,16 @@
AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc);
AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv);
AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings);
- if (imgp->sysent->sv_fxrng_gen_base != 0)
- AUXARGS_ENTRY(pos, AT_FXRNG, imgp->sysent->sv_fxrng_gen_base);
- if (imgp->sysent->sv_vdso_base != 0 && __elfN(vdso) != 0)
- AUXARGS_ENTRY(pos, AT_KPRELOAD, imgp->sysent->sv_vdso_base);
+#ifdef RANDOM_FENESTRASX
+ if ((imgp->sysent->sv_flags & SV_RNG_SEED_VER) != 0) {
+ AUXARGS_ENTRY(pos, AT_FXRNG,
+ vmspace->vm_sp_base + imgp->sysent->sv_fxrng_gen_offset);
+ }
+#endif
+ if ((imgp->sysent->sv_flags & SV_DSO_SIG) != 0 && __elfN(vdso) != 0) {
+ AUXARGS_ENTRY(pos, AT_KPRELOAD,
+ vmspace->vm_sp_base + imgp->sysent->sv_vdso_offset);
+ }
AUXARGS_ENTRY(pos, AT_NULL, 0);
free(imgp->auxargs, M_TEMP);
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -1107,13 +1107,12 @@
if (sv->sv_shared_page_obj == NULL)
return;
- pmap_remove(vmspace_pmap(vmspace), sv->sv_shared_page_base,
- sv->sv_shared_page_base + sv->sv_shared_page_len);
+ pmap_remove(vmspace_pmap(vmspace), p->p_vmspace->vm_sp_base,
+ p->p_vmspace->vm_sp_base + sv->sv_shared_page_len);
}
/*
- * Run down the current address space and install a new one. Map the shared
- * page.
+ * Run down the current address space and install a new one.
*/
int
exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
@@ -1122,7 +1121,6 @@
struct proc *p = imgp->proc;
struct vmspace *vmspace = p->p_vmspace;
struct thread *td = curthread;
- vm_object_t obj;
vm_offset_t sv_minuser;
vm_map_t map;
@@ -1159,7 +1157,8 @@
*/
vm_map_lock(map);
vm_map_modflags(map, 0, MAP_WIREFUTURE | MAP_ASLR |
- MAP_ASLR_IGNSTART | MAP_ASLR_STACK | MAP_WXORX);
+ MAP_ASLR_IGNSTART | MAP_ASLR_STACK | MAP_ASLR_SHARED_PAGE |
+ MAP_WXORX);
vm_map_unlock(map);
} else {
error = vmspace_exec(p, sv_minuser, sv->sv_maxuser);
@@ -1170,21 +1169,6 @@
}
map->flags |= imgp->map_flags;
- /* Map a shared page */
- obj = sv->sv_shared_page_obj;
- if (obj != NULL) {
- vm_object_reference(obj);
- error = vm_map_fixed(map, obj, 0,
- sv->sv_shared_page_base, sv->sv_shared_page_len,
- VM_PROT_READ | VM_PROT_EXECUTE,
- VM_PROT_READ | VM_PROT_EXECUTE,
- MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE);
- if (error != KERN_SUCCESS) {
- vm_object_deallocate(obj);
- return (vm_mmap_to_errno(error));
- }
- }
-
return (sv->sv_onexec != NULL ? sv->sv_onexec(p, imgp) : 0);
}
@@ -1200,9 +1184,11 @@
vm_map_t map;
struct vmspace *vmspace;
vm_offset_t stack_addr, stack_top;
+ vm_offset_t sharedpage_addr;
u_long ssiz;
int error, find_space, stack_off;
vm_prot_t stack_prot;
+ vm_object_t obj;
p = imgp->proc;
sv = p->p_sysent;
@@ -1254,6 +1240,43 @@
stack_top -= rounddown2(stack_off & PAGE_MASK, sizeof(void *));
}
+ /* Map a shared page */
+ obj = sv->sv_shared_page_obj;
+ if (obj == NULL) {
+ /*
+ * No shared page is provided for this ABI,
+ * e.g. in case of a.out binaries.
+ */
+ sharedpage_addr = 0;
+ goto out;
+ }
+
+ /*
+ * If randomization is disabled the vm logic maps it exactly
+ * to the specific address (VMFS_NO_SPACE).
+ * Otherwise it can choose any address above .data section.
+ * Same logic is used for stack address randomization.
+ */
+ if ((map->flags & MAP_ASLR_SHARED_PAGE) != 0) {
+ sharedpage_addr = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
+ lim_max(curthread, RLIMIT_DATA));
+ find_space = VMFS_ANY_SPACE;
+ } else {
+ sharedpage_addr = sv->sv_shared_page_base;
+ find_space = VMFS_NO_SPACE;
+ }
+ vm_object_reference(obj);
+ error = vm_map_find(map, obj, 0,
+ &sharedpage_addr, sv->sv_shared_page_len,
+ sv->sv_maxuser, find_space,
+ VM_PROT_READ | VM_PROT_EXECUTE,
+ VM_PROT_READ | VM_PROT_EXECUTE,
+ MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE);
+ if (error != KERN_SUCCESS) {
+ vm_object_deallocate(obj);
+ return (vm_mmap_to_errno(error));
+ }
+out:
/*
* vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they
* are still used to enforce the stack rlimit on the process stack.
@@ -1261,6 +1284,7 @@
vmspace->vm_maxsaddr = (char *)stack_addr;
vmspace->vm_stacktop = stack_top;
vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT;
+ vmspace->vm_sp_base = sharedpage_addr;
return (0);
}
@@ -1624,7 +1648,7 @@
/*
* Install sigcode.
*/
- if (sysent->sv_sigcode_base == 0 && sysent->sv_szsigcode != NULL) {
+ if (sysent->sv_shared_page_base == 0 && sysent->sv_szsigcode != NULL) {
szsigcode = *(sysent->sv_szsigcode);
destp -= szsigcode;
destp = rounddown2(destp, sizeof(void *));
Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -3096,9 +3096,9 @@
if ((req->flags & SCTL_MASK32) != 0) {
bzero(&kst32, sizeof(kst32));
if (SV_PROC_FLAG(p, SV_ILP32)) {
- if (sv->sv_sigcode_base != 0) {
- kst32.ksigtramp_start = sv->sv_sigcode_base;
- kst32.ksigtramp_end = sv->sv_sigcode_base +
+ if (sv->sv_shared_page_base != 0) {
+ kst32.ksigtramp_start = PROC_SIGCODE(p);
+ kst32.ksigtramp_end = kst32.ksigtramp_start +
((sv->sv_flags & SV_DSO_SIG) == 0 ?
*sv->sv_szsigcode :
(uintptr_t)sv->sv_szsigcode);
@@ -3114,9 +3114,9 @@
}
#endif
bzero(&kst, sizeof(kst));
- if (sv->sv_sigcode_base != 0) {
- kst.ksigtramp_start = (char *)sv->sv_sigcode_base;
- kst.ksigtramp_end = (char *)sv->sv_sigcode_base +
+ if (sv->sv_shared_page_base != 0) {
+ kst.ksigtramp_start = (char *)PROC_SIGCODE(p);
+ kst.ksigtramp_end = (char *)kst.ksigtramp_start +
((sv->sv_flags & SV_DSO_SIG) == 0 ? *sv->sv_szsigcode :
(uintptr_t)sv->sv_szsigcode);
} else {
@@ -3245,6 +3245,8 @@
kvm.kvm_map_flags |= KMAP_FLAG_WXORX;
if ((vmspace->vm_map.flags & MAP_ASLR_STACK) != 0)
kvm.kvm_map_flags |= KMAP_FLAG_ASLR_STACK;
+ if ((vmspace->vm_map.flags & MAP_ASLR_SHARED_PAGE) != 0)
+ kvm.kvm_map_flags |= KMAP_FLAG_ASLR_SHARED_PAGE;
#ifdef COMPAT_FREEBSD32
if (SV_CURPROC_FLAG(SV_ILP32)) {
Index: sys/kern/kern_sharedpage.c
===================================================================
--- sys/kern/kern_sharedpage.c
+++ sys/kern/kern_sharedpage.c
@@ -305,10 +305,6 @@
exec_sysvec_init(void *param)
{
struct sysentvec *sv;
- vm_offset_t sb;
-#ifdef RANDOM_FENESTRASX
- ptrdiff_t base;
-#endif
u_int flags;
int res;
@@ -322,19 +318,18 @@
sv->sv_shared_page_obj = shared_page_obj;
if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD) {
if ((flags & SV_DSO_SIG) != 0) {
- sb = sv->sv_shared_page_base;
res = shared_page_fill((uintptr_t)sv->sv_szsigcode,
16, sv->sv_sigcode);
if (res == -1)
panic("copying sigtramp to shared page");
- sb += res;
- sv->sv_vdso_base = sb;
- sb += sv->sv_sigcodeoff;
- sv->sv_sigcode_base = sb;
+ sv->sv_vdso_offset = res;
+ sv->sv_sigcode_offset = res + sv->sv_sigcodeoff;
} else {
- sv->sv_sigcode_base = sv->sv_shared_page_base +
- shared_page_fill(*(sv->sv_szsigcode), 16,
- sv->sv_sigcode);
+ res = shared_page_fill(*(sv->sv_szsigcode),
+ 16, sv->sv_sigcode);
+ if (res == -1)
+ panic("copying sigtramp to shared page");
+ sv->sv_sigcode_offset = res;
}
}
if ((flags & SV_TIMEKEEP) != 0) {
@@ -348,8 +343,7 @@
KASSERT(compat32_svtk != NULL,
("Compat32 not registered"));
}
- sv->sv_timekeep_base = sv->sv_shared_page_base +
- compat32_svtk->sv_timekeep_off;
+ sv->sv_timekeep_offset = compat32_svtk->sv_timekeep_off;
} else {
#endif
if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD) {
@@ -360,8 +354,7 @@
KASSERT(host_svtk != NULL,
("Host not registered"));
}
- sv->sv_timekeep_base = sv->sv_shared_page_base +
- host_svtk->sv_timekeep_off;
+ sv->sv_timekeep_offset = host_svtk->sv_timekeep_off;
#ifdef COMPAT_FREEBSD32
}
#endif
@@ -375,8 +368,8 @@
*/
if (fxrng_shpage_mapping == NULL)
alloc_sv_fxrng_generation();
- base = (char *)fxrng_shpage_mapping - shared_page_mapping;
- sv->sv_fxrng_gen_base = sv->sv_shared_page_base + base;
+ sv->sv_fxrng_gen_offset =
+ (char *)fxrng_shpage_mapping - shared_page_mapping;
}
#endif
}
@@ -392,20 +385,13 @@
(sv->sv_flags & SV_RNG_SEED_VER));
sv2->sv_shared_page_obj = sv->sv_shared_page_obj;
- sv2->sv_sigcode_base = sv2->sv_shared_page_base +
- (sv->sv_sigcode_base - sv->sv_shared_page_base);
- if ((sv2->sv_flags & SV_DSO_SIG) != 0) {
- sv2->sv_vdso_base = sv2->sv_shared_page_base +
- (sv->sv_vdso_base - sv->sv_shared_page_base);
- }
+ sv2->sv_sigcode_offset = sv->sv_sigcode_offset;
+ if ((sv2->sv_flags & SV_DSO_SIG) != 0)
+ sv2->sv_vdso_offset = sv->sv_vdso_offset;
if ((sv2->sv_flags & SV_ABI_MASK) != SV_ABI_FREEBSD)
return;
- if ((sv2->sv_flags & SV_TIMEKEEP) != 0) {
- sv2->sv_timekeep_base = sv2->sv_shared_page_base +
- (sv->sv_timekeep_base - sv->sv_shared_page_base);
- }
- if ((sv2->sv_flags & SV_RNG_SEED_VER) != 0) {
- sv2->sv_fxrng_gen_base = sv2->sv_shared_page_base +
- (sv->sv_fxrng_gen_base - sv->sv_shared_page_base);
- }
+ if ((sv2->sv_flags & SV_TIMEKEEP) != 0)
+ sv2->sv_timekeep_offset = sv->sv_timekeep_offset;
+ if ((sv2->sv_flags & SV_RNG_SEED_VER) != 0)
+ sv2->sv_fxrng_gen_offset = sv->sv_fxrng_gen_offset;
}
Index: sys/powerpc/powerpc/elf32_machdep.c
===================================================================
--- sys/powerpc/powerpc/elf32_machdep.c
+++ sys/powerpc/powerpc/elf32_machdep.c
@@ -52,6 +52,8 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
#include <machine/altivec.h>
#include <machine/cpu.h>
Index: sys/powerpc/powerpc/elf64_machdep.c
===================================================================
--- sys/powerpc/powerpc/elf64_machdep.c
+++ sys/powerpc/powerpc/elf64_machdep.c
@@ -49,6 +49,8 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
#include <machine/altivec.h>
#include <machine/cpu.h>
@@ -216,10 +218,10 @@
* exec_sysvec_init_secondary() assumes secondary sysvecs use
* identical signal code, and skips allocating a second copy.
* Since the ELFv2 trampoline is a strict subset of the ELFv1 code,
- * we can work around this by adjusting the base address. This also
+ * we can work around this by adjusting the offset. This also
* avoids two copies of the trampoline code being allocated!
*/
- elf64_freebsd_sysvec_v2.sv_sigcode_base +=
+ elf64_freebsd_sysvec_v2.sv_sigcode_offset +=
(uintptr_t)sigcode64_elfv2 - (uintptr_t)&sigcode64;
elf64_freebsd_sysvec_v2.sv_szsigcode = &szsigcode64_elfv2;
}
Index: sys/powerpc/powerpc/elf_common.c
===================================================================
--- sys/powerpc/powerpc/elf_common.c
+++ sys/powerpc/powerpc/elf_common.c
@@ -34,6 +34,7 @@
{
Elf_Auxargs *args;
Elf_Auxinfo *argarray, *pos;
+ struct vmspace *vmspace;
int error;
/*
@@ -58,6 +59,8 @@
argarray = pos = malloc(AT_OLD_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
+ vmspace = imgp->proc->p_vmspace;
+
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_OLD_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, AT_OLD_PHDR, args->phdr);
@@ -81,9 +84,9 @@
AUXARGS_ENTRY_PTR(pos, AT_OLD_PAGESIZES, imgp->pagesizes);
AUXARGS_ENTRY(pos, AT_OLD_PAGESIZESLEN, imgp->pagesizeslen);
}
- if (imgp->sysent->sv_timekeep_base != 0) {
+ if ((imgp->sysent->sv_flags & SV_TIMEKEEP) != 0) {
AUXARGS_ENTRY(pos, AT_OLD_TIMEKEEP,
- imgp->sysent->sv_timekeep_base);
+ vmspace->vm_sp_base + imgp->sysent->sv_timekeep_offset);
}
AUXARGS_ENTRY(pos, AT_OLD_STACKPROT, imgp->sysent->sv_shared_page_obj
!= NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
Index: sys/powerpc/powerpc/exec_machdep.c
===================================================================
--- sys/powerpc/powerpc/exec_machdep.c
+++ sys/powerpc/powerpc/exec_machdep.c
@@ -94,7 +94,10 @@
#include <machine/trap.h>
#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <vm/vm_map.h>
#ifdef FPU_EMU
#include <powerpc/fpu/fpu_extern.h>
@@ -310,7 +313,7 @@
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p);
- tf->srr0 = (register_t)p->p_sysent->sv_sigcode_base;
+ tf->srr0 = (register_t)PROC_SIGCODE(p);
/*
* copy the frame out to userland.
Index: sys/riscv/riscv/exec_machdep.c
===================================================================
--- sys/riscv/riscv/exec_machdep.c
+++ sys/riscv/riscv/exec_machdep.c
@@ -415,8 +415,8 @@
tf->tf_sp = (register_t)fp;
sysent = p->p_sysent;
- if (sysent->sv_sigcode_base != 0)
- tf->tf_ra = (register_t)sysent->sv_sigcode_base;
+ if (sysent->sv_shared_page_base != 0)
+ tf->tf_ra = (register_t)PROC_SIGCODE(p);
else
tf->tf_ra = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
Index: sys/sys/exec.h
===================================================================
--- sys/sys/exec.h
+++ sys/sys/exec.h
@@ -90,6 +90,14 @@
#define PROC_PS_STRINGS(p) \
((p)->p_vmspace->vm_stacktop - (p)->p_sysent->sv_psstringssz)
+/*
+ * Address of signal trampoline (in user space).
+ * This assumes that the sigcode resides in the shared page, which is true
+ * in all cases, except for a.out binaries.
+ */
+#define PROC_SIGCODE(p) \
+ ((p)->p_vmspace->vm_sp_base + (p)->p_sysent->sv_sigcode_offset)
+
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
@@ -91,7 +91,7 @@
bool vmspace_destroyed; /* we've blown away original vm space */
bool opened; /* we have opened executable vnode */
bool textset;
- u_int map_flags;
+ vm_flags_t map_flags;
};
#ifdef _KERNEL
Index: sys/sys/sysent.h
===================================================================
--- sys/sys/sysent.h
+++ sys/sys/sysent.h
@@ -137,19 +137,19 @@
void (*sv_set_syscall_retval)(struct thread *, int);
int (*sv_fetch_syscall_args)(struct thread *);
const char **sv_syscallnames;
- vm_offset_t sv_timekeep_base;
+ vm_offset_t sv_timekeep_offset;
vm_offset_t sv_shared_page_base;
vm_offset_t sv_shared_page_len;
- vm_offset_t sv_sigcode_base;
+ vm_offset_t sv_sigcode_offset;
void *sv_shared_page_obj;
- vm_offset_t sv_vdso_base;
+ vm_offset_t sv_vdso_offset;
void (*sv_schedtail)(struct thread *);
void (*sv_thread_detach)(struct thread *);
int (*sv_trap)(struct thread *);
u_long *sv_hwcap; /* Value passed in AT_HWCAP. */
u_long *sv_hwcap2; /* Value passed in AT_HWCAP2. */
const char *(*sv_machine_arch)(struct proc *);
- vm_offset_t sv_fxrng_gen_base;
+ vm_offset_t sv_fxrng_gen_offset;
void (*sv_onexec_old)(struct thread *td);
int (*sv_onexec)(struct proc *, struct image_params *);
void (*sv_onexit)(struct proc *);
Index: sys/sys/user.h
===================================================================
--- sys/sys/user.h
+++ sys/sys/user.h
@@ -625,6 +625,7 @@
#define KMAP_FLAG_ASLR_IGNSTART 0x04 /* ASLR may map into sbrk grow region */
#define KMAP_FLAG_WXORX 0x08 /* W^X mapping policy is enforced */
#define KMAP_FLAG_ASLR_STACK 0x10 /* the stack location is randomized */
+#define KMAP_FLAG_ASLR_SHARED_PAGE 0x20 /* the shared page location is randomized */
struct kinfo_vm_layout {
uintptr_t kvm_min_user_addr;
Index: sys/vm/vm.h
===================================================================
--- sys/vm/vm.h
+++ sys/vm/vm.h
@@ -88,6 +88,8 @@
#define VM_PROT_RW (VM_PROT_READ|VM_PROT_WRITE)
#define VM_PROT_DEFAULT VM_PROT_ALL
+typedef uint16_t vm_flags_t;
+
enum obj_type {
OBJT_DEFAULT,
OBJT_SWAP,
Index: sys/vm/vm_map.h
===================================================================
--- sys/vm/vm_map.h
+++ sys/vm/vm_map.h
@@ -79,7 +79,6 @@
* vm_map_entry_t an entry in an address map.
*/
-typedef u_char vm_flags_t;
typedef u_int vm_eflags_t;
/*
@@ -230,6 +229,7 @@
#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 */
+#define MAP_ASLR_SHARED_PAGE 0x100 /* shared page location is randomized */
#ifdef _KERNEL
#if defined(KLD_MODULE) && !defined(KLD_TIED)
@@ -295,6 +295,7 @@
caddr_t vm_daddr; /* (c) user virtual address of data */
caddr_t vm_maxsaddr; /* user VA at max stack growth */
vm_offset_t vm_stacktop; /* top of the stack, may not be page-aligned */
+ vm_offset_t vm_sp_base; /* shared page address */
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
@@ -4264,6 +4264,7 @@
vm2->vm_daddr = vm1->vm_daddr;
vm2->vm_maxsaddr = vm1->vm_maxsaddr;
vm2->vm_stacktop = vm1->vm_stacktop;
+ vm2->vm_sp_base = vm1->vm_sp_base;
vm_map_lock(old_map);
if (old_map->busy)
vm_map_wait_busy(old_map);
@@ -4282,7 +4283,7 @@
new_map->anon_loc = old_map->anon_loc;
new_map->flags |= old_map->flags & (MAP_ASLR | MAP_ASLR_IGNSTART |
- MAP_ASLR_STACK | MAP_WXORX);
+ MAP_ASLR_STACK | MAP_ASLR_SHARED_PAGE | MAP_WXORX);
VM_MAP_ENTRY_FOREACH(old_entry, old_map) {
if ((old_entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0)
Index: tests/sys/kern/kern_copyin.c
===================================================================
--- tests/sys/kern/kern_copyin.c
+++ tests/sys/kern/kern_copyin.c
@@ -34,6 +34,7 @@
#include <sys/exec.h>
#include <sys/sysctl.h>
#include <sys/user.h>
+#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
@@ -104,6 +105,8 @@
{
char template[] = "copyin.XXXXXX";
uintptr_t maxuser;
+ size_t size;
+ void *addr;
#if defined(__mips__)
/*
@@ -119,6 +122,16 @@
#else
maxuser = VM_MAXUSER_ADDRESS;
#endif
+ size = sysconf(_SC_PAGESIZE);
+
+ /*
+ * Since the shared page address can be randomized we need to make
+ * sure that something is mapped at the top of the user address space.
+ * Otherwise reading bytes from maxuser-X will fail rendering this test
+ * useless.
+ */
+ addr = mmap((void *)(maxuser - size), size, PROT_READ,
+ MAP_ANON | MAP_FIXED | MAP_EXCL, -1, 0);
scratch_file = mkstemp(template);
ATF_REQUIRE(scratch_file != -1);
@@ -141,6 +154,9 @@
ATF_CHECK(copyin_checker(ADDR_SIGNED, 1) == EFAULT);
ATF_CHECK(copyin_checker2(ADDR_SIGNED) == EFAULT);
#endif
+
+ if (addr != MAP_FAILED)
+ munmap(addr, PAGE_SIZE);
}
ATF_TP_ADD_TCS(tp)

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 8, 4:41 PM (12 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29410370
Default Alt Text
D35349.id106568.diff (26 KB)

Event Timeline