FreeBSD Bugzilla – Attachment 136327 Details for
Bug 181497
[kernel] [patch] Add ASLR feature to kernel
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
aslr-2014-03-21_01.patch.txt
aslr-2014-03-21_01.patch.txt (text/plain; x-unix-mode=0644), 35.62 KB, created by
Shawn Webb
on 2014-03-21 11:52:58 UTC
(
hide
)
Description:
aslr-2014-03-21_01.patch.txt
Filename:
MIME Type:
Creator:
Shawn Webb
Created:
2014-03-21 11:52:58 UTC
Size:
35.62 KB
patch
obsolete
>diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c >index b093a76..1bf0d12 100644 >--- a/sys/compat/freebsd32/freebsd32_misc.c >+++ b/sys/compat/freebsd32/freebsd32_misc.c >@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); > #include "opt_compat.h" > #include "opt_inet.h" > #include "opt_inet6.h" >+#include "opt_pax.h" > > #define __ELF_WORD_SIZE 32 > >@@ -113,6 +114,10 @@ __FBSDID("$FreeBSD$"); > > FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD"); > >+#ifdef PAX_ASLR >+#include <sys/pax.h> >+#endif /* PAX_ASLR */ >+ > #ifndef __mips__ > CTASSERT(sizeof(struct timeval32) == 8); > CTASSERT(sizeof(struct timespec32) == 8); >@@ -2822,6 +2827,9 @@ freebsd32_copyout_strings(struct image_params *imgp) > { > int argc, envc, i; > u_int32_t *vectp; >+#ifdef PAX_ASLR >+ uintptr_t orig_destp; >+#endif /* PAX_ASLR */ > char *stringp; > uintptr_t destp; > u_int32_t *stack_base; >@@ -2847,6 +2855,11 @@ freebsd32_copyout_strings(struct image_params *imgp) > szsigcode = 0; > destp = (uintptr_t)arginfo; > >+#ifdef PAX_ASLR >+ orig_destp = destp; >+ pax_aslr_stack(curthread, &destp, orig_destp); >+#endif /* PAX_ASLR */ >+ > /* > * install sigcode > */ >diff --git a/sys/conf/files b/sys/conf/files >index 596cc69..c2e59ca 100644 >--- a/sys/conf/files >+++ b/sys/conf/files >@@ -2835,6 +2835,7 @@ kern/kern_mtxpool.c standard > kern/kern_mutex.c standard > kern/kern_ntptime.c standard > kern/kern_osd.c standard >+kern/kern_pax.c optional pax_aslr > kern/kern_physio.c standard > kern/kern_pmc.c standard > kern/kern_poll.c optional device_polling >diff --git a/sys/conf/options b/sys/conf/options >index 75fe424..ecabb5f 100644 >--- a/sys/conf/options >+++ b/sys/conf/options >@@ -910,6 +910,9 @@ RACCT opt_global.h > # Resource Limits > RCTL opt_global.h > >+# PaX - hardening options >+PAX_ASLR opt_pax.h >+PAX_ASLR_MAX_SEC opt_pax.h > # Random number generator(s) > RANDOM_YARROW opt_random.h > RANDOM_FORTUNA opt_random.h >diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c >index d5ec365..308e3f9 100644 >--- a/sys/kern/imgact_elf.c >+++ b/sys/kern/imgact_elf.c >@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); > #include "opt_capsicum.h" > #include "opt_compat.h" > #include "opt_core.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/capsicum.h> >@@ -47,7 +48,9 @@ __FBSDID("$FreeBSD$"); > #include <sys/mount.h> > #include <sys/mman.h> > #include <sys/namei.h> >+#include <sys/pax.h> > #include <sys/pioctl.h> >+#include <sys/jail.h> > #include <sys/proc.h> > #include <sys/procfs.h> > #include <sys/racct.h> >@@ -600,6 +603,9 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr, > u_long rbase; > u_long base_addr = 0; > int error, i, numsegs; >+#ifdef PAX_ASLR >+ struct prison *pr; >+#endif > > #ifdef CAPABILITY_MODE > /* >@@ -655,11 +661,17 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr, > hdr = (const Elf_Ehdr *)imgp->image_header; > if ((error = __elfN(check_header)(hdr)) != 0) > goto fail; >- if (hdr->e_type == ET_DYN) >+ if (hdr->e_type == ET_DYN) { > rbase = *addr; >- else if (hdr->e_type == ET_EXEC) >+#ifdef PAX_ASLR >+ if (pax_aslr_active(NULL, imgp->proc)) { >+ pr = pax_aslr_get_prison(NULL, imgp->proc); >+ rbase += round_page(PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_EXEC_LSB, pr->pr_pax_aslr_exec_len)); >+ } >+#endif >+ } else if (hdr->e_type == ET_EXEC) { > rbase = 0; >- else { >+ } else { > error = ENOEXEC; > goto fail; > } >@@ -729,6 +741,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) > Elf_Brandinfo *brand_info; > char *path; > struct sysentvec *sv; >+#ifdef PAX_ASLR >+ struct prison *pr; >+#endif > > /* > * Do we have a valid ELF header ? >@@ -793,10 +808,20 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) > * Honour the base load address from the dso if it is > * non-zero for some reason. > */ >- if (baddr == 0) >+ if (baddr == 0) { >+#ifdef PAX_ASLR >+ if (pax_aslr_active(NULL, imgp->proc)) { >+ pr = pax_aslr_get_prison(NULL, imgp->proc); >+ et_dyn_addr = trunc_page(PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_EXEC_LSB, pr->pr_pax_aslr_exec_len)); >+ } else { >+ et_dyn_addr = ET_DYN_LOAD_ADDR; >+ } >+#else > et_dyn_addr = ET_DYN_LOAD_ADDR; >- else >+#endif >+ } else { > et_dyn_addr = 0; >+ } > } else > et_dyn_addr = 0; > sv = brand_info->sysvec; >diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c >index 9f223ca..fe6357f 100644 >--- a/sys/kern/kern_exec.c >+++ b/sys/kern/kern_exec.c >@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); > #include "opt_capsicum.h" > #include "opt_hwpmc_hooks.h" > #include "opt_ktrace.h" >+#include "opt_pax.h" > #include "opt_vm.h" > > #include <sys/param.h> >@@ -94,6 +95,10 @@ __FBSDID("$FreeBSD$"); > dtrace_execexit_func_t dtrace_fasttrap_exec; > #endif > >+#ifdef PAX_ASLR >+#include <sys/pax.h> >+#endif /* PAX_ASLR */ >+ > SDT_PROVIDER_DECLARE(proc); > SDT_PROBE_DEFINE1(proc, kernel, , exec, "char *"); > SDT_PROBE_DEFINE1(proc, kernel, , exec__failure, "int"); >@@ -1055,6 +1060,10 @@ exec_new_vmspace(imgp, sv) > map = &vmspace->vm_map; > } > >+#ifdef PAX_ASLR >+ pax_aslr_init(curthread, imgp); >+#endif /* PAX_ASLR */ >+ > /* Map a shared page */ > obj = sv->sv_shared_page_obj; > if (obj != NULL) { >@@ -1231,6 +1240,9 @@ exec_copyout_strings(imgp) > { > int argc, envc; > char **vectp; >+#ifdef PAX_ASLR >+ uintptr_t orig_destp; >+#endif /* PAX_ASLR */ > char *stringp; > uintptr_t destp; > register_t *stack_base; >@@ -1239,6 +1251,7 @@ exec_copyout_strings(imgp) > size_t execpath_len; > int szsigcode, szps; > char canary[sizeof(long) * 8]; >+ unsigned int sgap; > > szps = sizeof(pagesizes[0]) * MAXPAGESIZES; > /* >@@ -1256,7 +1269,12 @@ exec_copyout_strings(imgp) > if (p->p_sysent->sv_szsigcode != NULL) > szsigcode = *(p->p_sysent->sv_szsigcode); > } >+ sgap=(unsigned int)(ALIGN(arc4random()&((64*1024)-1))); > destp = (uintptr_t)arginfo; >+#ifdef PAX_ASLR >+ orig_destp = destp; >+ pax_aslr_stack(curthread, &destp, orig_destp); >+#endif /* PAX_ASLR */ > > /* > * install sigcode >diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c >index 47cd568..f8751a4 100644 >--- a/sys/kern/kern_jail.c >+++ b/sys/kern/kern_jail.c >@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); > #include "opt_ddb.h" > #include "opt_inet.h" > #include "opt_inet6.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/types.h> >@@ -60,6 +61,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/syscallsubr.h> > #include <sys/sysctl.h> > #include <sys/vnode.h> >+#include <sys/pax.h> > > #include <net/if.h> > #include <net/if_var.h> >@@ -114,6 +116,20 @@ struct prison prison0 = { > .pr_flags = PR_HOST|_PR_IP_SADDRSEL, > #endif > .pr_allow = PR_ALLOW_ALL, >+#ifdef PAX_ASLR >+ .pr_pax_set = 0, >+ .pr_pax_aslr_status = 0, >+ .pr_pax_aslr_debug = 0, >+ .pr_pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MIN_LEN, >+ .pr_pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MIN_LEN, >+ .pr_pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MIN_LEN, >+#ifdef COMPAT_FREEBSD32 >+ .pr_pax_aslr_compat_status = 0, >+ .pr_pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN, >+ .pr_pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN, >+ .pr_pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN, >+#endif /* COMPAT_FREEBSD32 */ >+#endif /* PAX_ASLR */ > }; > MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); > >diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c >new file mode 100644 >index 0000000..2185baf >--- /dev/null >+++ b/sys/kern/kern_pax.c >@@ -0,0 +1,588 @@ >+/*- >+ * Copyright (c) 2013, by Oliver Pinter <oliver.pntr at gmail.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. The name of the developer may NOT be used to endorse or promote products >+ * derived from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ * >+ * $FreeBSD$ >+ * >+ * Enhancements made by Shawn "lattera" Webb under the direction of SoldierX. >+ */ >+ >+#include <sys/cdefs.h> >+__FBSDID("$FreeBSD$"); >+ >+#include "opt_pax.h" >+#include "opt_compat.h" >+ >+#include <sys/param.h> >+#include <sys/systm.h> >+#include <sys/kernel.h> >+#include <sys/imgact.h> >+#include <sys/sysent.h> >+#include <sys/proc.h> >+#include <sys/elf_common.h> >+#include <sys/pax.h> >+#include <sys/sysctl.h> >+#include <sys/vnode.h> >+#include <sys/queue.h> >+#include <sys/libkern.h> >+#include <sys/jail.h> >+ >+#include <sys/mman.h> >+#include <sys/libkern.h> >+#include <sys/exec.h> >+ >+#include <vm/pmap.h> >+#include <vm/vm_map.h> >+ >+static int sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS); >+ >+/* >+ * sysctls and tunables >+ */ >+int pax_aslr_status = PAX_ASLR_ENABLED; >+int pax_aslr_debug = 0; >+ >+#ifdef PAX_ASLR_MAX_SEC >+int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MAX_LEN; >+int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MAX_LEN; >+int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MAX_LEN; >+#else >+int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_MIN_LEN; >+int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_MIN_LEN; >+int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_MIN_LEN; >+#endif /* PAX_ASLR_MAX_SEC */ >+ >+ >+SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0, >+ "PaX (exploit mitigation) features."); >+SYSCTL_NODE(_security_pax, OID_AUTO, aslr, CTLFLAG_RD, 0, >+ "Address Space Layout Randomization."); >+ >+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, status, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_status, "I", >+ "Restrictions status. " >+ "0 - disabled, " >+ "1 - enabled, " >+ "2 - global enabled, " >+ "3 - force global enabled"); >+TUNABLE_INT("security.pax.aslr.status", &pax_aslr_status); >+ >+SYSCTL_INT(_security_pax_aslr, OID_AUTO, debug, CTLFLAG_RWTUN|CTLFLAG_PRISON, &pax_aslr_debug, 0, "ASLR debug mode"); >+TUNABLE_INT("security.pax.aslr.debug", &pax_aslr_debug); >+ >+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, mmap_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_mmap, "I", >+ "Number of bits randomized for mmap(2) calls. " >+ "32 bit: [8,16] 64 bit: [16,32]"); >+TUNABLE_INT("security.pax.aslr.mmap", &pax_aslr_mmap_len); >+ >+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, stack_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_stack, "I", >+ "Number of bits randomized for the stack. " >+ "32 bit: [6,12] 64 bit: [12,21]"); >+TUNABLE_INT("security.pax.aslr.stack", &pax_aslr_stack_len); >+ >+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, exec_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_exec, "I", >+ "Number of bits randomized for the PIE exec base. " >+ "32 bit: [6,12] 64 bit: [12,21]"); >+TUNABLE_INT("security.pax.aslr.stack", &pax_aslr_exec_len); >+ >+static int >+sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = (pr != NULL) ? pr->pr_pax_aslr_status : pax_aslr_status; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ switch (val) { >+ case PAX_ASLR_DISABLED: >+ case PAX_ASLR_ENABLED: >+ case PAX_ASLR_GLOBAL_ENABLED: >+ case PAX_ASLR_FORCE_GLOBAL_ENABLED: >+ pax_aslr_status = val; >+ if (pr) >+ pr->pr_pax_aslr_status = val; >+ break; >+ default: >+ return (EINVAL); >+ } >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_DELTA_MMAP_MIN_LEN >+ || val > PAX_ASLR_DELTA_MMAP_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_mmap_len = val; >+ if (pr) >+ pr->pr_pax_aslr_mmap_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_DELTA_STACK_MIN_LEN >+ || val > PAX_ASLR_DELTA_STACK_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_stack_len = val; >+ if (pr) >+ pr->pr_pax_aslr_stack_len = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = (pr != NULL) ? pr->pr_pax_aslr_exec_len : pax_aslr_exec_len; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_DELTA_EXEC_MIN_LEN >+ || val > PAX_ASLR_DELTA_EXEC_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_exec_len = val; >+ if (pr) >+ pr->pr_pax_aslr_exec_len = val; >+ >+ return (0); >+} >+ >+/* >+ * COMPAT_FREEBSD32 and linuxulator.. >+ */ >+#ifdef COMPAT_FREEBSD32 >+int pax_aslr_compat_status = PAX_ASLR_ENABLED; >+ >+static int sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS); >+static int sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS); >+ >+#ifdef PAX_ASLR_MAX_SEC >+int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN; >+int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN; >+int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN; >+#else >+int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN; >+int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN; >+int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN; >+#endif /* PAX_ASLR_MAX_SEC */ >+ >+SYSCTL_NODE(_security_pax_aslr, OID_AUTO, compat, CTLFLAG_RD, 0, >+ "Setting for COMPAT_FREEBSD32 and linuxulator."); >+ >+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, status, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_compat_status, "I", >+ "Restrictions status. " >+ "0 - disabled, " >+ "1 - enabled, " >+ "2 - global enabled, " >+ "3 - force global enabled"); >+TUNABLE_INT("security.pax.aslr.compat.status", &pax_aslr_compat_status); >+ >+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, mmap_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_compat_mmap, "I", >+ "Number of bits randomized for mmap(2) calls. " >+ "32 bit: [8,16]"); >+TUNABLE_INT("security.pax.aslr.compat.mmap", &pax_aslr_compat_mmap_len); >+ >+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, stack_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_compat_stack, "I", >+ "Number of bits randomized for the stack. " >+ "32 bit: [6,12]"); >+TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_stack_len); >+ >+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, exec_len, >+ CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN|CTLFLAG_PRISON, >+ NULL, 0, sysctl_pax_aslr_compat_exec, "I", >+ "Number of bits randomized for the PIE exec base. " >+ "32 bit: [6,12]"); >+TUNABLE_INT("security.pax.aslr.compat.stack", &pax_aslr_compat_exec_len); >+ >+ >+static int >+sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val, *ptr; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_status) : &pax_aslr_compat_status; >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = *ptr; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ switch (val) { >+ case PAX_ASLR_DISABLED: >+ case PAX_ASLR_ENABLED: >+ case PAX_ASLR_GLOBAL_ENABLED: >+ case PAX_ASLR_FORCE_GLOBAL_ENABLED: >+ pax_aslr_compat_status = val; >+ *ptr = val; >+ break; >+ default: >+ return (EINVAL); >+ } >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val, *ptr; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_mmap_len) : &pax_aslr_compat_mmap_len; >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = *ptr; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN >+ || val > PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_compat_mmap_len = val; >+ *ptr = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val, *ptr; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_stack_len) : &pax_aslr_compat_stack_len; >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN >+ || val > PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_compat_stack_len = val; >+ *ptr = val; >+ >+ return (0); >+} >+ >+static int >+sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS) >+{ >+ int err; >+ int val, *ptr; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(req->td, NULL); >+ ptr = (pr != NULL) ? &(pr->pr_pax_aslr_compat_exec_len) : &pax_aslr_compat_exec_len; >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ val = *ptr; >+ err = sysctl_handle_int(oidp, &val, sizeof(int), req); >+ if (err || !req->newptr) >+ return (err); >+ >+ if (val < PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN >+ || val > PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN) >+ return (EINVAL); >+ >+ pax_aslr_compat_exec_len = val; >+ *ptr = val; >+ >+ return (0); >+} >+#endif /* COMPAT_FREEBSD32 */ >+ >+ >+/* >+ * ASLR functions >+ */ >+bool >+pax_aslr_active(struct thread *td, struct proc *proc) >+{ >+ int status; >+ struct prison *pr=NULL; >+#ifdef notyet >+ uint32_t flags; >+#endif /* notyet */ >+ >+ if (!(td) && !(proc)) >+ return (true); >+ >+#ifdef notyet >+ flags = (td != NULL) ? td->td_proc->p_pax : proc->p_pax; >+#endif /* notyet */ >+ pr = pax_aslr_get_prison(td, proc); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ status = (pr != NULL) ? pr->pr_pax_aslr_status : pax_aslr_status; >+ >+ switch (status) { >+ case PAX_ASLR_DISABLED: >+ return (false); >+ case PAX_ASLR_FORCE_GLOBAL_ENABLED: >+ return (true); >+ case PAX_ASLR_ENABLED: >+#ifdef notyet >+ if ((flags & ELF_NOTE_PAX_ASLR) == 0) >+ return (false); >+#endif /* notyet */ >+ break; >+ case PAX_ASLR_GLOBAL_ENABLED: >+#ifdef notyet >+ if ((flags & ELF_NOTE_PAX_NOASLR) != 0) >+ return (false); >+#endif /* notyet */ >+ break; >+ default: >+ return (true); >+ } >+ >+ return (true); >+} >+ >+struct prison * >+pax_aslr_get_prison(struct thread *td, struct proc *proc) >+{ >+ if ((td)) { >+ if ((td->td_proc) && (td->td_proc->p_ucred)) >+ return td->td_proc->p_ucred->cr_prison; >+ >+ return NULL; >+ } >+ >+ if (!(proc)) >+ return NULL; >+ >+ return proc->p_ucred->cr_prison; >+} >+ >+void >+pax_aslr_init_prison(struct prison *pr) >+{ >+ if (!(pr)) >+ return; >+ >+ if (pr->pr_pax_set) >+ return; >+ >+ if (pax_aslr_debug) >+ uprintf("[PaX ASLR] pax_aslr_init_prison: Setting prison %s ASLR variables\n", pr->pr_name); >+ >+ pr->pr_pax_aslr_status = pax_aslr_status; >+ pr->pr_pax_aslr_debug = pax_aslr_debug; >+ pr->pr_pax_aslr_mmap_len = pax_aslr_mmap_len; >+ pr->pr_pax_aslr_stack_len = pax_aslr_stack_len; >+ pr->pr_pax_aslr_exec_len = pax_aslr_exec_len; >+ >+#ifdef COMPAT_FREEBSD32 >+ pr->pr_pax_aslr_compat_status = pax_aslr_compat_status; >+ pr->pr_pax_aslr_compat_mmap_len = pax_aslr_compat_mmap_len; >+ pr->pr_pax_aslr_compat_stack_len = pax_aslr_compat_stack_len; >+ pr->pr_pax_aslr_compat_exec_len = pax_aslr_compat_exec_len; >+#endif /* COMPAT_FREEBSD32 */ >+ >+ pr->pr_pax_set = 1; >+} >+ >+void >+pax_aslr_init(struct thread *td, struct image_params *imgp) >+{ >+ struct vmspace *vm; >+ u_int sv_flags; >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(td, NULL); >+ >+ if ((pr) && !(pr->pr_pax_set)) >+ pax_aslr_init_prison(pr); >+ >+ if (imgp == NULL) { >+ panic("[PaX ASLR] pax_aslr_init - imgp == NULL"); >+ } >+ >+ if (!pax_aslr_active(td, NULL)) >+ return; >+ >+ vm = imgp->proc->p_vmspace; >+ sv_flags = imgp->proc->p_sysent->sv_flags; >+ >+#ifndef COMPAT_FREEBSD32 >+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); >+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); >+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); >+#else /* COMPAT_FREEBSD32 */ >+ if ((sv_flags & SV_LP64) != 0) { >+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); >+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); >+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); >+ } else { >+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compat_mmap_len); >+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), >+ PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len); >+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); >+ } >+#endif /* !COMPAT_FREEBSD32 */ >+} >+ >+void >+pax_aslr_mmap(struct thread *td, vm_offset_t *addr, vm_offset_t orig_addr, int flags) >+{ >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(td, NULL); >+ >+ if (!pax_aslr_active(td, NULL)) >+ return; >+ >+ if (!(flags & MAP_FIXED) && ((orig_addr == 0) || !(flags & MAP_ANON))) { >+ if (pax_aslr_debug) >+ uprintf("[PaX ASLR] applying to %p orig_addr=%p f=%x\n", >+ (void *)*addr, (void *)orig_addr, flags); >+ if (!(td->td_proc->p_vmspace->vm_map.flags & MAP_ENTRY_GROWS_DOWN)) >+ *addr += td->td_proc->p_vmspace->vm_aslr_delta_mmap; >+ else >+ *addr -= td->td_proc->p_vmspace->vm_aslr_delta_mmap; >+ if (pax_aslr_debug) >+ uprintf("[PaX ASLR] result %p\n", (void *)*addr); >+ } >+ else if (pax_aslr_debug) >+ uprintf("[PaX ASLR] not applying to %p orig_addr=%p f=%x\n", >+ (void *)*addr, (void *)orig_addr, flags); >+} >+ >+void >+pax_aslr_stack(struct thread *td, uintptr_t *addr, uintptr_t orig_addr) >+{ >+ struct prison *pr=NULL; >+ >+ pr = pax_aslr_get_prison(td, NULL); >+ >+ if (!pax_aslr_active(td, NULL)) >+ return; >+ >+ *addr -= td->td_proc->p_vmspace->vm_aslr_delta_stack; >+ if ((pr) && pr->pr_pax_aslr_debug) >+ uprintf("[PaX ASLR] orig_addr=%p, addr=%p\n", >+ (void *)orig_addr, (void *)*addr); >+} >diff --git a/sys/sys/jail.h b/sys/sys/jail.h >index 59d791c..f2bb97c 100644 >--- a/sys/sys/jail.h >+++ b/sys/sys/jail.h >@@ -184,6 +184,20 @@ struct prison { > char pr_hostname[MAXHOSTNAMELEN]; /* (p) jail hostname */ > char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */ > char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */ >+#ifdef PAX_ASLR >+ int pr_pax_set; >+ int pr_pax_aslr_status; >+ int pr_pax_aslr_debug; >+ int pr_pax_aslr_mmap_len; >+ int pr_pax_aslr_stack_len; >+ int pr_pax_aslr_exec_len; >+#endif /* PAX_ASLR */ >+#if defined(PAX_ASLR) && defined(COMPAT_FREEBSD32) >+ int pr_pax_aslr_compat_status; >+ int pr_pax_aslr_compat_mmap_len; >+ int pr_pax_aslr_compat_stack_len; >+ int pr_pax_aslr_compat_exec_len; >+#endif /* COMPAT_FREEBSD32 */ > }; > > struct prison_racct { >diff --git a/sys/sys/pax.h b/sys/sys/pax.h >new file mode 100644 >index 0000000..b66e68b >--- /dev/null >+++ b/sys/sys/pax.h >@@ -0,0 +1,166 @@ >+/*- >+ * Copyright (c) 2013, by Oliver Pinter <oliver.pntr at gmail.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. The name of the developer may NOT be used to endorse or promote products >+ * derived from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ * >+ * $FreeBSD$ >+ * >+ * Enhancements made by Shawn "lattera" Webb under the direction of SoldierX. >+ */ >+ >+#ifndef __SYS_PAX_H >+#define __SYS_PAX_H >+ >+struct image_params; >+struct thread; >+struct vmspace; >+struct vm_offset_t; >+ >+/* >+ * used in sysctl handler >+ */ >+#define PAX_ASLR_DISABLED 0 >+#define PAX_ASLR_ENABLED 1 >+#define PAX_ASLR_GLOBAL_ENABLED 2 >+#define PAX_ASLR_FORCE_GLOBAL_ENABLED 3 >+ >+#ifndef PAX_ASLR_DELTA >+#define PAX_ASLR_DELTA(delta, lsb, len) \ >+ (((delta) & ((1UL << (len)) - 1)) << (lsb)) >+#endif /* PAX_ASLR_DELTA */ >+ >+#ifdef PAX_ASLR >+/* >+ * generic ASLR values >+ * >+ * MMAP | 32 bit | 64 bit | >+ * +-------+--------+--------+ >+ * | MIN | 8 bit | 16 bit | >+ * +-------+--------+--------+ >+ * | MAX | 16 bit | 32 bit | >+ * +-------+--------+--------+ >+ * >+ * STACK | 32 bit | 64 bit | >+ * +-------+--------+--------+ >+ * | MIN | 6 bit | 12 bit | >+ * +-------+--------+--------+ >+ * | MAX | 10 bit | 21 bit | >+ * +-------+--------+--------+ >+ * >+ * EXEC | 32 bit | 64 bit | >+ * +-------+--------+--------+ >+ * | MIN | 6 bit | 12 bit | >+ * +-------+--------+--------+ >+ * | MAX | 10 bit | 21 bit | >+ * +-------+--------+--------+ >+ * >+ */ >+#ifndef PAX_ASLR_DELTA_MMAP_LSB >+#define PAX_ASLR_DELTA_MMAP_LSB PAGE_SHIFT >+#endif /* PAX_ASLR_DELTA_MMAP_LSB */ >+ >+#ifndef PAX_ASLR_DELTA_MMAP_MIN_LEN >+#define PAX_ASLR_DELTA_MMAP_MIN_LEN ((sizeof(void *) * NBBY) / 4) >+#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_MMAP_MAX_LEN >+#define PAX_ASLR_DELTA_MMAP_MAX_LEN ((sizeof(void *) * NBBY) / 2) >+#endif /* PAX_ASLR_DELTA_MMAP_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_STACK_LSB >+#define PAX_ASLR_DELTA_STACK_LSB 3 >+#endif /* PAX_ASLR_DELTA_STACK_LSB */ >+ >+#ifndef PAX_ASLR_DELTA_STACK_MIN_LEN >+#define PAX_ASLR_DELTA_STACK_MIN_LEN ((sizeof(void *) * NBBY) / 5) >+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_STACK_MAX_LEN >+#define PAX_ASLR_DELTA_STACK_MAX_LEN ((sizeof(void *) * NBBY) / 3) >+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_EXEC_LSB >+#define PAX_ASLR_DELTA_EXEC_LSB PAGE_SHIFT >+#endif /* PAX_ASLR_DELTA_EXEC_LSB */ >+ >+#ifndef PAX_ASLR_DELTA_EXEC_MIN_LEN >+#define PAX_ASLR_DELTA_EXEC_MIN_LEN ((sizeof(void *) * NBBY) / 5) >+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */ >+ >+#ifndef PAX_ASLR_DELTA_EXEC_MAX_LEN >+#define PAX_ASLR_DELTA_EXEC_MAX_LEN ((sizeof(void *) * NBBY) / 3) >+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */ >+ >+/* >+ * ASLR values for COMPAT_FREEBSD32 and COMPAT_LINUX >+ */ >+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_LSB >+#define PAX_ASLR_COMPAT_DELTA_MMAP_LSB PAGE_SHIFT >+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_LSB */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN >+#define PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN ((sizeof(int) * NBBY) / 4) >+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN >+#define PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN ((sizeof(int) * NBBY) / 2) >+#endif /* PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_LSB >+#define PAX_ASLR_COMPAT_DELTA_STACK_LSB 3 >+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_LSB */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN >+#define PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN ((sizeof(int) * NBBY) / 5) >+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN >+#define PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN ((sizeof(int) * NBBY) / 3) >+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN >+#define PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN ((sizeof(int) * NBBY) / 5) >+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */ >+ >+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN >+#define PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN ((sizeof(int) * NBBY) / 3) >+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */ >+ >+extern int pax_aslr_status; >+extern int pax_aslr_debug; >+extern int pax_aslr_compat_status; >+ >+extern int pax_aslr_mmap_len; >+extern int pax_aslr_stack_len; >+extern int pax_aslr_exec_len; >+#endif /* PAX_ASLR */ >+ >+void pax_init(void); >+void pax_aslr_init_prison(struct prison *pr); >+bool pax_aslr_active(struct thread *td, struct proc *proc); >+void pax_aslr_init(struct thread *td, struct image_params *imgp); >+void pax_aslr_mmap(struct thread *td, vm_offset_t *addr, >+ vm_offset_t orig_addr, int flags); >+void pax_aslr_stack(struct thread *td, uintptr_t *addr, uintptr_t orig_addr); >+struct prison *pax_aslr_get_prison(struct thread *td, struct proc *proc); >+ >+#endif /* __SYS_PAX_H */ >diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c >index e15e0ca..3c066ef 100644 >--- a/sys/vm/vm_map.c >+++ b/sys/vm/vm_map.c >@@ -65,6 +65,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > >+#include "opt_pax.h" >+ > #include <sys/param.h> > #include <sys/systm.h> > #include <sys/kernel.h> >@@ -289,6 +291,10 @@ vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit) > vm->vm_taddr = 0; > vm->vm_daddr = 0; > vm->vm_maxsaddr = 0; >+#ifdef PAX_ASLR >+ vm->vm_aslr_delta_mmap = 0; >+ vm->vm_aslr_delta_stack = 0; >+#endif /* PAX_ASLR */ > return (vm); > } > >diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h >index 850bf25..e4fbebd 100644 >--- a/sys/vm/vm_map.h >+++ b/sys/vm/vm_map.h >@@ -241,6 +241,8 @@ struct vmspace { > 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_aslr_delta_mmap; /* mmap() random delta for ASLR */ >+ vm_size_t vm_aslr_delta_stack; /* stack random delta for ASLR */ > volatile int vm_refcnt; /* number of references */ > /* > * Keep the PMAP last, so that CPU-specific variations of that >diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c >index 272491e..3707c5a 100644 >--- a/sys/vm/vm_mmap.c >+++ b/sys/vm/vm_mmap.c >@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); > > #include "opt_compat.h" > #include "opt_hwpmc_hooks.h" >+#include "opt_pax.h" > > #include <sys/param.h> > #include <sys/systm.h> >@@ -91,6 +92,10 @@ __FBSDID("$FreeBSD$"); > #include <sys/pmckern.h> > #endif > >+#ifdef PAX_ASLR >+#include <sys/pax.h> >+#endif /* PAX_ASLR */ >+ > int old_mlock = 0; > SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW | CTLFLAG_TUN, &old_mlock, 0, > "Do not apply RLIMIT_MEMLOCK on mlockall"); >@@ -203,6 +208,9 @@ sys_mmap(td, uap) > struct file *fp; > struct vnode *vp; > vm_offset_t addr; >+#ifdef PAX_ASLR >+ vm_offset_t orig_addr; >+#endif /* PAX_ASLR */ > vm_size_t size, pageoff; > vm_prot_t cap_maxprot, prot, maxprot; > void *handle; >@@ -213,6 +221,9 @@ sys_mmap(td, uap) > cap_rights_t rights; > > addr = (vm_offset_t) uap->addr; >+#ifdef PAX_ASLR >+ orig_addr = addr; >+#endif /* PAX_ASLR */ > size = uap->len; > prot = uap->prot & VM_PROT_ALL; > flags = uap->flags; >@@ -309,9 +320,11 @@ sys_mmap(td, uap) > if (addr == 0 || > (addr >= round_page((vm_offset_t)vms->vm_taddr) && > addr < round_page((vm_offset_t)vms->vm_daddr + >- lim_max(td->td_proc, RLIMIT_DATA)))) >- addr = round_page((vm_offset_t)vms->vm_daddr + >- lim_max(td->td_proc, RLIMIT_DATA)); >+ lim_max(td->td_proc, RLIMIT_DATA)))) { >+ addr = round_page((vm_offset_t)vms->vm_daddr + >+ lim_max(td->td_proc, RLIMIT_DATA)); >+ addr = round_page(addr + (arc4random()&(256*1024*1024-1))); >+ } > PROC_UNLOCK(td->td_proc); > } > if (flags & MAP_ANON) { >@@ -414,6 +427,9 @@ sys_mmap(td, uap) > map: > td->td_fpop = fp; > maxprot &= cap_maxprot; >+#ifdef PAX_ASLR >+ pax_aslr_mmap(td, &addr, orig_addr, flags); >+#endif /* PAX_ASLR */ > error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, > flags, handle_type, handle, pos); > td->td_fpop = NULL;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 181497
:
136322
|
136323
|
136324
|
136325
|
136326
| 136327 |
136328
|
153731