From owner-freebsd-bugs@FreeBSD.ORG Sat Aug 24 02:20:00 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 9B672692 for ; Sat, 24 Aug 2013 02:20:00 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 7BEBE2359 for ; Sat, 24 Aug 2013 02:20:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r7O2K0JN033214 for ; Sat, 24 Aug 2013 02:20:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r7O2K0Mt033213; Sat, 24 Aug 2013 02:20:00 GMT (envelope-from gnats) Resent-Date: Sat, 24 Aug 2013 02:20:00 GMT Resent-Message-Id: <201308240220.r7O2K0Mt033213@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Steven Lee Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id D19C165E for ; Sat, 24 Aug 2013 02:15:41 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id AF872233C for ; Sat, 24 Aug 2013 02:15:41 +0000 (UTC) Received: from oldred.freebsd.org ([127.0.1.6]) by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r7O2FfEn009157 for ; Sat, 24 Aug 2013 02:15:41 GMT (envelope-from nobody@oldred.freebsd.org) Received: (from nobody@localhost) by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r7O2Ff2o009155; Sat, 24 Aug 2013 02:15:41 GMT (envelope-from nobody) Message-Id: <201308240215.r7O2Ff2o009155@oldred.freebsd.org> Date: Sat, 24 Aug 2013 02:15:41 GMT From: Steven Lee To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: kern/181497: ASLR Feature Request - patch included X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 24 Aug 2013 02:20:00 -0000 >Number: 181497 >Category: kern >Synopsis: ASLR Feature Request - patch included >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sat Aug 24 02:20:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Steven Lee >Release: releng/9.2 >Organization: Root Hosts >Environment: N/A >Description: Most modern operating systems have ASLR to help mitigate yet-unknown vulnerabilities. It would be very nice if FreeBSD shipped with ASLR features in the kernel (default off), that could be easily switched on with a sysctl variable. I understand that in some production environments ASLR may make a system slower through memory fragmentation, but at least give people the option to turn ASLR on for those who actually want it. :) >How-To-Repeat: N/A >Fix: This patch has been circulating the internet since FreeBSD 7.0-RELEASE at least. It looks like parts of it are from OpenBSD? (I could be wrong.) I've used it in production for many many years and it works like a champ. The patch will just need the sysctl defaults inverted and the variable names possibly renamed for clarity. Patch attached with submission follows: commit 779a962519e7ead63dda24348b98f6cde8156752 Author: Oliver Pinter Date: Tue Oct 4 00:24:01 2011 +0200 forwardport mmap-randomization patch from 7-STABLE-op Signed-off-by: Oliver Pinter diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index fe01142..dc66db6 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -106,6 +106,7 @@ MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS); static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS); static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS); +static int sysctl_kern_stackgap_random(SYSCTL_HANDLER_ARGS); static int do_execve(struct thread *td, struct image_args *args, struct mac *mac_p); @@ -120,6 +121,9 @@ SYSCTL_PROC(_kern, KERN_USRSTACK, usrstack, CTLTYPE_ULONG|CTLFLAG_RD| SYSCTL_PROC(_kern, OID_AUTO, stackprot, CTLTYPE_INT|CTLFLAG_RD, NULL, 0, sysctl_kern_stackprot, "I", ""); +SYSCTL_PROC(_kern, OID_AUTO, stackgap_random, CTLTYPE_INT|CTLFLAG_RW, + NULL, 0, sysctl_kern_stackgap_random, "I", "stackgap maximum offset"); + u_long ps_arg_cache_limit = PAGE_SIZE / 16; SYSCTL_ULONG(_kern, OID_AUTO, ps_arg_cache_limit, CTLFLAG_RW, &ps_arg_cache_limit, 0, ""); @@ -177,6 +181,30 @@ sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS) sizeof(p->p_sysent->sv_stackprot))); } +static int stackgap_random = 64 * 1024; + +static int +sysctl_kern_stackgap_random(SYSCTL_HANDLER_ARGS) +{ + int err; + int val; + + val=stackgap_random; + err=sysctl_handle_int(oidp, &val, sizeof(int), req); + if (err || !req->newptr) { + return (err); + } + + if ((val64*1024*1024) { + return (EINVAL); + } + + stackgap_random=val; + + return (0); +} + /* * Each of the items is a pointer to a `const struct execsw', hence the * double pointer here. @@ -1248,6 +1276,7 @@ exec_copyout_strings(imgp) size_t execpath_len; int szsigcode, szps; char canary[sizeof(long) * 8]; + int sgap; szps = sizeof(pagesizes[0]) * MAXPAGESIZES; /* @@ -1265,7 +1294,11 @@ exec_copyout_strings(imgp) if (p->p_sysent->sv_szsigcode != NULL) szsigcode = *(p->p_sysent->sv_szsigcode); } - destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - + sgap=0; + if (stackgap_random!=0) { + sgap=ALIGN(arc4random()&(stackgap_random-1)); + } + destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - sgap - roundup(execpath_len, sizeof(char *)) - roundup(sizeof(canary), sizeof(char *)) - roundup(szps, sizeof(char *)) - diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index e85b681..991a37d 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -99,6 +100,10 @@ static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, static int vm_mmap_shm(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, int *, struct shmfd *, vm_ooffset_t, vm_object_t *); +static int mmap_random=1; +SYSCTL_INT(_vm, OID_AUTO, mmap_random, CTLFLAG_RW, &mmap_random, 0, + "random mmap offset"); + /* * MPSAFE */ @@ -256,7 +261,8 @@ sys_mmap(td, uap) /* * XXX for non-fixed mappings where no hint is provided or * the hint would fall in the potential heap space, - * place it after the end of the largest possible heap. + * place it after the end of the largest possible heap, + * plus a random offset, if mmap_random is set. * * There should really be a pmap call to determine a reasonable * location. @@ -265,9 +271,13 @@ sys_mmap(td, uap) if (addr == 0 || (addr >= round_page((vm_offset_t)vms->vm_taddr) && addr < round_page((vm_offset_t)vms->vm_daddr + - lim_max(td->td_proc, RLIMIT_DATA)))) + lim_max(td->td_proc, RLIMIT_DATA)))) { addr = round_page((vm_offset_t)vms->vm_daddr + lim_max(td->td_proc, RLIMIT_DATA)); + if (mmap_random) { + addr+=arc4random()&(256*1024*1024-1); + } + } PROC_UNLOCK(td->td_proc); } if (flags & MAP_ANON) { >Release-Note: >Audit-Trail: >Unformatted: