aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>2004-09-21 21:05:13 +0000
committerJulian Elischer <julian@FreeBSD.org>2004-09-21 21:05:13 +0000
commit297800599a494e589a2c90fb8b7b21a149cc6481 (patch)
tree0d614b0d2d633d3f962a8393348b6913d1cd260d
parentaa1cb3e183ec2d625fa51f040a0154506a406dc4 (diff)
downloadsrc-297800599a494e589a2c90fb8b7b21a149cc6481.tar.gz
src-297800599a494e589a2c90fb8b7b21a149cc6481.zip
In a threaded process, don't kill off all the other threads until we have a
reasonable chance that the eceve() is going to succeeed. I.e. wait until we've done the permission checks etc. MFC after: 1 week
Notes
Notes: svn path=/head/; revision=135552
-rw-r--r--sys/kern/kern_exec.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 1a79f48a3273..16dd5e62042d 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -254,17 +254,6 @@ kern_execve(td, fname, argv, envv, mac_p)
PROC_LOCK(p);
KASSERT((p->p_flag & P_INEXEC) == 0,
("%s(): process already has P_INEXEC flag", __func__));
- if (p->p_flag & P_HADTHREADS) {
- if (thread_single(SINGLE_EXIT)) {
- PROC_UNLOCK(p);
- mtx_unlock(&Giant);
- return (ERESTART); /* Try again later. */
- }
- /*
- * If we get here all other threads are dead,
- * and threading mode has been turned off
- */
- }
p->p_flag |= P_INEXEC;
PROC_UNLOCK(p);
@@ -356,6 +345,23 @@ interpret:
if (error)
goto exec_fail_dealloc;
+ PROC_LOCK(p);
+ if (p->p_flag & P_HADTHREADS) {
+ if (thread_single(SINGLE_EXIT)) {
+ PROC_UNLOCK(p);
+ error = ERESTART;
+ goto exec_fail_dealloc;
+ }
+ /*
+ * If we get here all other threads are dead,
+ * and threading mode has been turned off.
+ * Returning to the user from this point on
+ * may confuse the thread library as some threads
+ * will have just "died".
+ */
+ }
+ PROC_UNLOCK(p);
+
/*
* If the current process has a special image activator it
* wants to try first, call it. For example, emulating shell