DragonFly BSD
DragonFly submit List (threaded) for 2005-06
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Stackgap support


From: Craig Dooley <xlnxminusx@xxxxxxxxx>
Date: Wed, 22 Jun 2005 09:05:12 -0400

This patch adds support for adding a random padding to the top of the
user stack on process creation.  It is based off the OpenBSD
implementation.  I have been testing this for about a day and it has
not caused any problems.  It should also waste at most 1 physical page
per process (someone correct me if I'm wrong).

-Craig
-- 
-----------------------------------------------------------------------
Craig Dooley <xlnxminusx@xxxxxxxxx>
Index: kern/kern_exec.c
===================================================================
RCS file: /home/dcvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.32
diff -u -r1.32 kern_exec.c
--- kern/kern_exec.c	20 Apr 2005 16:37:09 -0000	1.32
+++ kern/kern_exec.c	22 Jun 2005 08:57:46 -0000
@@ -52,6 +52,7 @@
 #include <sys/vnode.h>
 #include <sys/vmmeter.h>
 #include <sys/aio.h>
+#include <sys/libkern.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -93,6 +94,30 @@
 SYSCTL_INT(_kern, OID_AUTO, debug_execve_args, CTLFLAG_RW, &debug_execve_args,
     0, "");
 
+/*
+ * stackgap_random specifies if the stackgap should have a random size added
+ * to it.  It must be a power of 2.  If non-zero, the stack gap will be 
+ * calculated as: (ALIGN(arc4random()) & (stackgap_random - 1) + STACKGAPLEN.
+ */
+static int stackgap_random = 1024;
+static int
+sysctl_kern_stackgap(SYSCTL_HANDLER_ARGS)
+{
+	int error, new_val;
+	new_val = stackgap_random;
+	error = sysctl_handle_int(oidp, &new_val, 0, req);
+	if (error != 0 || req->newptr == NULL)
+		return (error);
+	if ((new_val < 0) || (new_val > 16 * PAGE_SIZE) || ! powerof2(new_val))
+		return (EINVAL);
+	stackgap_random = new_val;
+
+	return(0);
+}
+
+SYSCTL_PROC(_kern, OID_AUTO, stackgap_random, CTLFLAG_RW|CTLTYPE_UINT, 
+	0, 0, sysctl_kern_stackgap, "IU", "Max random stack gap (power of 2)");
+	
 void
 print_execve_args(struct image_args *args)
 {
@@ -771,7 +796,7 @@
 register_t *
 exec_copyout_strings(struct image_params *imgp)
 {
-	int argc, envc;
+	int argc, envc, sgap = 0;
 	char **vectp;
 	char *stringp, *destp;
 	register_t *stack_base;
@@ -784,7 +809,9 @@
 	 */
 	arginfo = (struct ps_strings *)PS_STRINGS;
 	szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
-	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+	if (stackgap_random != 0)
+		sgap += (ALIGN(arc4random())) & (stackgap_random - 1);
+	destp =	(caddr_t)arginfo - szsigcode - SPARE_USRSPACE - sgap -
 	    roundup((ARG_MAX - imgp->args->space), sizeof(char *));
 
 	/*


[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]