Date: Wed, 9 Apr 2014 02:18:55 +0200 From: Oliver Pinter <oliver.pntr@gmail.com> Cc: freebsd-bugs@freebsd.org Subject: Re: kern/181497: [kernel] [patch] Add ASLR feature to kernel Message-ID: <CAPjTQNE2gns9mAaAh%2BAU3f_tvc6ty9b0=brOQrtV1yj7PJLYNw@mail.gmail.com> In-Reply-To: <201403220050.s2M0o0cf060347@freefall.freebsd.org> References: <201403220050.s2M0o0cf060347@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 3/22/14, Shawn Webb <lattera@gmail.com> wrote: > The following reply was made to PR kern/181497; it has been noted by GNATS. > > From: Shawn Webb <lattera@gmail.com> > To: bug-followup@FreeBSD.org > Cc: > Subject: Re: kern/181497: [kernel] [patch] Add ASLR feature to kernel > Date: Fri, 21 Mar 2014 20:49:01 -0400 > > --Apple-Mail=_3B294110-F7A1-429D-BF98-4300F2774717 > Content-Transfer-Encoding: 7bit > Content-Type: text/plain; > charset=us-ascii > > The attached patch provides better stability to the new PIE feature. > > > --Apple-Mail=_3B294110-F7A1-429D-BF98-4300F2774717 > Content-Disposition: attachment; > filename=aslr-2014-03-21_02.patch.txt > Content-Type: text/plain; > name="aslr-2014-03-21_02.patch.txt" > Content-Transfer-Encoding: quoted-printable > > 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" > =20 > #define __ELF_WORD_SIZE 32 > =20 > @@ -113,6 +114,10 @@ __FBSDID("$FreeBSD$"); > =20 > FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD"); > =20 > +#ifdef PAX_ASLR > +#include <sys/pax.h> > +#endif /* PAX_ASLR */ > + > #ifndef __mips__ > CTASSERT(sizeof(struct timeval32) =3D=3D 8); > CTASSERT(sizeof(struct timespec32) =3D=3D 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 =3D 0; > destp =3D (uintptr_t)arginfo; > =20 > +#ifdef PAX_ASLR > + orig_destp =3D 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 > =20 > +# 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..68852bb 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" > =20 > #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 =3D 0; > int error, i, numsegs; > +#ifdef PAX_ASLR > + struct prison *pr; > +#endif > =20 > #ifdef CAPABILITY_MODE > /* > @@ -655,11 +661,17 @@ __elfN(load_file)(struct proc *p, const char = > *file, u_long *addr, > hdr =3D (const Elf_Ehdr *)imgp->image_header; > if ((error =3D __elfN(check_header)(hdr)) !=3D 0) > goto fail; > - if (hdr->e_type =3D=3D ET_DYN) > + if (hdr->e_type =3D=3D ET_DYN) { > rbase =3D *addr; > - else if (hdr->e_type =3D=3D ET_EXEC) > +#ifdef PAX_ASLR > + if (pax_aslr_active(NULL, imgp->proc)) { > + pr =3D pax_aslr_get_prison(NULL, imgp->proc); > + rbase +=3D round_page(PAX_ASLR_DELTA(arc4random(), = > PAX_ASLR_DELTA_EXEC_LSB, pr->pr_pax_aslr_exec_len)); > + } > +#endif > + } else if (hdr->e_type =3D=3D ET_EXEC) { > rbase =3D 0; > - else { > + } else { > error =3D 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 > =20 > /* > * Do we have a valid ELF header ? > @@ -793,10 +808,23 @@ __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 =3D=3D 0) > + if (baddr =3D=3D 0) { > +#ifdef PAX_ASLR > + if (pax_aslr_active(NULL, imgp->proc)) { > + pr =3D pax_aslr_get_prison(NULL, imgp->proc); > + do { > + /* Do this in a loop to make sure we don't attempt = > a NULL page mapping */ > + et_dyn_addr =3D = > trunc_page(PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_EXEC_LSB, = > pr->pr_pax_aslr_exec_len)); > + } while (et_dyn_addr =3D=3D 0); > + } else { > + et_dyn_addr =3D ET_DYN_LOAD_ADDR; > + } > +#else > et_dyn_addr =3D ET_DYN_LOAD_ADDR; > - else > +#endif > + } else { > et_dyn_addr =3D 0; > + } > } else > et_dyn_addr =3D 0; > sv =3D brand_info->sysvec; > diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c > index 9f223ca..7f54f33 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" > =20 > #include <sys/param.h> > @@ -94,6 +95,10 @@ __FBSDID("$FreeBSD$"); > dtrace_execexit_func_t dtrace_fasttrap_exec; > #endif > =20 > +#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 =3D &vmspace->vm_map; > } > =20 > +#ifdef PAX_ASLR > + pax_aslr_init(curthread, imgp); > +#endif /* PAX_ASLR */ > + > /* Map a shared page */ > obj =3D sv->sv_shared_page_obj; > if (obj !=3D 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; > @@ -1257,6 +1269,10 @@ exec_copyout_strings(imgp) > szsigcode =3D *(p->p_sysent->sv_szsigcode); > } > destp =3D (uintptr_t)arginfo; > +#ifdef PAX_ASLR > + orig_destp =3D destp; > + pax_aslr_stack(curthread, &destp, orig_destp); > +#endif /* PAX_ASLR */ > =20 > /* > * 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" > =20 > #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> > =20 > #include <net/if.h> > #include <net/if_var.h> > @@ -114,6 +116,20 @@ struct prison prison0 =3D { > .pr_flags =3D PR_HOST|_PR_IP_SADDRSEL, > #endif > .pr_allow =3D PR_ALLOW_ALL, > +#ifdef PAX_ASLR > + .pr_pax_set =3D 0, > + .pr_pax_aslr_status =3D 0, > + .pr_pax_aslr_debug =3D 0, > + .pr_pax_aslr_mmap_len =3D PAX_ASLR_DELTA_MMAP_MIN_LEN, > + .pr_pax_aslr_stack_len =3D PAX_ASLR_DELTA_STACK_MIN_LEN, > + .pr_pax_aslr_exec_len =3D PAX_ASLR_DELTA_EXEC_MIN_LEN, > +#ifdef COMPAT_FREEBSD32 > + .pr_pax_aslr_compat_status =3D 0, > + .pr_pax_aslr_compat_mmap_len =3D = > PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN, > + .pr_pax_aslr_compat_stack_len =3D = > PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN, > + .pr_pax_aslr_compat_exec_len =3D = > PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN, > +#endif /* COMPAT_FREEBSD32 */ > +#endif /* PAX_ASLR */ > }; > MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF); > =20 > 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 =3D PAX_ASLR_ENABLED; > +int pax_aslr_debug =3D 0; > + > +#ifdef PAX_ASLR_MAX_SEC > +int pax_aslr_mmap_len =3D PAX_ASLR_DELTA_MMAP_MAX_LEN; > +int pax_aslr_stack_len =3D PAX_ASLR_DELTA_STACK_MAX_LEN; > +int pax_aslr_exec_len =3D PAX_ASLR_DELTA_EXEC_MAX_LEN; > +#else > +int pax_aslr_mmap_len =3D PAX_ASLR_DELTA_MMAP_MIN_LEN; > +int pax_aslr_stack_len =3D PAX_ASLR_DELTA_STACK_MIN_LEN; > +int pax_aslr_exec_len =3D 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=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_status : pax_aslr_status; > + err =3D 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 =3D val; > + if (pr) > + pr->pr_pax_aslr_status =3D val; > + break; > + default: > + return (EINVAL); > + } > + > + return (0); > +} > + > +static int > +sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS) > +{ > + int err; > + int val; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_mmap_len : = > pax_aslr_mmap_len; > + err =3D 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 =3D val; > + if (pr) > + pr->pr_pax_aslr_mmap_len =3D val; > + > + return (0); > +} > + > +static int > +sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS) > +{ > + int err; > + int val; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_stack_len : = > pax_aslr_stack_len; > + err =3D 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 =3D val; > + if (pr) > + pr->pr_pax_aslr_stack_len =3D val; > + > + return (0); > +} > + > +static int > +sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS) > +{ > + int err; > + int val; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + val =3D (pr !=3D NULL) ? pr->pr_pax_aslr_exec_len : = > pax_aslr_exec_len; > + err =3D 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 =3D val; > + if (pr) > + pr->pr_pax_aslr_exec_len =3D val; > + > + return (0); > +} > + > +/* > + * COMPAT_FREEBSD32 and linuxulator.. > + */ > +#ifdef COMPAT_FREEBSD32 > +int pax_aslr_compat_status =3D 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 =3D PAX_ASLR_COMPAT_DELTA_MMAP_MAX_LEN; > +int pax_aslr_compat_stack_len =3D PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN; > +int pax_aslr_compat_exec_len =3D PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN; > +#else > +int pax_aslr_compat_mmap_len =3D PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN; > +int pax_aslr_compat_stack_len =3D PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN; > +int pax_aslr_compat_exec_len =3D 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=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + ptr =3D (pr !=3D NULL) ? &(pr->pr_pax_aslr_compat_status) : = > &pax_aslr_compat_status; > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + val =3D *ptr; > + err =3D 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 =3D val; > + *ptr =3D 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=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + ptr =3D (pr !=3D 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 =3D *ptr; > + err =3D 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 =3D val; > + *ptr =3D val; > + > + return (0); > +} > + > +static int > +sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS) > +{ > + int err; > + int val, *ptr; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + ptr =3D (pr !=3D 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 =3D (pr !=3D NULL) ? pr->pr_pax_aslr_compat_stack_len : = > pax_aslr_compat_stack_len; > + err =3D 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 =3D val; > + *ptr =3D val; > + > + return (0); > +} > + > +static int > +sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS) > +{ > + int err; > + int val, *ptr; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(req->td, NULL); > + ptr =3D (pr !=3D 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 =3D *ptr; > + err =3D 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 =3D val; > + *ptr =3D val; > + > + return (0); > +} > +#endif /* COMPAT_FREEBSD32 */ > + > + > +/* > + * ASLR functions > + */ > +bool > +pax_aslr_active(struct thread *td, struct proc *proc) > +{ > + int status; > + struct prison *pr=3DNULL; > +#ifdef notyet > + uint32_t flags; > +#endif /* notyet */ > + > + if (!(td) && !(proc)) > + return (true); > + > +#ifdef notyet > + flags =3D (td !=3D NULL) ? td->td_proc->p_pax : proc->p_pax; > +#endif /* notyet */ > + pr =3D pax_aslr_get_prison(td, proc); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + status =3D (pr !=3D 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) =3D=3D 0) > + return (false); > +#endif /* notyet */ > + break; > + case PAX_ASLR_GLOBAL_ENABLED: > +#ifdef notyet > + if ((flags & ELF_NOTE_PAX_NOASLR) !=3D 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 =3D pax_aslr_status; > + pr->pr_pax_aslr_debug =3D pax_aslr_debug; > + pr->pr_pax_aslr_mmap_len =3D pax_aslr_mmap_len; > + pr->pr_pax_aslr_stack_len =3D pax_aslr_stack_len; > + pr->pr_pax_aslr_exec_len =3D pax_aslr_exec_len; > + > +#ifdef COMPAT_FREEBSD32 > + pr->pr_pax_aslr_compat_status =3D pax_aslr_compat_status; > + pr->pr_pax_aslr_compat_mmap_len =3D pax_aslr_compat_mmap_len; > + pr->pr_pax_aslr_compat_stack_len =3D pax_aslr_compat_stack_len; > + pr->pr_pax_aslr_compat_exec_len =3D pax_aslr_compat_exec_len; > +#endif /* COMPAT_FREEBSD32 */ > + > + pr->pr_pax_set =3D 1; > +} > + > +void > +pax_aslr_init(struct thread *td, struct image_params *imgp) > +{ > + struct vmspace *vm; > + u_int sv_flags; > + struct prison *pr=3DNULL; > + > + pr =3D pax_aslr_get_prison(td, NULL); > + > + if ((pr) && !(pr->pr_pax_set)) > + pax_aslr_init_prison(pr); > + > + if (imgp =3D=3D NULL) { > + panic("[PaX ASLR] pax_aslr_init - imgp =3D=3D NULL"); > + } > + > + if (!pax_aslr_active(td, NULL)) > + return; > + > + vm =3D imgp->proc->p_vmspace; > + sv_flags =3D imgp->proc->p_sysent->sv_flags; > + > +#ifndef COMPAT_FREEBSD32 > + vm->vm_aslr_delta_mmap =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_DELTA_MMAP_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); > + vm->vm_aslr_delta_stack =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_DELTA_STACK_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); > + vm->vm_aslr_delta_stack =3D ALIGN(vm->vm_aslr_delta_stack); > +#else /* COMPAT_FREEBSD32 */ > + if ((sv_flags & SV_LP64) !=3D 0) { > + vm->vm_aslr_delta_mmap =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_DELTA_MMAP_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); > + vm->vm_aslr_delta_stack =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_DELTA_STACK_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); > + vm->vm_aslr_delta_stack =3D ALIGN(vm->vm_aslr_delta_stack); > + } else { > + vm->vm_aslr_delta_mmap =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compat_mmap_len); > + vm->vm_aslr_delta_stack =3D PAX_ASLR_DELTA(arc4random(), > + PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr !=3D NULL) ? = > pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len); > + vm->vm_aslr_delta_stack =3D 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=3DNULL; > + > + pr =3D pax_aslr_get_prison(td, NULL); > + > + if (!pax_aslr_active(td, NULL)) > + return; > + > + if (!(flags & MAP_FIXED) && ((orig_addr =3D=3D 0) || !(flags & = > MAP_ANON))) { > + if (pax_aslr_debug) > + uprintf("[PaX ASLR] applying to %p orig_addr=3D%p f=3D%x\n", > + (void *)*addr, (void *)orig_addr, flags); > + if (!(td->td_proc->p_vmspace->vm_map.flags & = > MAP_ENTRY_GROWS_DOWN)) > + *addr +=3D td->td_proc->p_vmspace->vm_aslr_delta_mmap; > + else > + *addr -=3D 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=3D%p f=3D%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=3DNULL; > + > + pr =3D pax_aslr_get_prison(td, NULL); > + > + if (!pax_aslr_active(td, NULL)) > + return; > + > + *addr -=3D td->td_proc->p_vmspace->vm_aslr_delta_stack; > + if ((pr) && pr->pr_pax_aslr_debug) > + uprintf("[PaX ASLR] orig_addr=3D%p, addr=3D%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 */ > }; > =20 > 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 34807ab..bbacdd7 100644 > --- a/sys/vm/vm_map.c > +++ b/sys/vm/vm_map.c > @@ -65,6 +65,8 @@ > #include <sys/cdefs.h> > __FBSDID("$FreeBSD$"); > =20 > +#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 =3D 0; > vm->vm_daddr =3D 0; > vm->vm_maxsaddr =3D 0; > +#ifdef PAX_ASLR > + vm->vm_aslr_delta_mmap =3D 0; > + vm->vm_aslr_delta_stack =3D 0; > +#endif /* PAX_ASLR */ > return (vm); > } > =20 > 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$"); > =20 > #include "opt_compat.h" > #include "opt_hwpmc_hooks.h" > +#include "opt_pax.h" > =20 > #include <sys/param.h> > #include <sys/systm.h> > @@ -91,6 +92,10 @@ __FBSDID("$FreeBSD$"); > #include <sys/pmckern.h> > #endif > =20 > +#ifdef PAX_ASLR > +#include <sys/pax.h> > +#endif /* PAX_ASLR */ > + > int old_mlock =3D 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; > =20 > addr =3D (vm_offset_t) uap->addr; > +#ifdef PAX_ASLR > + orig_addr =3D addr; > +#endif /* PAX_ASLR */ > size =3D uap->len; > prot =3D uap->prot & VM_PROT_ALL; > flags =3D uap->flags; > @@ -309,9 +320,11 @@ sys_mmap(td, uap) > if (addr =3D=3D 0 || > (addr >=3D 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 =3D round_page((vm_offset_t)vms->vm_daddr + > - lim_max(td->td_proc, RLIMIT_DATA)); > + lim_max(td->td_proc, RLIMIT_DATA)))) { > + addr =3D round_page((vm_offset_t)vms->vm_daddr + > + lim_max(td->td_proc, RLIMIT_DATA)); > + addr =3D 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 =3D fp; > maxprot &=3D cap_maxprot; > +#ifdef PAX_ASLR > + pax_aslr_mmap(td, &addr, orig_addr, flags); > +#endif /* PAX_ASLR */ > error =3D vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, > flags, handle_type, handle, pos); > td->td_fpop =3D NULL; > > --Apple-Mail=_3B294110-F7A1-429D-BF98-4300F2774717-- > _______________________________________________ > freebsd-bugs@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-bugs > To unsubscribe, send any mail to "freebsd-bugs-unsubscribe@freebsd.org" > updated tree are there: https://github.com/HardenedBSD/hardenedBSD/commits/hardened/10/aslr
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAPjTQNE2gns9mAaAh%2BAU3f_tvc6ty9b0=brOQrtV1yj7PJLYNw>