summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2011-09-17 20:48:49 +0000
committertrasz <trasz@FreeBSD.org>2011-09-17 20:48:49 +0000
commit18eab554550b02da04c0b7662fde8622cbbc2959 (patch)
treecc926eae70d6a4a03b1a3a1ce9aad4f6e990fb01 /sys/kern
parent885c3974292380cb965fd99f2a4371e9e3225697 (diff)
downloadFreeBSD-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)
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_fork.c38
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);
OpenPOWER on IntegriCloud