summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exec.c20
-rw-r--r--sys/kern/kern_sysctl.c19
2 files changed, 33 insertions, 6 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index eaa05b0dc75..b49eb939c55 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exec.c,v 1.54 2001/06/27 04:49:41 art Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.55 2001/08/18 03:32:16 art Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
@@ -66,6 +66,15 @@
#include <machine/cpu.h>
#include <machine/reg.h>
+#include <dev/rndvar.h>
+
+/*
+ * stackgap_random specifies if the stackgap should have a random size added
+ * to it. Must be a n^2. If non-zero, the stack gap will be calculated as:
+ * (arc4random() * ALIGNBYTES) & (stackgap_random - 1) + STACKGAPLEN.
+ */
+int stackgap_random;
+
/*
* check exec:
* given an "executable" described in the exec package's namei info,
@@ -219,7 +228,7 @@ sys_execve(p, v, retval)
void *v;
register_t *retval;
{
- register struct sys_execve_args /* {
+ struct sys_execve_args /* {
syscallarg(char *) path;
syscallarg(char * *) argp;
syscallarg(char * *) envp;
@@ -232,7 +241,7 @@ sys_execve(p, v, retval)
char *argp;
char * const *cpp, *dp, *sp;
long argc, envc;
- size_t len;
+ size_t len, sgap;
#ifdef MACHINE_STACK_GROWS_UP
size_t slen;
#endif
@@ -355,9 +364,12 @@ sys_execve(p, v, retval)
szsigcode = pack.ep_emul->e_esigcode - pack.ep_emul->e_sigcode;
+ sgap = STACKGAPLEN;
+ if (stackgap_random != 0)
+ sgap += (arc4random() * ALIGNBYTES) & (stackgap_random - 1);
/* Now check if args & environ fit into new stack */
len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(char *) +
- sizeof(long) + dp + STACKGAPLEN + szsigcode +
+ sizeof(long) + dp + sgap + szsigcode +
sizeof(struct ps_strings)) - argp;
len = ALIGN(len); /* make the stack "safely" aligned */
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index d2f2b25a5de..9b642481e68 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.55 2001/07/17 20:57:49 deraadt Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.56 2001/08/18 03:32:16 art Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -230,11 +230,12 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
size_t newlen;
struct proc *p;
{
- int error, level, inthostid;
+ int error, level, inthostid, oldsgap;
extern char ostype[], osrelease[], osversion[], version[];
extern int somaxconn, sominconn;
extern int usermount, nosuidcoredump;
extern long cp_time[CPUSTATES];
+ extern int stackgap_random;
/* all sysctl names at this level are terminal */
if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF ||
@@ -394,6 +395,20 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_rdint(oldp, oldlenp, newp, nprocs));
case KERN_POOL:
return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp));
+ case KERN_STACKGAPRANDOM:
+ oldsgap = stackgap_random;
+
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap_random);
+ /*
+ * Safety harness.
+ */
+ if ((stackgap_random < ALIGNBYTES && stackgap_random != 0) ||
+ !powerof2(stackgap_random) ||
+ stackgap_random > PAGE_SIZE * 2) {
+ stackgap_random = oldsgap;
+ return (EINVAL);
+ }
+ return (error);
default:
return (EOPNOTSUPP);
}