diff options
author | trasz <trasz@FreeBSD.org> | 2011-09-17 20:48:49 +0000 |
---|---|---|
committer | trasz <trasz@FreeBSD.org> | 2011-09-17 20:48:49 +0000 |
commit | 18eab554550b02da04c0b7662fde8622cbbc2959 (patch) | |
tree | cc926eae70d6a4a03b1a3a1ce9aad4f6e990fb01 | |
parent | 885c3974292380cb965fd99f2a4371e9e3225697 (diff) | |
download | FreeBSD-src-18eab554550b02da04c0b7662fde8622cbbc2959.zip FreeBSD-src-18eab554550b02da04c0b7662fde8622cbbc2959.tar.gz |
Fix error handling bug that would prevent MAC structures from getting
freed properly if resource limit got exceeded.
Approved by: re (kib)
-rw-r--r-- | sys/kern/kern_fork.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 0a27cc0..a3634b7 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -863,11 +863,6 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, } } else vm2 = NULL; -#ifdef MAC - mac_proc_init(newproc); -#endif - knlist_init_mtx(&newproc->p_klist, &newproc->p_mtx); - STAILQ_INIT(&newproc->p_ktr); /* * XXX: This is ugly; when we copy resource usage, we need to bump @@ -884,6 +879,23 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, goto fail1; } +#ifdef RACCT + PROC_LOCK(newproc); + error = racct_add(newproc, RACCT_NPROC, 1); + error += racct_add(newproc, RACCT_NTHR, 1); + PROC_UNLOCK(newproc); + if (error != 0) { + error = EAGAIN; + goto fail1; + } +#endif + +#ifdef MAC + mac_proc_init(newproc); +#endif + knlist_init_mtx(&newproc->p_klist, &newproc->p_mtx); + STAILQ_INIT(&newproc->p_ktr); + /* We have to lock the process tree while we look for a pid. */ sx_slock(&proctree_lock); @@ -901,20 +913,6 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, goto fail; } -#ifdef RACCT - /* - * After fork, there is exactly one thread running. - */ - PROC_LOCK(newproc); - error = racct_add(newproc, RACCT_NPROC, 1); - error += racct_add(newproc, RACCT_NTHR, 1); - PROC_UNLOCK(newproc); - if (error != 0) { - error = EAGAIN; - goto fail; - } -#endif - /* * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. @@ -946,7 +944,6 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, error = EAGAIN; fail: - racct_proc_exit(newproc); sx_sunlock(&proctree_lock); if (ppsratecheck(&lastfail, &curfail, 1)) printf("maxproc limit exceeded by uid %i, please see tuning(7) and login.conf(5).\n", @@ -956,6 +953,7 @@ fail: mac_proc_destroy(newproc); #endif fail1: + racct_proc_exit(newproc); if (vm2 != NULL) vmspace_free(vm2); uma_zfree(proc_zone, newproc); |