Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147021438
D35349.id106568.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D35349.id106568.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D35349: [RFC] Shared page address randomization
Attached
Detach File
Event Timeline
Log In to Comment