From cea1e8acc8dffb20e9ec556ae328cb009546c31a Mon Sep 17 00:00:00 2001 From: Artur Grabowski Date: Mon, 21 Oct 2002 21:15:18 +0000 Subject: 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 --- sys/kern/kern_fork.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sys/kern') 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; -- cgit v1.2.3