diff options
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 1c5380c40f9..ff53d3feb9a 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.120 2011/10/16 05:29:51 guenther Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.121 2011/12/11 19:42:28 guenther Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -267,6 +267,10 @@ sys_execve(struct proc *p, void *v, register_t *retval) #endif char *pathbuf = NULL; + /* get other threads to stop */ + if ((error = single_thread_set(p, SINGLE_UNWIND, 1))) + goto bad; + /* * Cheap solution to complicated problems. * Mark this process as "leave me alone, I'm execing". @@ -410,6 +414,13 @@ sys_execve(struct proc *p, void *v, register_t *retval) pack.ep_ssize = len; /* maybe should go elsewhere, but... */ /* + * we're committed: any further errors will kill the process, so + * kill the other threads now. + * XXX wait until threads are reaped to make uvmspace_exec() cheaper? + */ + single_thread_set(p, SINGLE_EXIT, 0); + + /* * Prepare vmspace for remapping. Note that uvmspace_exec can replace * p_vmspace! */ @@ -667,6 +678,7 @@ sys_execve(struct proc *p, void *v, register_t *retval) #endif atomic_clearbits_int(&p->p_flag, P_INEXEC); + single_thread_clear(p); #if NSYSTRACE > 0 if (ISSET(p->p_flag, P_SYSTRACE) && @@ -702,6 +714,7 @@ bad: clrflag: #endif atomic_clearbits_int(&p->p_flag, P_INEXEC); + single_thread_clear(p); if (pathbuf != NULL) pool_put(&namei_pool, pathbuf); |