summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-10-21 21:15:18 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-10-21 21:15:18 +0000
commitcea1e8acc8dffb20e9ec556ae328cb009546c31a (patch)
tree1858668edf03fba24866c9e057ded5ae45485a9d /sys/kern
parent3558c442fe2ddd5a578674559becd5bf9ee7fa1f (diff)
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')
-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;