Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109293068
D473.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
70 KB
Referenced Files
None
Subscribers
None
D473.diff
View Options
Index: share/man/man4/Makefile
===================================================================
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -51,6 +51,7 @@
${_aout.4} \
${_apic.4} \
arcmsr.4 \
+ aslr.4 \
${_asmc.4} \
ata.4 \
ath.4 \
Index: share/man/man4/aslr.4
===================================================================
--- /dev/null
+++ share/man/man4/aslr.4
@@ -0,0 +1,257 @@
+.\"-
+.\" Copyright (c) 2014-2015 Shawn Webb <shawn.webb@hardenedbsd.org>
+.\" 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. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" 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$
+.\"
+.Dd February 21, 2015
+.Dt ASLR 4
+.Os
+.Sh NAME
+.Nm aslr
+.Nd Address Space Layout Randomization
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/pax.h
+.Pp
+In the kernel configuration file:
+.Cd "options PAX_ASLR"
+.Sh DESCRIPTION
+ASLR randomizes the address space layout of an application, making
+exploitation difficult for an attacker.
+By randomizing the address space, an attacker won't know where in
+memory a vulnerability or a piece of interesting information lies.
+.Ss General Overview
+When compiled with the PAX_ASLR option, systems will have ASLR
+enabled.
+For systems with that kernel option enabled, if a user wants
+to disable ASLR for a given application, the user must configure that
+application to opt-out.
+.Pp
+Another kernel option,
+.Cd PAX_SYSCTLS ,
+exposes additional
+.Xr sysctl 8
+tunables, allowing ASLR behavior control without requiring a reboot.
+By default, the
+.Xr sysctl 8
+.Va security.pax.aslr.status
+can only be changed
+at boot time via
+.Xr loader.conf 5 .
+Enabling the
+.Cd PAX_SYSCTLS
+kernel option allows a root user to modify
+.Va security.pax.aslr.status .
+See Appendix A for a list of all the tunables.
+.Pp
+ASLR tunables are per-jail and each
+.Xr jail 8
+inherits its parent jail's settings.
+Having per-jail tunables allows more flexibility in shared-hosting
+environments.
+.Ss Implementation Details
+A new
+.Xr SYSINIT 9
+ subroutine ID,
+.Dv SI_SUB_PAX ,
+initializes ASLR system
+variables.
+Upon system boot, tunables from
+.Xr loader.conf 5
+are checked for validity.
+Any invalid values generate a warning message to the console and the
+tunable is set to a sensible default.
+.Pp
+For the sake of performance, the ASLR system relies on per-process
+deltas rather than calling
+.Xr arc4random 3
+for each mapping.
+When a process calls
+.Xr execve 2
+.Ns ,
+the ASLR deltas are initialized.
+Deltas are randomly generated for the execution base,
+.Xr mmap 2
+.Ns ,
+and stack addresses.
+Only the execution base of applications compiled as Position
+Independent Executables (PIEs) is randomized.
+The execution base of non-PIE applications is not modified.
+The mappings of shared objects are randomized for both PIE and non-PIE
+applications.
+.Pp
+The deltas are used as a hint to the Virtual Memory (VM) system.
+The VM system may modify the hint to make a better fit for superpages
+and other alignment constraints.
+.Pp
+The delta applied to the PIE execbase is different than the delta
+applied to the base address of shared objects.
+In the Executable and Linkable File (ELF) image handler, the
+execution base of PIE applications is randomized by adding the delta
+controlled by the
+.Va security.pax.aslr.exec_len
+tunable to
+.Va et_dyn_addr ,
+which is initialized to be
+.Dv ET_DYN_LOAD_ADDR
+(an architecture- dependent macro).
+The base address of shared objects loaded by the dynamic linker are
+randomized by applying the delta controlled by the
+.Va security.pax.aslr.mmap_len
+tunable in
+.Fn sys_mmap
+.Ns .
+Stack randomization is implemented using a stack gap.
+On executable image activation, the stack delta is computed and
+subtracted from the top of the stack.
+.Ss APPENDIX A
+NOTE: All tunables can only be changed during boot-time via
+.Fa /boot/loader.conf
+unless the kernel has been compiled with
+.Cd PAX_SYSCTLS
+.Ns .
+.Bl -bullet
+.It
+.Va security.pax.aslr.status
+.Bl -dash -compact
+.It
+Type: integer
+.It
+Description: Toggle system-wide ASLR protection.
+.It
+Values:
+.br
+0 - ASLR disabled system-wide.
+Individual applications may
+.Em NOT
+opt in.
+.br
+1 - ASLR disabled but applications may opt in.
+.br
+2 - ASLR enabled and applications may opt out.
+.br
+3 - ASLR enabled for all applications.
+Applications may not opt out.
+.It
+Default: 2
+.El
+.It
+.Va security.pax.aslr.exec_len
+.Bl -dash -compact
+.It
+Type: integer
+.It
+Description: Set the number of bits to be randomized for the PIE
+execbase.
+.It
+Values:
+.br
+For 32-bit systems, minimum of 8, maximum of 21.
+For 64-bit systems, minimum of 16, maximum of 42.
+.It
+Default: For 32-bit systems: 14.
+For 64-bit systems: 16.
+.El
+.It
+.Va security.pax.aslr.mmap_len
+.Bl -dash -compact
+.It
+Type: integer
+.It
+Description: Set the number of bits to be randomized for
+.Xr mmap 2
+calls.
+.It
+Values:
+.br
+For 32-bit systems, minimum of 8, maximum of 21.
+For 64-bit systems, minimum of 16, maximum of 42.
+.It
+Default: For 32-bit systems: 14.
+For 64-bit systems: 21.
+.El
+.It
+.Va security.pax.aslr.stack_len
+.Bl -dash -compact
+.It
+Type: integer
+.It
+Description: Set the number of bits to be randomized for the stack.
+.It
+Values:
+.br
+For 32-bit systems, minimum of 8, maximum of 21.
+For 64-bit systems, minimum of 16, maximum of 42.
+.It
+Default: For 32-bit systems: 8.
+For 64-bit systems: 16.
+.El
+.El
+.Sh SEE ALSO
+.Xr mmap 2 ,
+.Xr elf 3 ,
+.Xr mac 4
+.Rs
+.%T "PaX ASLR"
+.%U http://pax.grsecurity.net/docs/aslr.txt
+.Re
+.Rs
+.%T "HardenedBSD"
+.%U http://hardenedbsd.org/
+.Re
+.Rs
+.%T "secadm"
+.%U https://github.com/HardenedBSD/secadm
+.Re
+.Sh AUTHORS
+This manual page was written by
+.An -nosplit
+.An Shawn Webb .
+The ASLR implementation was written by
+.An Oliver Pinter
+and
+.An Shawn Webb .
+.Sh BUGS
+The existing gap-based stack randomization is not optimal.
+Mapping-base stack randomization is more robust, but hard-coded kernel
+structures and addresses, especially
+.Va PS_STRINGS ,
+will need to be modified.
+The required changes to
+.Va PS_STRINGS
+are major and will likely touch
+userland along with the kernel.
+The original PaX implementation, from which the
+.Fx
+implementation is inspired, uses a special ELF process header which
+requires modification of executable files.
+The authors of the
+.Fx
+implementation have deliberately chosen to go a different route based
+on the
+.Xr mac 4
+framework.
+Support for filesystem extended attributes will be added at a later
+time.
Index: sys/amd64/amd64/elf_machdep.c
===================================================================
--- sys/amd64/amd64/elf_machdep.c
+++ sys/amd64/amd64/elf_machdep.c
@@ -26,12 +26,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/linker.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
@@ -82,6 +85,7 @@
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
Index: sys/amd64/conf/GENERIC
===================================================================
--- sys/amd64/conf/GENERIC
+++ sys/amd64/conf/GENERIC
@@ -69,6 +69,8 @@
options CAPABILITY_MODE # Capsicum capability mode
options CAPABILITIES # Capsicum capabilities
options MAC # TrustedBSD MAC Framework
+#options PAX_ASLR # Address Space Layout Randomization
+#options PAX_SYSCTLS # Run-time settings for PAX and Hardening
options KDTRACE_FRAME # Ensure frames are compiled in
options KDTRACE_HOOKS # Kernel DTrace hooks
options DDB_CTF # Kernel ELF linker loads CTF data
Index: sys/amd64/include/vmparam.h
===================================================================
--- sys/amd64/include/vmparam.h
+++ sys/amd64/include/vmparam.h
@@ -178,7 +178,8 @@
#define VM_MAXUSER_ADDRESS UVADDR(NUPML4E, 0, 0, 0)
#define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE)
-#define USRSTACK SHAREDPAGE
+#define SHAREDPAGE_GUARD (4 * PAGE_SIZE)
+#define USRSTACK (SHAREDPAGE - SHAREDPAGE_GUARD)
#define VM_MAX_ADDRESS UPT_MAX_ADDRESS
#define VM_MIN_ADDRESS (0)
Index: sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -33,6 +33,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_pax.h"
#ifndef COMPAT_FREEBSD32
#error "Unable to compile Linux-emulator due to missing COMPAT_FREEBSD32 option!"
@@ -51,6 +52,7 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
@@ -1037,6 +1039,7 @@
.sv_shared_page_base = LINUX32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
Index: sys/arm/arm/elf_machdep.c
===================================================================
--- sys/arm/arm/elf_machdep.c
+++ sys/arm/arm/elf_machdep.c
@@ -26,6 +26,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -34,6 +36,7 @@
#include <sys/linker.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/syscall.h>
#include <sys/signalvar.h>
@@ -81,6 +84,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
static Elf32_Brandinfo freebsd_brand_info = {
Index: sys/arm/arm/machdep.c
===================================================================
--- sys/arm/arm/machdep.c
+++ sys/arm/arm/machdep.c
@@ -47,6 +47,7 @@
#include "opt_platform.h"
#include "opt_sched.h"
#include "opt_timer.h"
+#include "opt_pax.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -116,6 +117,10 @@
#include <ddb/ddb.h>
#endif
+#ifdef PAX_ASLR
+#include <sys/pax.h>
+#endif
+
#ifdef DEBUG
#define debugf(fmt, args...) printf(fmt, ##args)
#else
@@ -287,6 +292,9 @@
tf->tf_pc = (register_t)catcher;
tf->tf_usr_sp = (register_t)fp;
tf->tf_usr_lr = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
+#ifdef PAX_ASLR
+ pax_aslr_stack(p, &tf->tf_usr_lr);
+#endif
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr,
tf->tf_usr_sp);
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -30,6 +30,7 @@
#include "opt_compat.h"
#include "opt_inet.h"
#include "opt_inet6.h"
+#include "opt_pax.h"
#define __ELF_WORD_SIZE 32
@@ -55,6 +56,7 @@
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/procctl.h>
#include <sys/reboot.h>
@@ -2802,6 +2804,10 @@
szsigcode = 0;
destp = (uintptr_t)arginfo;
+#ifdef PAX_ASLR
+ pax_aslr_stack(imgp->proc, &destp);
+#endif
+
/*
* install sigcode
*/
Index: sys/compat/ia32/ia32_sysvec.c
===================================================================
--- sys/compat/ia32/ia32_sysvec.c
+++ sys/compat/ia32/ia32_sysvec.c
@@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_pax.h"
#define __ELF_WORD_SIZE 32
@@ -43,6 +44,7 @@
#include <sys/mman.h>
#include <sys/namei.h>
#include <sys/pioctl.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/procfs.h>
#include <sys/resourcevar.h>
@@ -136,6 +138,7 @@
.sv_shared_page_base = FREEBSD32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec);
Index: sys/conf/NOTES
===================================================================
--- sys/conf/NOTES
+++ sys/conf/NOTES
@@ -2978,6 +2978,9 @@
# Module to enable execution of application via emulators like QEMU
options IMAGACT_BINMISC
+# PaX-inspired exploit mitigations
+options PAX_ASLR # Address Space Layout Randomization
+options PAX_SYSCTLS # Run-time settings for PAX and Hardening
# zlib I/O stream support
# This enables support for compressed core dumps.
options GZIO
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3024,6 +3024,8 @@
kern/kern_mutex.c standard
kern/kern_ntptime.c standard
kern/kern_osd.c standard
+kern/kern_pax.c optional pax_aslr
+kern/kern_pax_aslr.c optional pax_aslr
kern/kern_physio.c standard
kern/kern_pmc.c standard
kern/kern_poll.c optional device_polling
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -931,6 +931,10 @@
# Resource Limits
RCTL opt_global.h
+# PaX - hardening options
+PAX_ASLR opt_pax.h
+PAX_SYSCTLS opt_pax.h
+
# Random number generator(s)
RANDOM_YARROW opt_random.h
RANDOM_FORTUNA opt_random.h
Index: sys/i386/i386/elf_machdep.c
===================================================================
--- sys/i386/i386/elf_machdep.c
+++ sys/i386/i386/elf_machdep.c
@@ -27,6 +27,7 @@
__FBSDID("$FreeBSD$");
#include "opt_cpu.h"
+#include "opt_pax.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -34,6 +35,7 @@
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/linker.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
@@ -88,6 +90,7 @@
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
Index: sys/i386/ibcs2/ibcs2_sysvec.c
===================================================================
--- sys/i386/ibcs2/ibcs2_sysvec.c
+++ sys/i386/ibcs2/ibcs2_sysvec.c
@@ -31,6 +31,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -40,6 +42,7 @@
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/signalvar.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sx.h>
@@ -89,6 +92,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
static int
Index: sys/i386/linux/linux_sysvec.c
===================================================================
--- sys/i386/linux/linux_sysvec.c
+++ sys/i386/linux/linux_sysvec.c
@@ -29,6 +29,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
@@ -41,6 +43,7 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
@@ -973,6 +976,7 @@
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
@@ -1011,6 +1015,7 @@
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
Index: sys/kern/imgact_aout.c
===================================================================
--- sys/kern/imgact_aout.c
+++ sys/kern/imgact_aout.c
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/imgact.h>
@@ -36,6 +38,7 @@
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
@@ -99,6 +102,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
#elif defined(__amd64__)
@@ -143,6 +147,7 @@
.sv_set_syscall_retval = ia32_set_syscall_retval,
.sv_fetch_syscall_args = ia32_fetch_syscall_args,
.sv_syscallnames = freebsd32_syscallnames,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
#else
#error "Port me"
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -33,6 +33,7 @@
#include "opt_capsicum.h"
#include "opt_compat.h"
+#include "opt_pax.h"
#include "opt_gzio.h"
#include <sys/param.h>
@@ -50,6 +51,7 @@
#include <sys/mman.h>
#include <sys/namei.h>
#include <sys/pioctl.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/procfs.h>
#include <sys/racct.h>
@@ -797,16 +799,7 @@
if (hdr->e_type == ET_DYN) {
if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
return (ENOEXEC);
- /*
- * Honour the base load address from the dso if it is
- * non-zero for some reason.
- */
- if (baddr == 0)
- et_dyn_addr = ET_DYN_LOAD_ADDR;
- else
- et_dyn_addr = 0;
- } else
- et_dyn_addr = 0;
+ }
sv = brand_info->sysvec;
if (interp != NULL && brand_info->interp_newpath != NULL)
newinterp = brand_info->interp_newpath;
@@ -827,6 +820,20 @@
error = exec_new_vmspace(imgp, sv);
imgp->proc->p_sysent = sv;
+ et_dyn_addr = 0;
+ if (hdr->e_type == ET_DYN) {
+ /*
+ * Honour the base load address from the dso if it is
+ * non-zero for some reason.
+ */
+ if (baddr == 0) {
+ et_dyn_addr = ET_DYN_LOAD_ADDR;
+#ifdef PAX_ASLR
+ pax_aslr_execbase(imgp->proc, &et_dyn_addr);
+#endif
+ }
+ }
+
vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
if (error)
return (error);
Index: sys/kern/init_main.c
===================================================================
--- sys/kern/init_main.c
+++ sys/kern/init_main.c
@@ -46,6 +46,7 @@
#include "opt_ddb.h"
#include "opt_init_path.h"
+#include "opt_pax.h"
#include "opt_verbose_sysinit.h"
#include <sys/param.h>
@@ -61,6 +62,7 @@
#include <sys/mutex.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/racct.h>
#include <sys/resourcevar.h>
@@ -411,6 +413,7 @@
.sv_fetch_syscall_args = null_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = NULL,
};
/*
@@ -478,6 +481,9 @@
p->p_flag = P_SYSTEM | P_INMEM;
p->p_flag2 = 0;
p->p_state = PRS_NORMAL;
+#if defined(PAX_ASLR)
+ p->p_pax = PAX_NOTE_ALL_DISABLED;
+#endif
knlist_init_mtx(&p->p_klist, &p->p_mtx);
STAILQ_INIT(&p->p_ktr);
p->p_nice = NZERO;
@@ -495,6 +501,9 @@
td->td_flags = TDF_INMEM;
td->td_pflags = TDP_KTHREAD;
td->td_cpuset = cpuset_thread0();
+#if defined(PAX_ASLR)
+ td->td_pax = PAX_NOTE_ALL_DISABLED;
+#endif
prison0_init();
p->p_peers = 0;
p->p_leader = p;
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -30,6 +30,7 @@
#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>
@@ -50,6 +51,7 @@
#include <sys/imgact_elf.h>
#include <sys/wait.h>
#include <sys/malloc.h>
+#include <sys/pax.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/pioctl.h>
@@ -65,6 +67,7 @@
#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <sys/stat.h>
+#include <sys/jail.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
@@ -130,6 +133,10 @@
SYSCTL_INT(_security_bsd, OID_AUTO, map_at_zero, CTLFLAG_RWTUN, &map_at_zero, 0,
"Permit processes to map an object at virtual address 0.");
+#ifdef PAX_ASLR
+static int exec_check_aslr(struct image_params *imgp);
+#endif
+
static int
sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS)
{
@@ -383,6 +390,7 @@
imgp->proc = p;
imgp->attr = &attr;
imgp->args = args;
+ imgp->pax_flags = 0;
#ifdef MAC
error = mac_execve_enter(imgp, mac_p);
@@ -1043,6 +1051,12 @@
map = &vmspace->vm_map;
}
+#ifdef PAX_ASLR
+ PROC_LOCK(imgp->proc);
+ pax_aslr_init(imgp);
+ PROC_UNLOCK(imgp->proc);
+#endif
+
/* Map a shared page */
obj = sv->sv_shared_page_obj;
if (obj != NULL) {
@@ -1089,6 +1103,9 @@
*/
vmspace->vm_ssize = sgrowsiz >> PAGE_SHIFT;
vmspace->vm_maxsaddr = (char *)sv->sv_usrstack - ssiz;
+#ifdef PAX_ASLR
+ pax_aslr_stack_fixup(imgp->proc);
+#endif
return (0);
}
@@ -1256,6 +1273,9 @@
szsigcode = *(p->p_sysent->sv_szsigcode);
}
destp = (uintptr_t)arginfo;
+#ifdef PAX_ASLR
+ pax_aslr_stack(p, &destp);
+#endif
/*
* install sigcode
@@ -1376,6 +1396,46 @@
return (stack_base);
}
+#ifdef PAX_ASLR
+/*
+ * If we've disabled ASLR via ptrace, do not allow execution of
+ * setuid/setgid binaries.
+ */
+static int
+exec_check_aslr(struct image_params *imgp)
+{
+ struct proc *p = imgp->proc;
+ struct ucred *oldcred = p->p_ucred;
+ struct vattr *attr = imgp->attr;
+ int credential_changing;
+#ifdef MAC
+ struct label *interpvplabel = NULL;
+ int will_transition;
+#endif
+
+ credential_changing = 0;
+ credential_changing |= (attr->va_mode & S_ISUID) && oldcred->cr_uid !=
+ attr->va_uid;
+ credential_changing |= (attr->va_mode & S_ISGID) && oldcred->cr_gid !=
+ attr->va_gid;
+
+#ifdef MAC
+ will_transition = mac_vnode_execve_will_transition(oldcred, imgp->vp,
+ interpvplabel, imgp);
+ credential_changing |= will_transition;
+#endif
+
+ if (credential_changing) {
+ if ((p->p_paxdebug & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR) {
+ if (pax_aslr_active(imgp->proc))
+ return (EPERM);
+ }
+ }
+
+ return (pax_elf(imgp, p->p_paxdebug));
+}
+#endif /* PAX_ASLR */
+
/*
* Check permissions of file to execute.
* Called with imgp->vp locked.
@@ -1397,6 +1457,16 @@
if (error)
return (error);
+#if defined(PAX_ASLR)
+ PROC_LOCK(imgp->proc);
+ error = exec_check_aslr(imgp);
+ if (error) {
+ PROC_UNLOCK(imgp->proc);
+ return (error);
+ }
+ PROC_UNLOCK(imgp->proc);
+#endif
+
#ifdef MAC
error = mac_vnode_check_exec(td->td_ucred, imgp->vp, imgp);
if (error)
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -471,6 +471,7 @@
__rangeof(struct thread, td_startcopy, td_endcopy));
bcopy(&p2->p_comm, &td2->td_name, sizeof(td2->td_name));
+ td2->td_pax = p2->p_pax;
td2->td_sigstk = td->td_sigstk;
td2->td_flags = TDF_INMEM;
td2->td_lend_user_pri = PRI_MAX;
Index: sys/kern/kern_jail.c
===================================================================
--- sys/kern/kern_jail.c
+++ sys/kern/kern_jail.c
@@ -33,6 +33,7 @@
#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_inet6.h"
+#include "opt_pax.h"
#include <sys/param.h>
#include <sys/types.h>
@@ -42,6 +43,7 @@
#include <sys/sysproto.h>
#include <sys/malloc.h>
#include <sys/osd.h>
+#include <sys/pax.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/taskqueue.h>
@@ -246,6 +248,9 @@
prison0.pr_cpuset = cpuset_ref(thread0.td_cpuset);
prison0.pr_osreldate = osreldate;
strlcpy(prison0.pr_osrelease, osrelease, sizeof(prison0.pr_osrelease));
+#ifdef PAX_ASLR
+ pax_init_prison(&prison0);
+#endif
}
#ifdef INET
@@ -1357,7 +1362,9 @@
prison_deref(pr, PD_LIST_XLOCKED);
goto done_releroot;
}
-
+#ifdef PAX_ASLR
+ pax_init_prison(pr);
+#endif
mtx_lock(&pr->pr_mtx);
/*
* New prisons do not yet have a reference, because we do not
Index: sys/kern/kern_pax.c
===================================================================
--- /dev/null
+++ sys/kern/kern_pax.c
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org>
+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org>
+ * 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. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author 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 ``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 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$
+ *
+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753
+ * HardenedBSD-version: v16
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_pax.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/elf_common.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/jail.h>
+#include <sys/kthread.h>
+#include <sys/libkern.h>
+#include <sys/lock.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/mutex.h>
+#include <sys/pax.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/syslimits.h>
+#include <sys/sx.h>
+#include <sys/vnode.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <machine/elf.h>
+
+static int pax_validate_flags(uint32_t flags);
+static int pax_check_conflicting_modes(uint32_t mode);
+
+SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0,
+ "PaX (exploit mitigation) features.");
+
+const char *pax_status_str[] = {
+ [PAX_FEATURE_DISABLED] = "disabled",
+ [PAX_FEATURE_OPTIN] = "opt-in",
+ [PAX_FEATURE_OPTOUT] = "opt-out",
+ [PAX_FEATURE_FORCE_ENABLED] = "force enabled",
+ [PAX_FEATURE_UNKNOWN_STATUS] = "UNKNOWN -> changed to \"force enabled\""
+};
+
+const char *pax_status_simple_str[] = {
+ [PAX_FEATURE_SIMPLE_DISABLED] = "disabled",
+ [PAX_FEATURE_SIMPLE_ENABLED] = "enabled"
+};
+
+struct prison *
+pax_get_prison(struct proc *p)
+{
+
+ /* p can be NULL with kernel threads, so use prison0. */
+ if (p == NULL || p->p_ucred == NULL)
+ return (&prison0);
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ return (p->p_ucred->cr_prison);
+}
+
+/*
+* As it stands right now, only the sysctl(8)s controlling ASLR use
+* pax_get_prison_td. Thus this function requires td being equal to
+* curthread.
+*/
+struct prison *
+pax_get_prison_td(struct thread *td)
+{
+
+ KASSERT(td == curthread, ("pax_get_prison_td: td != curthread"));
+ if (td == NULL || td->td_ucred == NULL)
+ return (&prison0);
+ return (td->td_ucred->cr_prison);
+}
+
+void
+pax_get_flags(struct proc *p, uint32_t *flags)
+{
+
+ *flags = p->p_pax;
+}
+
+void
+pax_get_flags_td(struct thread *td, uint32_t *flags)
+{
+
+ *flags = td->td_pax;
+}
+
+static int
+pax_validate_flags(uint32_t flags)
+{
+
+ if ((flags & ~PAX_NOTE_ALL) != 0)
+ return (1);
+ return (0);
+}
+
+static int
+pax_check_conflicting_modes(uint32_t mode)
+{
+
+ if (((mode & PAX_NOTE_ALL_ENABLED) & ((mode & PAX_NOTE_ALL_DISABLED) >> 1)) != 0)
+ return (1);
+ return (0);
+}
+
+int
+pax_elf(struct image_params *imgp, uint32_t mode)
+{
+ uint32_t flags, flags_aslr;
+
+ flags = mode;
+ flags_aslr = 0;
+ if (pax_validate_flags(flags) != 0)
+ return (ENOEXEC);
+ if (pax_check_conflicting_modes(mode) != 0)
+ return (ENOEXEC);
+#ifdef PAX_ASLR
+ flags_aslr = pax_aslr_setup_flags(imgp, mode);
+#endif
+ flags = flags_aslr;
+ CTR3(KTR_PAX, "%s : flags = %x mode = %x",
+ __func__, flags, mode);
+ imgp->proc->p_pax = flags;
+ return (0);
+}
+
+void
+pax_init_prison(struct prison *pr)
+{
+
+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
+ __func__, pr->pr_name);
+
+ pax_aslr_init_prison(pr);
+#ifdef COMPAT_FREEBSD32
+ pax_aslr_init_prison32(pr);
+#endif
+}
Index: sys/kern/kern_pax_aslr.c
===================================================================
--- /dev/null
+++ sys/kern/kern_pax_aslr.c
@@ -0,0 +1,807 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org>
+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org>
+ * 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. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author 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 ``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 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$
+ *
+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753
+ * HardenedBSD-version: v16
+ *
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_pax.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/elf_common.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/jail.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/ktr.h>
+#include <sys/libkern.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/pax.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/sysent.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <machine/elf.h>
+
+#ifndef PAX_ASLR_DELTA
+#define PAX_ASLR_DELTA(delta, lsb, len) \
+ (((delta) & ((1UL << (len)) - 1)) << (lsb))
+#endif /* PAX_ASLR_DELTA */
+
+/*-
+ * generic ASLR values
+ *
+ * MMAP | 32 bit | 64 bit | compat |
+ * +-------+--------+--------+--------+
+ * | MIN | 8 bit | 16 bit | 8 bit |
+ * +-------+--------+--------+--------+
+ * | DEF | 14 bit | 21 bit | 14 bit |
+ * +-------+--------+--------+--------+
+ * | MAX | 21 bit | 42 bit | 21 bit |
+ * +-------+--------+--------+--------+
+ *
+ * STACK | 32 bit | 64 bit | 32 bit |
+ * +-------+--------+--------+--------+
+ * | MIN | 8 bit | 16 bit | 8 bit |
+ * +-------+--------+--------+--------+
+ * | DEF | 8 bit | 16 bit | 8 bit |
+ * +-------+--------+--------+--------+
+ * | MAX | 21 bit | 42 bit | 21 bit |
+ * +-------+--------+--------+--------+
+ *
+ * EXEC | 32 bit | 64 bit | 32 bit |
+ * +-------+--------+--------+--------+
+ * | MIN | 8 bit | 16 bit | 8 bit |
+ * +-------+--------+--------+--------+
+ * | DEF | 14 bit | 16 bit | 14 bit |
+ * +-------+--------+--------+--------+
+ * | MAX | 21 bit | 42 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) / 3)
+#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) / 4)
+#endif /* PAX_ASLR_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_DELTA_STACK_MAX_LEN
+#define PAX_ASLR_DELTA_STACK_MAX_LEN (((sizeof(void *) * NBBY) * 2) / 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) / 4)
+#endif /* PAX_ASLR_DELTA_EXEC_MIN_LEN */
+
+#ifndef PAX_ASLR_DELTA_EXEC_MAX_LEN
+#define PAX_ASLR_DELTA_EXEC_MAX_LEN (((sizeof(void *) * NBBY) * 2) / 3)
+#endif /* PAX_ASLR_DELTA_EXEC_MAX_LEN */
+
+/*
+ * ASLR default values for native host
+ */
+#ifdef __LP64__
+#ifndef PAX_ASLR_DELTA_MMAP_DEF_LEN
+#define PAX_ASLR_DELTA_MMAP_DEF_LEN 21
+#endif /* PAX_ASLR_DELTA_MMAP_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_STACK_DEF_LEN
+#define PAX_ASLR_DELTA_STACK_DEF_LEN 16
+#endif /* PAX_ASLR_DELTA_STACK_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_EXEC_DEF_LEN
+#define PAX_ASLR_DELTA_EXEC_DEF_LEN 16
+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */
+#else /* ! __LP64__ */
+#ifndef PAX_ASLR_DELTA_MMAP_DEF_LEN
+#define PAX_ASLR_DELTA_MMAP_DEF_LEN 14
+#endif /* PAX_ASLR_DELTA_MMAP_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_STACK_DEF_LEN
+#define PAX_ASLR_DELTA_STACK_DEF_LEN PAX_ASLR_DELTA_STACK_MIN_LEN
+#endif /* PAX_ASLR_DELTA_STACK_DEF_LEN */
+#ifndef PAX_ASLR_DELTA_EXEC_DEF_LEN
+#define PAX_ASLR_DELTA_EXEC_DEF_LEN 14
+#endif /* PAX_ASLR_DELTA_EXEC_DEF_LEN */
+#endif /* __LP64__ */
+
+/*
+ * ASLR values for COMPAT_FREEBSD32, COMPAT_LINUX and MAP_32BIT
+ */
+#if defined(COMPAT_LINUX) || defined(COMPAT_FREEBSD32) || defined(MAP_32BIT)
+#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) / 3)
+#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) / 4)
+#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) * 2) / 3)
+#endif /* PAX_ASLR_COMPAT_DELTA_STACK_MAX_LEN */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_LSB
+#define PAX_ASLR_COMPAT_DELTA_EXEC_LSB PAGE_SHIFT
+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_LSB */
+
+#ifndef PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN
+#define PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN ((sizeof(int) * NBBY) / 4)
+#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) * 2) / 3)
+#endif /* PAX_ASLR_COMPAT_DELTA_EXEC_MAX_LEN */
+#endif
+
+FEATURE(aslr, "Address Space Layout Randomization.");
+
+static int pax_aslr_status = PAX_FEATURE_OPTOUT;
+static int pax_aslr_mmap_len = PAX_ASLR_DELTA_MMAP_DEF_LEN;
+static int pax_aslr_stack_len = PAX_ASLR_DELTA_STACK_DEF_LEN;
+static int pax_aslr_exec_len = PAX_ASLR_DELTA_EXEC_DEF_LEN;
+
+#ifdef COMPAT_FREEBSD32
+static int pax_aslr_compat_status = PAX_FEATURE_OPTOUT;
+static int pax_aslr_compat_mmap_len = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN;
+static int pax_aslr_compat_stack_len = PAX_ASLR_COMPAT_DELTA_STACK_MIN_LEN;
+static int pax_aslr_compat_exec_len = PAX_ASLR_COMPAT_DELTA_EXEC_MIN_LEN;
+#endif /* COMPAT_FREEBSD32 */
+
+TUNABLE_INT("security.pax.aslr.status", &pax_aslr_status);
+TUNABLE_INT("security.pax.aslr.mmap_len", &pax_aslr_mmap_len);
+TUNABLE_INT("security.pax.aslr.stack_len", &pax_aslr_stack_len);
+TUNABLE_INT("security.pax.aslr.exec_len", &pax_aslr_exec_len);
+#ifdef COMPAT_FREEBSD32
+TUNABLE_INT("security.pax.aslr.compat.status", &pax_aslr_compat_status);
+TUNABLE_INT("security.pax.aslr.compat.mmap_len", &pax_aslr_compat_mmap_len);
+TUNABLE_INT("security.pax.aslr.compat.stack_len", &pax_aslr_compat_stack_len);
+TUNABLE_INT("security.pax.aslr.compat.exec_len", &pax_aslr_compat_exec_len);
+#endif
+
+#ifdef PAX_SYSCTLS
+SYSCTL_DECL(_security_pax);
+
+/*
+ * sysctls
+ */
+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);
+
+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_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+ NULL, 0, sysctl_pax_aslr_status, "I",
+ "Restrictions status. "
+ "0 - disabled, "
+ "1 - opt-in, "
+ "2 - opt-out, "
+ "3 - force enabled");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, mmap_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+ NULL, 0, sysctl_pax_aslr_mmap, "I",
+ "Number of bits randomized for mmap(2) calls. "
+ "32 bit: [8,21] 64 bit: [16,42]");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, stack_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+ NULL, 0, sysctl_pax_aslr_stack, "I",
+ "Number of bits randomized for the stack. "
+ "32 bit: [8,21] 64 bit: [16,42]");
+
+SYSCTL_PROC(_security_pax_aslr, OID_AUTO, exec_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON|CTLFLAG_SECURE,
+ NULL, 0, sysctl_pax_aslr_exec, "I",
+ "Number of bits randomized for the PIE exec base. "
+ "32 bit: [8,21] 64 bit: [16,42]");
+
+static int
+sysctl_pax_aslr_status(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_pax_aslr_status;
+ err = sysctl_handle_int(oidp, &val, sizeof(int), req);
+ if (err || (req->newptr == NULL))
+ return (err);
+ switch (val) {
+ case PAX_FEATURE_DISABLED:
+ case PAX_FEATURE_OPTIN:
+ case PAX_FEATURE_OPTOUT:
+ case PAX_FEATURE_FORCE_ENABLED:
+ if (pr == &prison0)
+ pax_aslr_status = val;
+ pr->pr_hardening.hf_pax_aslr_status = val;
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_mmap(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_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);
+ if (pr == &prison0)
+ pax_aslr_mmap_len = val;
+ pr->pr_hardening.hf_pax_aslr_mmap_len = val;
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_stack(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_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);
+ if (pr == &prison0)
+ pax_aslr_stack_len = val;
+ pr->pr_hardening.hf_pax_aslr_stack_len = val;
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_exec(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_pax_aslr_exec_len;
+ err = sysctl_handle_int(oidp, &val, sizeof(int), req);
+ if (err || (req->newptr == NULL))
+ return (err);
+ if (val < PAX_ASLR_DELTA_EXEC_MIN_LEN ||
+ val > PAX_ASLR_DELTA_EXEC_MAX_LEN)
+ return (EINVAL);
+ if (pr == &prison0)
+ pax_aslr_exec_len = val;
+ pr->pr_hardening.hf_pax_aslr_exec_len = val;
+ return (0);
+}
+
+/* COMPAT_FREEBSD32 and linuxulator. */
+#ifdef COMPAT_FREEBSD32
+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);
+
+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_RWTUN|CTLFLAG_PRISON,
+ NULL, 0, sysctl_pax_aslr_compat_status, "I",
+ "Restrictions status. "
+ "0 - disabled, "
+ "1 - enabled, "
+ "2 - global enabled, "
+ "3 - force global enabled");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, mmap_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+ NULL, 0, sysctl_pax_aslr_compat_mmap, "I",
+ "Number of bits randomized for mmap(2) calls. "
+ "32 bit: [8,16]");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, stack_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+ NULL, 0, sysctl_pax_aslr_compat_stack, "I",
+ "Number of bits randomized for the stack. "
+ "32 bit: [8,16]");
+
+SYSCTL_PROC(_security_pax_aslr_compat, OID_AUTO, exec_len,
+ CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_PRISON,
+ NULL, 0, sysctl_pax_aslr_compat_exec, "I",
+ "Number of bits randomized for the PIE exec base. "
+ "32 bit: [8,16]");
+
+static int
+sysctl_pax_aslr_compat_status(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_pax_aslr_compat_status;
+ err = sysctl_handle_int(oidp, &val, sizeof(int), req);
+ if (err || (req->newptr == NULL))
+ return (err);
+ switch (val) {
+ case PAX_FEATURE_DISABLED:
+ case PAX_FEATURE_OPTIN:
+ case PAX_FEATURE_OPTOUT:
+ case PAX_FEATURE_FORCE_ENABLED:
+ if (pr == &prison0)
+ pax_aslr_compat_status = val;
+ pr->pr_hardening.hf_pax_aslr_compat_status = val;
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_mmap(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_pax_aslr_compat_mmap_len;
+ 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);
+ if (pr == &prison0)
+ pax_aslr_compat_mmap_len = val;
+ pr->pr_hardening.hf_pax_aslr_compat_mmap_len = val;
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_stack(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+ val = pr->pr_hardening.hf_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);
+ if (pr == &prison0)
+ pax_aslr_compat_stack_len = val;
+ pr->pr_hardening.hf_pax_aslr_compat_stack_len = val;
+ return (0);
+}
+
+static int
+sysctl_pax_aslr_compat_exec(SYSCTL_HANDLER_ARGS)
+{
+ struct prison *pr;
+ int err, val;
+
+ pr = pax_get_prison_td(req->td);
+
+ val = pr->pr_hardening.hf_pax_aslr_compat_exec_len;
+ 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);
+ if (pr == &prison0)
+ pax_aslr_compat_exec_len = val;
+ pr->pr_hardening.hf_pax_aslr_compat_exec_len = val;
+ return (0);
+}
+
+#endif /* COMPAT_FREEBSD32 */
+#endif /* PAX_SYSCTLS */
+
+
+/*
+ * ASLR functions
+ */
+
+static void
+pax_aslr_sysinit(void)
+{
+
+ switch (pax_aslr_status) {
+ case PAX_FEATURE_DISABLED:
+ case PAX_FEATURE_OPTIN:
+ case PAX_FEATURE_OPTOUT:
+ case PAX_FEATURE_FORCE_ENABLED:
+ break;
+
+ default:
+ printf("warning: invalid settings in loader.conf:"
+ " (pax_aslr_status = %d)\n", pax_aslr_status);
+ pax_aslr_status = PAX_FEATURE_FORCE_ENABLED;
+ break;
+ }
+ if (bootverbose) {
+ printf("PAX ASLR status: %s\n", pax_status_str[pax_aslr_status]);
+ printf("PAX ASLR mmap: %d bit\n", pax_aslr_mmap_len);
+ printf("PAX ASLR exec base: %d bit\n", pax_aslr_exec_len);
+ printf("PAX ASLR stack: %d bit\n", pax_aslr_stack_len);
+ }
+}
+SYSINIT(pax_aslr, SI_SUB_PAX, SI_ORDER_FIRST, pax_aslr_sysinit, NULL);
+
+int
+pax_aslr_active(struct proc *p)
+{
+ uint32_t flags;
+
+ pax_get_flags(p, &flags);
+ CTR3(KTR_PAX, "%s: pid = %d p_pax = %x",
+ __func__, p->p_pid, flags);
+ if ((flags & PAX_NOTE_ASLR) == PAX_NOTE_ASLR)
+ return (1);
+ if ((flags & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR)
+ return (0);
+ return (1);
+}
+
+void
+pax_aslr_init_vmspace(struct proc *p)
+{
+ struct prison *pr;
+ struct vmspace *vm;
+ unsigned long rand_buf;
+
+ vm = p->p_vmspace;
+ pr = pax_get_prison(p);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_DELTA_MMAP_LSB,
+ pr->pr_hardening.hf_pax_aslr_mmap_len);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_DELTA_STACK_LSB,
+ pr->pr_hardening.hf_pax_aslr_stack_len);
+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_exec = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_DELTA_EXEC_LSB,
+ pr->pr_hardening.hf_pax_aslr_exec_len);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_mmap=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_mmap);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_stack=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_stack);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_exec=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_exec);
+}
+
+#ifdef COMPAT_FREEBSD32
+static void
+pax_compat_aslr_sysinit(void)
+{
+
+ switch (pax_aslr_compat_status) {
+ case PAX_FEATURE_DISABLED:
+ case PAX_FEATURE_OPTIN:
+ case PAX_FEATURE_OPTOUT:
+ case PAX_FEATURE_FORCE_ENABLED:
+ break;
+
+ default:
+ printf("warning: invalid settings in loader.conf! "
+ "(pax_aslr_compat_status = %d)\n", pax_aslr_compat_status);
+ pax_aslr_compat_status = PAX_FEATURE_FORCE_ENABLED;
+ break;
+ }
+ if (bootverbose) {
+ printf("PAX ASLR (compat) status: %s\n", pax_status_str[pax_aslr_compat_status]);
+ printf("PAX ASLR (compat) mmap: %d bit\n", pax_aslr_compat_mmap_len);
+ printf("PAX ASLR (compat) exec base: %d bit\n", pax_aslr_compat_exec_len);
+ printf("PAX ASLR (compat) stack: %d bit\n", pax_aslr_compat_stack_len);
+ }
+}
+SYSINIT(pax_compat_aslr, SI_SUB_PAX, SI_ORDER_SECOND, pax_compat_aslr_sysinit, NULL);
+
+void
+pax_aslr_init_vmspace32(struct proc *p)
+{
+ struct prison *pr;
+ struct vmspace *vm;
+ long rand_buf;
+
+ vm = p->p_vmspace;
+ pr = pax_get_prison(p);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_COMPAT_DELTA_MMAP_LSB,
+ pr->pr_hardening.hf_pax_aslr_compat_mmap_len);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_COMPAT_DELTA_STACK_LSB,
+ pr->pr_hardening.hf_pax_aslr_compat_stack_len);
+ vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack);
+ arc4rand(&rand_buf, sizeof(rand_buf), 0);
+ vm->vm_aslr_delta_exec = PAX_ASLR_DELTA(rand_buf,
+ PAX_ASLR_COMPAT_DELTA_EXEC_LSB,
+ pr->pr_hardening.hf_pax_aslr_compat_exec_len);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_mmap=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_mmap);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_stack=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_stack);
+ CTR2(KTR_PAX, "%s: vm_aslr_delta_exec=%p\n",
+ __func__, (void *)vm->vm_aslr_delta_exec);
+}
+#endif
+
+void
+pax_aslr_init(struct image_params *imgp)
+{
+ struct proc *p;
+
+ p = imgp->proc;
+ if (!pax_aslr_active(p))
+ return;
+ if (imgp->sysent->sv_pax_aslr_init != NULL)
+ imgp->sysent->sv_pax_aslr_init(p);
+}
+
+void
+pax_aslr_init_prison(struct prison *pr)
+{
+ struct prison *pr_p;
+
+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
+ __func__, pr->pr_name);
+ if (pr == &prison0) {
+ /* prison0 has no parent, use globals */
+ pr->pr_hardening.hf_pax_aslr_status = pax_aslr_status;
+ pr->pr_hardening.hf_pax_aslr_mmap_len =
+ pax_aslr_mmap_len;
+ pr->pr_hardening.hf_pax_aslr_stack_len =
+ pax_aslr_stack_len;
+ pr->pr_hardening.hf_pax_aslr_exec_len =
+ pax_aslr_exec_len;
+ } else {
+ KASSERT(pr->pr_parent != NULL,
+ ("%s: pr->pr_parent == NULL", __func__));
+ pr_p = pr->pr_parent;
+ pr->pr_hardening.hf_pax_aslr_status =
+ pr_p->pr_hardening.hf_pax_aslr_status;
+ pr->pr_hardening.hf_pax_aslr_mmap_len =
+ pr_p->pr_hardening.hf_pax_aslr_mmap_len;
+ pr->pr_hardening.hf_pax_aslr_stack_len =
+ pr_p->pr_hardening.hf_pax_aslr_stack_len;
+ pr->pr_hardening.hf_pax_aslr_exec_len =
+ pr_p->pr_hardening.hf_pax_aslr_exec_len;
+ }
+}
+
+#ifdef COMPAT_FREEBSD32
+void
+pax_aslr_init_prison32(struct prison *pr)
+{
+ struct prison *pr_p;
+
+ CTR2(KTR_PAX, "%s: Setting prison %s PaX variables\n",
+ __func__, pr->pr_name);
+ if (pr == &prison0) {
+ /* prison0 has no parent, use globals. */
+
+ pr->pr_hardening.hf_pax_aslr_compat_status =
+ pax_aslr_compat_status;
+ pr->pr_hardening.hf_pax_aslr_compat_mmap_len =
+ pax_aslr_compat_mmap_len;
+ pr->pr_hardening.hf_pax_aslr_compat_stack_len =
+ pax_aslr_compat_stack_len;
+ pr->pr_hardening.hf_pax_aslr_compat_exec_len =
+ pax_aslr_compat_exec_len;
+ } else {
+ KASSERT(pr->pr_parent != NULL,
+ ("%s: pr->pr_parent == NULL", __func__));
+ pr_p = pr->pr_parent;
+ pr->pr_hardening.hf_pax_aslr_compat_status =
+ pr_p->pr_hardening.hf_pax_aslr_compat_status;
+ pr->pr_hardening.hf_pax_aslr_compat_mmap_len =
+ pr_p->pr_hardening.hf_pax_aslr_compat_mmap_len;
+ pr->pr_hardening.hf_pax_aslr_compat_stack_len =
+ pr_p->pr_hardening.hf_pax_aslr_compat_stack_len;
+ pr->pr_hardening.hf_pax_aslr_compat_exec_len =
+ pr_p->pr_hardening.hf_pax_aslr_compat_exec_len;
+ }
+}
+#endif /* COMPAT_FREEBSD32 */
+
+void
+pax_aslr_mmap(struct proc *p, vm_offset_t *addr, vm_offset_t orig_addr, int flags)
+{
+
+ if (!pax_aslr_active(p))
+ return;
+ if (!(flags & MAP_FIXED) && ((orig_addr == 0) || !(flags & MAP_ANON))) {
+ CTR4(KTR_PAX, "%s: applying to %p orig_addr=%p flags=%x\n",
+ __func__, (void *)*addr, (void *)orig_addr, flags);
+#ifdef MAP_32BIT
+ if (flags & MAP_32BIT) {
+ int len_32bit;
+
+#ifdef COMPAT_FREEBSD32
+ len_32bit = pax_aslr_compat_mmap_len;
+#else
+ len_32bit = PAX_ASLR_COMPAT_DELTA_MMAP_MIN_LEN;
+#endif
+ *addr += PAX_ASLR_DELTA(arc4random(),
+ PAX_ASLR_COMPAT_DELTA_MMAP_LSB,
+ len_32bit);
+ } else
+#endif /* MAP_32BIT */
+ *addr += p->p_vmspace->vm_aslr_delta_mmap;
+ CTR2(KTR_PAX, "%s: result %p\n", __func__, (void *)*addr);
+ } else
+ CTR4(KTR_PAX, "%s: not applying to %p orig_addr=%p flags=%x\n",
+ __func__, (void *)*addr, (void *)orig_addr, flags);
+}
+
+void
+pax_aslr_stack(struct proc *p, uintptr_t *addr)
+{
+ uintptr_t orig_addr;
+
+ if (!pax_aslr_active(p))
+ return;
+ orig_addr = *addr;
+ *addr -= p->p_vmspace->vm_aslr_delta_stack;
+ CTR3(KTR_PAX, "%s: orig_addr=%p, new_addr=%p\n",
+ __func__, (void *)orig_addr, (void *)*addr);
+}
+
+void
+pax_aslr_stack_fixup(struct proc *p)
+{
+
+ if (!pax_aslr_active(p))
+ return;
+ p->p_vmspace->vm_maxsaddr -= p->p_vmspace->vm_aslr_delta_stack;
+}
+
+void
+pax_aslr_execbase(struct proc *p, u_long *et_dyn_addrp)
+{
+
+ if (!pax_aslr_active(p))
+ return;
+ *et_dyn_addrp += p->p_vmspace->vm_aslr_delta_exec;
+}
+
+uint32_t
+pax_aslr_setup_flags(struct image_params *imgp, uint32_t mode)
+{
+ struct prison *pr;
+ uint32_t flags, status;
+
+ flags = 0;
+ status = 0;
+ pr = pax_get_prison(imgp->proc);
+ status = pr->pr_hardening.hf_pax_aslr_status;
+ if (status == PAX_FEATURE_DISABLED) {
+ flags &= ~PAX_NOTE_ASLR;
+ flags |= PAX_NOTE_NOASLR;
+
+ return (flags);
+ }
+ if (status == PAX_FEATURE_FORCE_ENABLED) {
+ flags |= PAX_NOTE_ASLR;
+ flags &= ~PAX_NOTE_NOASLR;
+
+ return (flags);
+ }
+ if (status == PAX_FEATURE_OPTIN) {
+ if (mode & PAX_NOTE_ASLR) {
+ flags |= PAX_NOTE_ASLR;
+ flags &= ~PAX_NOTE_NOASLR;
+ } else {
+ flags &= ~PAX_NOTE_ASLR;
+ flags |= PAX_NOTE_NOASLR;
+ }
+ return (flags);
+ }
+ if (status == PAX_FEATURE_OPTOUT) {
+ if (mode & PAX_NOTE_NOASLR) {
+ flags &= ~PAX_NOTE_ASLR;
+ flags |= PAX_NOTE_NOASLR;
+ } else {
+ flags |= PAX_NOTE_ASLR;
+ flags &= ~PAX_NOTE_NOASLR;
+ }
+ return (flags);
+ }
+
+ /*
+ * flags is in an unknown state, so force ASLR.
+ */
+ flags |= PAX_NOTE_ASLR;
+ flags &= ~PAX_NOTE_NOASLR;
+ return (flags);
+}
+
Index: sys/kern/kern_thr.c
===================================================================
--- sys/kern/kern_thr.c
+++ sys/kern/kern_thr.c
@@ -254,6 +254,7 @@
td->td_proc->p_flag |= P_HADTHREADS;
thread_link(newtd, p);
bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
+ newtd->td_pax = p->p_pax;
thread_lock(td);
/* let the scheduler know about these things. */
sched_fork_thread(td, newtd);
Index: sys/kern/sys_process.c
===================================================================
--- sys/kern/sys_process.c
+++ sys/kern/sys_process.c
@@ -33,6 +33,7 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_pax.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -41,6 +42,7 @@
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
+#include <sys/pax.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/vnode.h>
@@ -651,6 +653,7 @@
/* Lock proctree before locking the process. */
switch (req) {
+ case PT_PAX:
case PT_TRACE_ME:
case PT_ATTACH:
case PT_STEP:
@@ -668,7 +671,7 @@
}
write = 0;
- if (req == PT_TRACE_ME) {
+ if (req == PT_TRACE_ME || req == PT_PAX) {
p = td->td_proc;
PROC_LOCK(p);
} else {
@@ -735,6 +738,16 @@
* Permissions check
*/
switch (req) {
+ case PT_PAX:
+ /* securelevel must be 0 to allow this */
+ if ((data & PAX_NOTE_NOASLR) == PAX_NOTE_NOASLR) {
+ if (securelevel_gt(p->p_ucred, 0) != 0) {
+ error = EPERM;
+ goto fail;
+ }
+ }
+ break;
+
case PT_TRACE_ME:
/* Always legal. */
break;
@@ -820,6 +833,9 @@
td->td_retval[0] = 0;
switch (req) {
+ case PT_PAX:
+ p->p_paxdebug = data;
+ break;
case PT_TRACE_ME:
/* set my trace flag and "owner" so it can read/write me */
p->p_flag |= P_TRACED;
Index: sys/mips/mips/elf_machdep.c
===================================================================
--- sys/mips/mips/elf_machdep.c
+++ sys/mips/mips/elf_machdep.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -36,6 +38,7 @@
#include <sys/linker.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/syscall.h>
#include <sys/signalvar.h>
@@ -83,6 +86,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
static Elf64_Brandinfo freebsd_brand_info = {
@@ -139,6 +143,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
static Elf32_Brandinfo freebsd_brand_info = {
Index: sys/mips/mips/freebsd32_machdep.c
===================================================================
--- sys/mips/mips/freebsd32_machdep.c
+++ sys/mips/mips/freebsd32_machdep.c
@@ -31,6 +31,7 @@
*/
#include "opt_compat.h"
+#include "opt_pax.h"
#define __ELF_WORD_SIZE 32
@@ -45,6 +46,7 @@
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/fcntl.h>
+#include <sys/pax.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
#include <sys/syscall.h>
@@ -106,6 +108,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = freebsd32_syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
Index: sys/powerpc/powerpc/elf32_machdep.c
===================================================================
--- sys/powerpc/powerpc/elf32_machdep.c
+++ sys/powerpc/powerpc/elf32_machdep.c
@@ -25,6 +25,8 @@
* $FreeBSD$
*/
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -34,6 +36,7 @@
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/malloc.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/fcntl.h>
@@ -108,6 +111,7 @@
.sv_shared_page_base = FREEBSD32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace32,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
Index: sys/powerpc/powerpc/elf64_machdep.c
===================================================================
--- sys/powerpc/powerpc/elf64_machdep.c
+++ sys/powerpc/powerpc/elf64_machdep.c
@@ -25,12 +25,15 @@
* $FreeBSD$
*/
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/malloc.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/fcntl.h>
@@ -84,6 +87,7 @@
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
Index: sys/sparc64/sparc64/elf_machdep.c
===================================================================
--- sys/sparc64/sparc64/elf_machdep.c
+++ sys/sparc64/sparc64/elf_machdep.c
@@ -34,12 +34,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_pax.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/linker.h>
+#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
@@ -87,6 +90,7 @@
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_pax_aslr_init = pax_aslr_init_vmspace,
};
static Elf64_Brandinfo freebsd_brand_info = {
Index: sys/sys/imgact.h
===================================================================
--- sys/sys/imgact.h
+++ sys/sys/imgact.h
@@ -81,6 +81,7 @@
int pagesizeslen;
vm_prot_t stack_prot;
u_long stack_sz;
+ int pax_flags;
};
#ifdef _KERNEL
Index: sys/sys/jail.h
===================================================================
--- sys/sys/jail.h
+++ sys/sys/jail.h
@@ -30,6 +30,10 @@
#ifndef _SYS_JAIL_H_
#define _SYS_JAIL_H_
+#if defined(_KERNEL) || defined(_WANT_PRISON)
+#include <sys/pax.h>
+#endif
+
#ifdef _KERNEL
struct jail_v0 {
u_int32_t version;
@@ -186,6 +190,7 @@
char pr_hostname[MAXHOSTNAMELEN]; /* (p) jail hostname */
char pr_domainname[MAXHOSTNAMELEN]; /* (p) jail domainname */
char pr_hostuuid[HOSTUUIDLEN]; /* (p) jail hostuuid */
+ struct hardening_features pr_hardening; /* (p) PaX-inspired hardening features */
char pr_osrelease[OSRELEASELEN]; /* (c) kern.osrelease value */
};
Index: sys/sys/kernel.h
===================================================================
--- sys/sys/kernel.h
+++ sys/sys/kernel.h
@@ -102,6 +102,7 @@
SI_SUB_WITNESS = 0x1A80000, /* witness initialization */
SI_SUB_MTX_POOL_DYNAMIC = 0x1AC0000, /* dynamic mutex pool */
SI_SUB_LOCK = 0x1B00000, /* various locks */
+ SI_SUB_PAX = 0x1B80000, /* pax setup */
SI_SUB_EVENTHANDLER = 0x1C00000, /* eventhandler init */
SI_SUB_VNET_PRELINK = 0x1E00000, /* vnet init before modules */
SI_SUB_KLD = 0x2000000, /* KLD and module setup */
Index: sys/sys/ktr_class.h
===================================================================
--- sys/sys/ktr_class.h
+++ sys/sys/ktr_class.h
@@ -71,7 +71,8 @@
#define KTR_INET6 0x10000000 /* IPv6 stack */
#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
#define KTR_BUF 0x40000000 /* Buffer cache */
-#define KTR_ALL 0x7fffffff
+#define KTR_PAX 0x80000000 /* PaX */
+#define KTR_ALL 0xffffffff
/* KTR trace classes to compile in */
#ifdef KTR
Index: sys/sys/pax.h
===================================================================
--- /dev/null
+++ sys/sys/pax.h
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
+ * Copyright (c) 2013-2015, by Oliver Pinter <oliver.pinter@hardenedbsd.org>
+ * Copyright (c) 2014-2015, by Shawn Webb <shawn.webb@hardenedbsd.org>
+ * 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. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author 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 ``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 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$
+ *
+ * HardenedBSD-version: 2fba75c32739bd7f7c80163ec88e3655c3130753
+ * HardenedBSD-version: v16
+ *
+ */
+
+#ifndef _SYS_PAX_H
+#define _SYS_PAX_H
+
+#if defined(_KERNEL) || defined(_WANT_PRISON)
+struct hardening_features {
+ int hf_pax_aslr_status; /* (p) PaX ASLR enabled */
+ int hf_pax_aslr_mmap_len; /* (p) Number of bits randomized with mmap */
+ int hf_pax_aslr_stack_len; /* (p) Number of bits randomized with stack */
+ int hf_pax_aslr_exec_len; /* (p) Number of bits randomized with the execbase */
+ int hf_pax_aslr_compat_status; /* (p) PaX ASLR enabled (compat32) */
+ int hf_pax_aslr_compat_mmap_len; /* (p) Number of bits randomized with mmap (compat32) */
+ int hf_pax_aslr_compat_stack_len; /* (p) Number of bits randomized with stack (compat32) */
+ int hf_pax_aslr_compat_exec_len; /* (p) Number of bits randomized with the execbase (compat32) */
+};
+#endif
+
+#ifdef _KERNEL
+#ifdef PAX_ASLR
+struct image_params;
+struct prison;
+struct thread;
+struct proc;
+struct vnode;
+struct vm_offset_t;
+
+/*
+ * Used in sysctl handlers.
+ */
+#define PAX_FEATURE_DISABLED 0
+#define PAX_FEATURE_OPTIN 1
+#define PAX_FEATURE_OPTOUT 2
+#define PAX_FEATURE_FORCE_ENABLED 3
+#define PAX_FEATURE_UNKNOWN_STATUS 4
+
+extern const char *pax_status_str[];
+
+#define PAX_FEATURE_SIMPLE_DISABLED 0
+#define PAX_FEATURE_SIMPLE_ENABLED 1
+
+extern const char *pax_status_simple_str[];
+
+/*
+ * Generic PaX functions.
+ */
+int pax_elf(struct image_params *, uint32_t);
+void pax_get_flags(struct proc *, uint32_t *);
+void pax_get_flags_td(struct thread *, uint32_t *);
+struct prison *pax_get_prison(struct proc *);
+struct prison *pax_get_prison_td(struct thread *);
+void pax_init_prison(struct prison *);
+
+/*
+ * ASLR related functions.
+ */
+int pax_aslr_active(struct proc *);
+void pax_aslr_execbase(struct proc *, u_long *);
+void pax_aslr_init(struct image_params *);
+void pax_aslr_init_prison(struct prison *);
+void pax_aslr_init_prison32(struct prison *);
+uint32_t pax_aslr_setup_flags(struct image_params *, uint32_t);
+void pax_aslr_init_vmspace(struct proc *);
+void pax_aslr_init_vmspace32(struct proc *);
+void pax_aslr_mmap(struct proc *, vm_offset_t *, vm_offset_t, int);
+void pax_aslr_stack(struct proc *, uintptr_t *);
+void pax_aslr_stack_fixup(struct proc *);
+
+#else /* PAX_ASLR */
+
+#define pax_aslr_init_vmspace NULL
+#define pax_aslr_init_vmspace32 NULL
+#define pax_aslr_init_prison(pr) do {} while (0)
+#define pax_aslr_init_prison32(pr) do {} while (0)
+
+#endif /* PAX_ASLR */
+
+/*
+ * Keep these values to keep compatibility with HardenedBSD
+ */
+#define PAX_NOTE_ASLR 0x00000040
+#define PAX_NOTE_NOASLR 0x00000080
+#define PAX_NOTE_ALL_ENABLED (PAX_NOTE_ASLR)
+#define PAX_NOTE_ALL_DISABLED (PAX_NOTE_NOASLR)
+#define PAX_NOTE_ALL (PAX_NOTE_ALL_ENABLED | PAX_NOTE_ALL_DISABLED)
+
+#endif /* _KERNEL */
+#endif /* _SYS_PAX_H */
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -288,6 +288,7 @@
u_char td_pri_class; /* (t) Scheduling class. */
u_char td_user_pri; /* (t) User pri from estcpu and nice. */
u_char td_base_user_pri; /* (t) Base user pri */
+ uint32_t td_pax; /* (b) Cached PaX settings from process */
#define td_endcopy td_pcb
/*
@@ -578,6 +579,8 @@
pid_t p_reapsubtree; /* (e) Pid of the direct child of the
reaper which spawned
our subtree. */
+ u_int p_pax; /* (b) PaX is enabled to this process */
+ u_int p_paxdebug; /* (b) PaX flags set via PTrace */
/* End area that is copied on creation. */
#define p_endcopy p_xstat
Index: sys/sys/ptrace.h
===================================================================
--- sys/sys/ptrace.h
+++ sys/sys/ptrace.h
@@ -76,6 +76,7 @@
#define PT_VM_ENTRY 41 /* Get VM map (entry) */
#define PT_FIRSTMACH 64 /* for machine-specific requests */
+#define PT_PAX 65 /* Toggle PaX-inspired hardening features */
#include <machine/ptrace.h> /* machine-specific requests, if any */
struct ptrace_io_desc {
Index: sys/sys/sysent.h
===================================================================
--- sys/sys/sysent.h
+++ sys/sys/sysent.h
@@ -38,6 +38,7 @@
struct sysent;
struct thread;
struct ksiginfo;
+struct proc;
typedef int sy_call_t(struct thread *, void *);
@@ -136,6 +137,7 @@
uint32_t sv_timekeep_gen;
void *sv_shared_page_obj;
void (*sv_schedtail)(struct thread *);
+ void (*sv_pax_aslr_init)(struct proc *);
};
#define SV_ILP32 0x000100
Index: sys/vm/vm_map.h
===================================================================
--- sys/vm/vm_map.h
+++ sys/vm/vm_map.h
@@ -241,6 +241,9 @@
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_offset_t vm_aslr_delta_mmap; /* mmap() random delta for ASLR */
+ vm_offset_t vm_aslr_delta_stack; /* stack random delta for ASLR */
+ vm_offset_t vm_aslr_delta_exec; /* exec base random delta for ASLR */
volatile 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
@@ -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>
@@ -297,6 +299,12 @@
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;
+ vm->vm_aslr_delta_exec = 0;
+#endif
+
return (vm);
}
@@ -3260,6 +3268,11 @@
vm2->vm_taddr = vm1->vm_taddr;
vm2->vm_daddr = vm1->vm_daddr;
vm2->vm_maxsaddr = vm1->vm_maxsaddr;
+#ifdef PAX_ASLR
+ vm2->vm_aslr_delta_exec = vm1->vm_aslr_delta_exec;
+ vm2->vm_aslr_delta_mmap = vm1->vm_aslr_delta_mmap;
+ vm2->vm_aslr_delta_stack = vm1->vm_aslr_delta_stack;
+#endif
vm_map_lock(old_map);
if (old_map->busy)
vm_map_wait_busy(old_map);
Index: sys/vm/vm_mmap.c
===================================================================
--- sys/vm/vm_mmap.c
+++ sys/vm/vm_mmap.c
@@ -45,6 +45,7 @@
#include "opt_compat.h"
#include "opt_hwpmc_hooks.h"
+#include "opt_pax.h"
#include "opt_vm.h"
#include <sys/param.h>
@@ -55,6 +56,7 @@
#include <sys/mutex.h>
#include <sys/sysproto.h>
#include <sys/filedesc.h>
+#include <sys/pax.h>
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/procctl.h>
@@ -440,6 +442,9 @@
td->td_fpop = fp;
maxprot &= cap_maxprot;
+#ifdef PAX_ASLR
+ pax_aslr_mmap(td->td_proc, &addr, (vm_offset_t)uap->addr, flags);
+#endif
/* This relies on VM_PROT_* matching PROT_*. */
error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
flags, handle_type, handle, pos);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Feb 4, 4:22 AM (2 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16447905
Default Alt Text
D473.diff (70 KB)
Attached To
Mode
D473: Base ASLR
Attached
Detach File
Event Timeline
Log In to Comment