diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-10-21 21:15:18 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-10-21 21:15:18 +0000 |
commit | cea1e8acc8dffb20e9ec556ae328cb009546c31a (patch) | |
tree | 1858668edf03fba24866c9e057ded5ae45485a9d /sys/kern | |
parent | 3558c442fe2ddd5a578674559becd5bf9ee7fa1f (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.c | 18 |
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; |