Skip to content

Commit

Permalink
HBSD OPNsense: Separate out the ASLR code.
Browse files Browse the repository at this point in the history
On OPNsense's 16.7 roadmap is HardenedBSD's ASLR code. This commit
separates out the ASLR code from the rest of our exploit mitigation
and system hardening code.

Testing and verification still need to be performed. Initial testing
(compile + boot + `procstat -v PIDofPIEapplication) has been
performed. More thorough testing should occur.

Shared object load order randomization in the RTLD is not included in
this patch. That will be discussed with the fine folks at OPNsense at
a later time.

Since OPNsense is based on FreeBSD 10.x, this patch will need to be
backported to 10-STABLE. However, a "horizontal port" to 11-CURRENT,
which is what this commit is, needed to be done first.

Signed-off-by:	Shawn Webb <shawn.webb@hardenedbsd.org>
  • Loading branch information
lattera authored and fichtner committed May 19, 2016
1 parent e0977fd commit e13c0d4
Show file tree
Hide file tree
Showing 55 changed files with 2,259 additions and 82 deletions.
4 changes: 4 additions & 0 deletions sys/amd64/amd64/elf_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -82,6 +85,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.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);

Expand Down
2 changes: 1 addition & 1 deletion sys/amd64/amd64/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}

regs->tf_rsp = (long)sfp;
regs->tf_rip = p->p_sysent->sv_sigcode_base;
regs->tf_rip = p->p_sigcode_base;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
Expand Down
3 changes: 3 additions & 0 deletions sys/amd64/conf/GENERIC
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,6 @@ device xenpci # Xen HVM Hypervisor services driver

# VMware support
device vmx # VMware VMXNET3 Ethernet

options PAX
options PAX_ASLR
6 changes: 3 additions & 3 deletions sys/amd64/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}

regs->tf_rsp = (uintptr_t)fp;
regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode;
regs->tf_rip = p->p_ps_strings - sz_ia32_osigcode;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ds = _udatasel;
Expand Down Expand Up @@ -534,7 +534,7 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}

regs->tf_rsp = (uintptr_t)sfp;
regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode -
regs->tf_rip = p->p_sigcode_base + sz_ia32_sigcode -
sz_freebsd4_ia32_sigcode;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
Expand Down Expand Up @@ -682,7 +682,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}

regs->tf_rsp = (uintptr_t)sfp;
regs->tf_rip = p->p_sysent->sv_sigcode_base;
regs->tf_rip = p->p_sigcode_base;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
Expand Down
2 changes: 1 addition & 1 deletion sys/amd64/ia32/ia32_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ setup_lcall_gate(void)
bzero(&uap, sizeof(uap));
uap.start = 0;
uap.num = 1;
lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp;
lcall_addr = curproc->p_psstrings - sz_lcall_tramp;
bzero(&desc, sizeof(desc));
desc.sd_type = SDT_MEMERA;
desc.sd_dpl = SEL_UPL;
Expand Down
7 changes: 4 additions & 3 deletions sys/amd64/include/vmparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#define DFLSSIZ (8UL*1024*1024) /* initial stack size limit */
#endif
#ifndef MAXSSIZ
#define MAXSSIZ (512UL*1024*1024) /* max stack size */
#define MAXSSIZ (1UL*1024*1024*1024) /* max stack size */
#endif
#ifndef SGROWSIZ
#define SGROWSIZ (128UL*1024) /* amount to grow stack */
Expand Down Expand Up @@ -178,10 +178,11 @@
#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)
#define VM_MIN_ADDRESS (65536)

#define PHYS_TO_DMAP(x) ((x) | DMAP_MIN_ADDRESS)
#define DMAP_TO_PHYS(x) ((x) & ~DMAP_MIN_ADDRESS)
Expand Down
2 changes: 1 addition & 1 deletion sys/amd64/linux32/linux32_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
* mmap's return value.
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
p->p_vmspace->vm_maxsaddr = (char *)p->p_usrstack -
lim_cur(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
Expand Down
11 changes: 7 additions & 4 deletions sys/amd64/linux32/linux32_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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!"
Expand All @@ -51,6 +52,7 @@ __FBSDID("$FreeBSD$");
#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>
Expand Down Expand Up @@ -250,11 +252,11 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
struct linux32_ps_strings *arginfo;
int issetugid;

arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);

KASSERT(curthread->td_proc == imgp->proc,
("unsafe elf_linux_fixup(), should be curproc"));

arginfo = (struct linux32_ps_strings *)imgp->proc->p_psstrings;
uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
base = (Elf32_Addr *)*stack_base;
args = (Elf32_Auxargs *)imgp->auxargs;
pos = base + (imgp->args->argc + imgp->args->envc + 2);
Expand Down Expand Up @@ -869,7 +871,7 @@ linux_copyout_strings(struct image_params *imgp)
* Calculate string base and vector table pointers.
* Also deal with signal trampoline code for this exec type.
*/
arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
arginfo = (struct linux32_ps_strings *)imgp->proc->p_psstrings;
destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
roundup((ARG_MAX - imgp->args->stringspace),
sizeof(char *));
Expand Down Expand Up @@ -1039,6 +1041,7 @@ struct sysentvec elf_linux_sysvec = {
.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);

Expand Down
4 changes: 4 additions & 0 deletions sys/arm/arm/elf_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -34,6 +36,7 @@ __FBSDID("$FreeBSD$");
#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>
Expand Down Expand Up @@ -79,6 +82,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.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 = {
Expand Down
4 changes: 3 additions & 1 deletion sys/arm/arm/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

#include "opt_compat.h"
#include "opt_ddb.h"
#include "opt_pax.h"
#include "opt_platform.h"
#include "opt_sched.h"
#include "opt_timer.h"
Expand All @@ -69,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/msgbuf.h>
#include <sys/mutex.h>
#include <sys/pax.h>
#include <sys/pcpu.h>
#include <sys/ptrace.h>
#include <sys/rwlock.h>
Expand Down Expand Up @@ -278,7 +280,7 @@ sendsig(catcher, ksi, mask)
tf->tf_r5 = (register_t)&fp->sf_uc;
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));
tf->tf_usr_lr = (register_t)(p->p_psstrings - *(p->p_sysent->sv_szsigcode));

CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr,
tf->tf_usr_sp);
Expand Down
14 changes: 10 additions & 4 deletions sys/compat/freebsd32/freebsd32_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_pax.h"

#define __ELF_WORD_SIZE 32

Expand All @@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$");
#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>
Expand Down Expand Up @@ -2865,12 +2867,16 @@ freebsd32_copyout_strings(struct image_params *imgp)
execpath_len = strlen(imgp->execpath) + 1;
else
execpath_len = 0;
arginfo = (struct freebsd32_ps_strings *)curproc->p_sysent->
sv_psstrings;
if (imgp->proc->p_sysent->sv_sigcode_base == 0)
arginfo = (struct freebsd32_ps_strings *)curproc->p_psstrings;
imgp->proc->p_sigcode_base = imgp->proc->p_sysent->sv_sigcode_base;
if (imgp->proc->p_sigcode_base == 0)
szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
else
else {
szsigcode = 0;
#ifdef PAX_ASLR
pax_aslr_vdso(imgp->proc, &(imgp->proc->p_sigcode_base));
#endif
}
destp = (uintptr_t)arginfo;

/*
Expand Down
3 changes: 3 additions & 0 deletions sys/compat/ia32/ia32_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$");

#include "opt_compat.h"
#include "opt_pax.h"

#define __ELF_WORD_SIZE 32

Expand All @@ -42,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/mman.h>
#include <sys/namei.h>
#include <sys/pax.h>
#include <sys/pioctl.h>
#include <sys/proc.h>
#include <sys/procfs.h>
Expand Down Expand Up @@ -139,6 +141,7 @@ struct sysentvec ia32_freebsd_sysvec = {
.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);

Expand Down
5 changes: 5 additions & 0 deletions sys/conf/NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -2993,3 +2993,8 @@ options RANDOM_RWFILE # Read and write entropy cache

# Intel em(4) driver
options EM_MULTIQUEUE # Activate multiqueue features/disable MSI-X

# PAX and HardenedBSD related knobs
options PAX
options PAX_ASLR
options PAX_SYSCTLS
4 changes: 4 additions & 0 deletions sys/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -2957,6 +2957,10 @@ gnu/fs/reiserfs/reiserfs_stree.c optional reiserfs
gnu/fs/reiserfs/reiserfs_vfsops.c optional reiserfs
gnu/fs/reiserfs/reiserfs_vnops.c optional reiserfs
#
hardenedbsd/hbsd_pax_common.c optional pax
hardenedbsd/hbsd_pax_log.c optional pax
hardenedbsd/hbsd_pax_aslr.c optional pax pax_aslr
#
isa/isa_if.m standard
isa/isa_common.c optional isa
isa/isahint.c optional isa
Expand Down
15 changes: 15 additions & 0 deletions sys/conf/options
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,21 @@ RACCT_DEFAULT_TO_DISABLED opt_global.h
# Resource Limits
RCTL opt_global.h

# PaX-inspired hardening features
PAX opt_pax.h
PAX_ASLR opt_pax.h
PAX_SYSCTLS opt_pax.h

# ASLR overwritable defaults
PAX_ASLR_DELTA_MMAP_DEF_LEN opt_pax.h
PAX_ASLR_DELTA_STACK_DEF_LEN opt_pax.h
PAX_ASLR_DELTA_VDSO_DEF_LEN opt_pax.h
PAX_ASLR_DELTA_EXEC_DEF_LEN opt_pax.h
PAX_ASLR_COMPAT_DELTA_MMAP_DEF_LEN opt_pax.h
PAX_ASLR_COMPAT_DELTA_STACK_DEF_LEN opt_pax.h
PAX_ASLR_COMPAT_DELTA_EXEC_DEF_LEN opt_pax.h
PAX_ASLR_COMPAT_DELTA_VDSO_DEF_LEN opt_pax.h

# Random number generator(s)
RANDOM_YARROW opt_random.h
RANDOM_FORTUNA opt_random.h
Expand Down
6 changes: 6 additions & 0 deletions sys/conf/options.amd64
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,9 @@ HYPERV opt_global.h

# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h

# HardenedBSD ASLR options
PAX_ASLR_DELTA_MAP32BIT_DEF_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_MIN_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_MAX_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_LSB opt_pax.h
6 changes: 6 additions & 0 deletions sys/conf/options.sparc64
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ SCHIZO_DEBUG opt_schizo.h

SUNKBD_DFLT_KEYMAP opt_sunkbd.h
SUNKBD_EMULATE_ATKBD opt_sunkbd.h

# HardenedBSD ASLR options
PAX_ASLR_DELTA_MAP32BIT_DEF_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_MIN_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_MAX_LEN opt_pax.h
PAX_ASLR_DELTA_MAP32BIT_LSB opt_pax.h
9 changes: 9 additions & 0 deletions sys/ddb/db_ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include "opt_pax.h"

#include <sys/param.h>
#include <sys/cons.h>
#include <sys/jail.h>
#include <sys/kdb.h>
#include <sys/pax.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -316,6 +319,9 @@ DB_SHOW_COMMAND(thread, db_show_thread)
(void *)(td->td_kstack + td->td_kstack_pages * PAGE_SIZE - 1));
db_printf(" flags: %#x ", td->td_flags);
db_printf(" pflags: %#x\n", td->td_pflags);
#ifdef PAX
pax_db_printf_flags_td(td, PAX_LOG_DEFAULT);
#endif
db_printf(" state: ");
switch (td->td_state) {
case TDS_INACTIVE:
Expand Down Expand Up @@ -423,6 +429,9 @@ DB_SHOW_COMMAND(proc, db_show_proc)
if (p->p_args != NULL)
db_printf(" arguments: %.*s\n", (int)p->p_args->ar_length,
p->p_args->ar_args);
#ifdef PAX
pax_db_printf_flags(p, PAX_LOG_DEFAULT);
#endif
db_printf(" threads: %d\n", p->p_numthreads);
FOREACH_THREAD_IN_PROC(p, td) {
dumpthread(p, td, 1);
Expand Down
Loading

0 comments on commit e13c0d4

Please sign in to comment.