From 88481e0aaad885c4533760ba195fdcdd9787fbc8 Mon Sep 17 00:00:00 2001 From: khorben Date: Sun, 20 Mar 2016 14:58:10 +0000 Subject: [PATCH] Let PaX ASLR know about the current emulation This effectively fixes PaX ASLR with 32-bits emulation on 64-bits platforms. Without this knowledge, the offset applied for 32-bits programs was really meant for a 64-bits address space - thus shifting the address up to 12 bits, with a success rate of about 1/4096. This offset is calculated once in the lifetime of the process, which therefore behaved normally when able to start. Fixes kern/50469, probably also kern/50986 Tested on NetBSD/amd64 (emul_netbsd32) --- sys/kern/kern_exec.c | 6 +++--- sys/kern/kern_pax.c | 16 +++++++++++----- sys/sys/pax.h | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index bbe88aa6d624..42b432113a1f 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.423 2015/11/30 22:47:19 pgoyette Exp $ */ +/* $NetBSD: kern_exec.c,v 1.424 2016/03/20 14:58:10 khorben Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.423 2015/11/30 22:47:19 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.424 2016/03/20 14:58:10 khorben Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -1160,7 +1160,7 @@ execve_runproc(struct lwp *l, struct execve_data * restrict data, vm->vm_minsaddr = (void *)epp->ep_minsaddr; #ifdef PAX_ASLR - pax_aslr_init_vm(l, vm); + pax_aslr_init_vm(l, vm, epp); #endif /* PAX_ASLR */ /* Now map address space. */ diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c index e31f9604fa9e..546cab71866d 100644 --- a/sys/kern/kern_pax.c +++ b/sys/kern/kern_pax.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_pax.c,v 1.34 2016/03/19 18:56:37 christos Exp $ */ +/* $NetBSD: kern_pax.c,v 1.35 2016/03/20 14:58:10 khorben Exp $ */ /* * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.34 2016/03/19 18:56:37 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.35 2016/03/20 14:58:10 khorben Exp $"); #include "opt_pax.h" @@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.34 2016/03/19 18:56:37 christos Exp $ #ifdef PAX_ASLR #include +#include int pax_aslr_enabled = 1; int pax_aslr_global = PAX_ASLR; @@ -399,13 +400,18 @@ pax_aslr_active(struct lwp *l) } void -pax_aslr_init_vm(struct lwp *l, struct vmspace *vm) +pax_aslr_init_vm(struct lwp *l, struct vmspace *vm, struct exec_package *ep) { if (!pax_aslr_active(l)) return; - vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(cprng_fast32(), - PAX_ASLR_DELTA_MMAP_LSB, PAX_ASLR_DELTA_MMAP_LEN); + if (ep->ep_flags & EXEC_32) + vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(cprng_fast32(), + PAX_ASLR_DELTA_MMAP_LSB, + (sizeof(netbsd32_pointer_t) * NBBY) / 2); + else + vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(cprng_fast32(), + PAX_ASLR_DELTA_MMAP_LSB, PAX_ASLR_DELTA_MMAP_LEN); PAX_DPRINTF("delta_mmap=%#jx", vm->vm_aslr_delta_mmap); } diff --git a/sys/sys/pax.h b/sys/sys/pax.h index 864169aea028..370f282770fb 100644 --- a/sys/sys/pax.h +++ b/sys/sys/pax.h @@ -1,4 +1,4 @@ -/* $NetBSD: pax.h,v 1.17 2016/03/19 18:56:37 christos Exp $ */ +/* $NetBSD: pax.h,v 1.18 2016/03/20 14:58:11 khorben Exp $ */ /*- * Copyright (c) 2006 Elad Efrat @@ -62,7 +62,7 @@ int pax_segvguard(struct lwp *, struct vnode *, const char *, bool); bool pax_aslr_epp_active(struct exec_package *); bool pax_aslr_active(struct lwp *); -void pax_aslr_init_vm(struct lwp *, struct vmspace *); +void pax_aslr_init_vm(struct lwp *, struct vmspace *, struct exec_package *); void pax_aslr_stack(struct exec_package *, u_long *); void pax_aslr_mmap(struct lwp *, vaddr_t *, vaddr_t, int);