summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorart <art@openbsd.org>2002-10-21 21:15:17 +0000
committerart <art@openbsd.org>2002-10-21 21:15:17 +0000
commit0c877b1e6e54db3ef79e89544a7ed7830a20dfbe (patch)
tree7f25ac6f38629cfaccbf1988817f3aa212acd405 /sys/kern/kern_fork.c
parentforgot dpadd (diff)
downloadwireguard-openbsd-0c877b1e6e54db3ef79e89544a7ed7830a20dfbe.tar.xz
wireguard-openbsd-0c877b1e6e54db3ef79e89544a7ed7830a20dfbe.zip
Two problems.
First we check for running out of processes (nprocs variable) before we continue with the fork, then we do various calls that might sleep (and allow other forks to start and pass that check), then we increase that variable. This could allow processes to be created past the limit. Second is that we don't decrease the the process count for this uid if the stack allocation fails. So a user could run out of processes he's allowed to run without actually having them. miod@ ok
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index adc491b5fc2..7682b5d3abc 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.55 2002/05/16 16:16:51 provos Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.56 2002/10/21 21:15:17 art Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -168,6 +168,7 @@ fork1(p1, exitsig, flags, stack, stacksize, func, arg, retval)
tablefull("proc");
return (EAGAIN);
}
+ nprocs++;
/*
* Increment the count of procs running with this uid. Don't allow
@@ -176,15 +177,23 @@ fork1(p1, exitsig, flags, stack, stacksize, func, arg, retval)
count = chgproccnt(uid, 1);
if (uid != 0 && count > p1->p_rlimit[RLIMIT_NPROC].rlim_cur) {
(void)chgproccnt(uid, -1);
+ nprocs--;
return (EAGAIN);
}
/*
* Allocate a pcb and kernel stack for the process
*/
- uaddr = uvm_km_valloc(kernel_map, USPACE);
- if (uaddr == 0)
- return ENOMEM;
+ uaddr = uvm_km_valloc_noexec(kernel_map, USPACE);
+ if (uaddr == 0) {
+ chgproccnt(uid, -1);
+ nprocs--;
+ return (ENOMEM);
+ }
+
+ /*
+ * From now on, we're comitted to the fork and cannot fail.
+ */
/* Allocate new proc. */
newproc = pool_get(&proc_pool, PR_WAITOK);
@@ -194,7 +203,6 @@ fork1(p1, exitsig, flags, stack, stacksize, func, arg, retval)
lastpid = 1 + (randompid ? arc4random() : lastpid) % PID_MAX;
} while (pidtaken(lastpid));
- nprocs++;
p2 = newproc;
p2->p_stat = SIDL; /* protect against others */
p2->p_pid = lastpid;