From 2d8bcbd0d81f2cc8f7c89638e161fc70d307d53d Mon Sep 17 00:00:00 2001 From: Sofian Brabez Date: Tue, 29 May 2012 22:50:16 +0200 Subject: [PATCH] add kern.stackgap_random sysctl to randomize stack address --- sys/kern/kern_exec.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 4545848..3b0af25 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,8 +121,11 @@ 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, +SYSCTL_ULONG(_kern, OID_AUTO, ps_arg_cache_limit, CTLFLAG_RW, &ps_arg_cache_limit, 0, ""); static int map_at_zero = 0; @@ -129,6 +133,25 @@ TUNABLE_INT("security.bsd.map_at_zero", &map_at_zero); SYSCTL_INT(_security_bsd, OID_AUTO, map_at_zero, CTLFLAG_RW, &map_at_zero, 0, "Permit processes to map an object at virtual address 0."); +static int stackgap_random = 64 * 1024; + +static int +sysctl_kern_stackgap_random(SYSCTL_HANDLER_ARGS) +{ + int error, val; + + val = stackgap_random; + error = sysctl_handle_int(oidp, &val, sizeof(int), req); + if (error || !req->newptr) + return (error); + + if ((val < ALIGNBYTES && (val != 0)) || !powerof2(val) || val > 64 * 1024 * 1024) + return (EINVAL); + + stackgap_random = val; + return (0); +} + static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS) { @@ -1237,6 +1260,7 @@ exec_copyout_strings(imgp) struct proc *p; size_t execpath_len; int szsigcode, szps; + int sgap; char canary[sizeof(long) * 8]; szps = sizeof(pagesizes[0]) * MAXPAGESIZES; @@ -1255,7 +1279,10 @@ 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 *)) - -- 1.7.10.3