From 33b5d96414249097847ca606a00038e6958bd871 Mon Sep 17 00:00:00 2001 From: Oliver Pinter Date: Wed, 2 Apr 2014 01:37:50 +0200 Subject: [PATCH] PAX ASLR: remove dirty hack to determine which pax_init should use probably this fixed some issue with linuxulator on amd64 bump __FreeBSD_version to 1000706 Signed-off-by: Oliver Pinter --- sys/amd64/amd64/elf_machdep.c | 10 ++++++++ sys/amd64/linux32/linux32_sysvec.c | 9 ++++++++ sys/arm/arm/elf_machdep.c | 10 ++++++++ sys/compat/ia32/ia32_sysvec.c | 9 ++++++++ sys/i386/i386/elf_machdep.c | 10 ++++++++ sys/i386/ibcs2/ibcs2_sysvec.c | 10 ++++++++ sys/i386/linux/linux_sysvec.c | 15 ++++++++++++ sys/ia64/ia64/elf_machdep.c | 11 +++++++++ sys/kern/imgact_aout.c | 14 +++++++++++ sys/kern/init_main.c | 1 + sys/kern/kern_pax.c | 46 ++++++++++++++++++++----------------- sys/mips/mips/elf_machdep.c | 15 ++++++++++++ sys/mips/mips/freebsd32_machdep.c | 9 ++++++++ sys/powerpc/powerpc/elf32_machdep.c | 10 ++++++++ sys/powerpc/powerpc/elf64_machdep.c | 10 ++++++++ sys/sparc64/sparc64/elf_machdep.c | 10 ++++++++ sys/sys/param.h | 2 +- sys/sys/pax.h | 3 +++ sys/sys/sysent.h | 3 +++ 19 files changed, 185 insertions(+), 22 deletions(-) diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index fdc4d56..ffb5e31 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -26,12 +26,17 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -81,6 +86,11 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index c06ce11..6212644 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -33,6 +33,7 @@ #include __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,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -1037,6 +1041,11 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_base = LINUX32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 6aec18b..8aca751 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -26,6 +26,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -34,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -79,6 +84,11 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; static Elf32_Brandinfo freebsd_brand_info = { diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index a8e52e8..2897328 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/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 @@ -42,6 +43,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -139,6 +143,11 @@ struct sysentvec ia32_freebsd_sysvec = { .sv_shared_page_base = FREEBSD32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec); diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index 034b4c4..f2297c8 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -26,12 +26,17 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -81,6 +86,11 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c index 5d007c7..08df5b78 100644 --- a/sys/i386/ibcs2/ibcs2_sysvec.c +++ b/sys/i386/ibcs2/ibcs2_sysvec.c @@ -31,6 +31,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -40,6 +42,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include @@ -89,6 +94,11 @@ struct sysentvec ibcs2_svr3_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = NULL, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, /* XXXOP */ +#else + .sv_pax_aslr_init = NULL, +#endif }; static int diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 0ad6791..5b14fee 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -29,6 +29,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -41,6 +43,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -974,6 +979,11 @@ struct sysentvec linux_sysvec = { .sv_shared_page_base = LINUX_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, /* XXXOP */ +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(aout_sysvec, &linux_sysvec); @@ -1012,6 +1022,11 @@ struct sysentvec elf_linux_sysvec = { .sv_shared_page_base = LINUX_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = linux_schedtail, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec); diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index 05cb641..a73f20f 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -25,12 +25,17 @@ * $FreeBSD$ */ +#include "opt_pax.h" + #include #include #include #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -86,6 +91,12 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif + }; static Elf64_Brandinfo freebsd_brand_info = { diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index 3ae78de..be699dd 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -27,6 +27,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -36,6 +38,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -99,6 +104,10 @@ struct sysentvec aout_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, /* XXXOP */ +#else + .sv_pax_aslr_init = NULL, }; #elif defined(__amd64__) @@ -143,6 +152,11 @@ struct sysentvec aout_sysvec = { .sv_set_syscall_retval = ia32_set_syscall_retval, .sv_fetch_syscall_args = ia32_fetch_syscall_args, .sv_syscallnames = freebsd32_syscallnames, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, /* XXXOP */ +#else + .sv_pax_aslr_init = NULL, +#endif }; #else #error "Port me" diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index ed343b6..369408d 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -410,6 +410,7 @@ struct sysentvec null_sysvec = { .sv_fetch_syscall_args = null_fetch_syscall_args, .sv_syscallnames = NULL, .sv_schedtail = NULL, + .sv_pax_aslr_init = NULL, }; /* diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c index b03cc03..9209038 100644 --- a/sys/kern/kern_pax.c +++ b/sys/kern/kern_pax.c @@ -30,8 +30,8 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_pax.h" #include "opt_compat.h" +#include "opt_pax.h" #include #include @@ -501,6 +501,28 @@ pax_aslr_init_prison(struct prison *pr) } void +_pax_aslr_init(struct vmspace *vm, struct prison *pr) +{ + vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), + PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); + vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), + PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); + vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); +} + +#ifdef COMPAT_FREEBSD32 +void +_pax_aslr_init32(struct vmspace *vm, struct prison *pr) +{ + vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), + PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compat_mmap_len); + vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), + PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len); + vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); +} +#endif + +void pax_aslr_init(struct thread *td, struct image_params *imgp) { struct vmspace *vm; @@ -522,27 +544,9 @@ pax_aslr_init(struct thread *td, struct image_params *imgp) vm = imgp->proc->p_vmspace; sv_flags = imgp->proc->p_sysent->sv_flags; -#ifndef COMPAT_FREEBSD32 - vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); - vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); - vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); -#else /* COMPAT_FREEBSD32 */ - if ((sv_flags & SV_LP64) != 0) { - vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_mmap_len : pax_aslr_mmap_len); - vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_stack_len : pax_aslr_stack_len); - vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); - } else { - vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_COMPAT_DELTA_MMAP_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_mmap_len : pax_aslr_compat_mmap_len); - vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), - PAX_ASLR_COMPAT_DELTA_STACK_LSB, (pr != NULL) ? pr->pr_pax_aslr_compat_stack_len : pax_aslr_compat_stack_len); - vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); + if (imgp->proc->p_sysent->sv_pax_aslr_init != NULL) { + imgp->proc->p_sysent->sv_pax_aslr_init(vm, pr); } -#endif /* !COMPAT_FREEBSD32 */ } void diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index d374713..bbf3956 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c @@ -28,6 +28,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include @@ -36,6 +38,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -83,6 +88,11 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; static Elf64_Brandinfo freebsd_brand_info = { @@ -139,6 +149,11 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, +#else + .sv_pax_aslr_init = NULL, +#endif }; static Elf32_Brandinfo freebsd_brand_info = { diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c index dfdf70f..9cfdb22 100644 --- a/sys/mips/mips/freebsd32_machdep.c +++ b/sys/mips/mips/freebsd32_machdep.c @@ -31,6 +31,7 @@ */ #include "opt_compat.h" +#include "opt_pax.h" #define __ELF_WORD_SIZE 32 @@ -42,6 +43,9 @@ #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -106,6 +110,11 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = freebsd32_syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c index dbe58df..e4ab2b9 100644 --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -25,6 +25,8 @@ * $FreeBSD$ */ +#include "opt_pax.h" + #include #include #include @@ -34,6 +36,9 @@ #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -107,6 +112,11 @@ struct sysentvec elf32_freebsd_sysvec = { .sv_shared_page_base = FREEBSD32_SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init32, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c index 0c41a8d..85b5697 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -25,12 +25,17 @@ * $FreeBSD$ */ +#include "opt_pax.h" + #include #include #include #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -83,6 +88,11 @@ struct sysentvec elf64_freebsd_sysvec = { .sv_shared_page_base = SHAREDPAGE, .sv_shared_page_len = PAGE_SIZE, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec); diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index 4d55717..b9f2be0 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -34,12 +34,17 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include #include #include #include #include #include +#ifdef PAX_ASLR +#include +#endif #include #include #include @@ -87,6 +92,11 @@ static struct sysentvec elf64_freebsd_sysvec = { .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, +#ifdef PAX_ASLR + .sv_pax_aslr_init = _pax_aslr_init, +#else + .sv_pax_aslr_init = NULL, +#endif }; static Elf64_Brandinfo freebsd_brand_info = { diff --git a/sys/sys/param.h b/sys/sys/param.h index 05b5968..ae1704a 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1000705 /* Master, propagated to newvers */ +#define __FreeBSD_version 1000706 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/pax.h b/sys/sys/pax.h index b66e68b..3ee3982 100644 --- a/sys/sys/pax.h +++ b/sys/sys/pax.h @@ -31,6 +31,7 @@ #define __SYS_PAX_H struct image_params; +struct prison; struct thread; struct vmspace; struct vm_offset_t; @@ -157,6 +158,8 @@ extern int pax_aslr_exec_len; 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 vmspace *vm, struct prison *pr); +void _pax_aslr_init32(struct vmspace *vm, struct prison *pr); 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); diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index c49db41..cfbcdc0 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -77,9 +77,11 @@ struct sysent { /* system call table */ #define SY_THR_INCR 0x8 struct image_params; +struct prison; struct __sigset; struct syscall_args; struct trapframe; +struct vmspace; struct vnode; struct sysentvec { @@ -130,6 +132,7 @@ struct sysentvec { uint32_t sv_timekeep_gen; void *sv_shared_page_obj; void (*sv_schedtail)(struct thread *); + void (*sv_pax_aslr_init)(struct vmspace *vm, struct prison *pr); }; #define SV_ILP32 0x000100 -- 1.9.0