On 11/15/11, Jeremie Le Hen <jere...@le-hen.org> wrote:
> Hi,
>
> On Wed, Oct 19, 2011 at 12:37:44AM +0200, Oliver Pinter wrote:
>> In NetBSD has been some PaX feature [0] implemented. (ASLR, W^X
>> (~nxstack), mprotect restriction, veriexec, mmap randomization[2]...)
>>
>> [0] http://pax.grsecurity.net/docs/index.html
>> [1] http://www.netbsd.org/~elad/recent/man/security.8.html
>> [2] http://people.freebsd.org/~ssouhlal/testing/stackgap-20050527.diff
>
> Suleiman actually wrought two patches, one randomizing the stack (the
> one you pointed out) and another one randomizing non-fixed mmap(2)
> calls:
>
> http://people.freebsd.org/~ssouhlal/testing/mmap_random-20050528.diff
>
>
> FYI, they do not apply cleanly on recent source trees (the patches were
> made in 2005), but they can be applied with little fiddling.  I'm
> running multiple 8.x production machines with them without any problem.

Yeah, I use thins patch in 7-STABLE and 9-STABLE too.
Patch for 9-STABLE has attached.



>
> I've always wanted them to be committed as opt-in knobs, but I can't
> remember why they hadn't at the time.
>
> Cheers,
> --
> Jeremie Le Hen
>
> Men are born free and equal.  Later on, they're on their own.
>                               Jean Yanne
>
commit 779a962519e7ead63dda24348b98f6cde8156752
Author: Oliver Pinter <opn@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.p...@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) {
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to