kern/181497: ASLR Feature Request - patch included
Steven Lee
steven at roothosts.com
Sat Aug 24 21:00:01 UTC 2013
The following reply was made to PR kern/181497; it has been noted by GNATS.
From: Steven Lee <steven at roothosts.com>
To: Oliver Pinter <oliver.pntr at gmail.com>,
freebsd-gnats-submit at freebsd.org
Cc:
Subject: Re: kern/181497: ASLR Feature Request - patch included
Date: Sat, 24 Aug 2013 14:49:03 -0600
Wow... very nice. :)
On 13-08-24 07:48 AM, Oliver Pinter wrote:
> new version of the patchset:
> https://github.com/opntr/freebsd-patches-2013-tavasz/tree/master/r249952+ASLR
>
> On 8/24/13, Steven Lee <steven at roothosts.com> wrote:
>>
>>> 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 <opn at opn.(none)>
>> Date: Tue Oct 4 00:24:01 2011 +0200
>>
>> forwardport mmap-randomization patch from 7-STABLE-op
>>
>> Signed-off-by: Oliver Pinter <oliver.pntr at gmail.com>
>>
>> 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 ((val<ALIGNBYTES && (val!=0))
>> + || !powerof2(val) || val>64*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 <sys/stat.h>
>> #include <sys/sysent.h>
>> #include <sys/vmmeter.h>
>> +#include <sys/sysctl.h>
>>
>> #include <security/mac/mac_framework.h>
>>
>> @@ -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:
>> _______________________________________________
>> freebsd-bugs at freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
>> To unsubscribe, send any mail to "freebsd-bugs-unsubscribe at freebsd.org"
>>
--
Regards,
Steven Lee
More information about the freebsd-bugs
mailing list