diff options
author | 2011-12-11 19:42:28 +0000 | |
---|---|---|
committer | 2011-12-11 19:42:28 +0000 | |
commit | 2ea51a70232b4bd59dc6059ffd1585fd81f5b25c (patch) | |
tree | 3ae98b3a3baa568fbbc43945a6d3100c7aef7f94 /sys/kern/kern_exec.c | |
parent | Make the mta code a bit more straightforward: (diff) | |
download | wireguard-openbsd-2ea51a70232b4bd59dc6059ffd1585fd81f5b25c.tar.xz wireguard-openbsd-2ea51a70232b4bd59dc6059ffd1585fd81f5b25c.zip |
Suspend other rthreads before dumping core or execing; make them exit
when exec succeeds.
ok jsing@
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); |