summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbryanv <bryanv@FreeBSD.org>2013-08-17 17:02:43 +0000
committerbryanv <bryanv@FreeBSD.org>2013-08-17 17:02:43 +0000
commit1b4affdd250f5e8bf3c007e7cc9a8b5b620a3c1f (patch)
tree031e3935d014cec1e86fd81c2d7288a55eec09e1
parenta1b54d7928341f63cab51c997c014f6d55206545 (diff)
downloadFreeBSD-src-1b4affdd250f5e8bf3c007e7cc9a8b5b620a3c1f.zip
FreeBSD-src-1b4affdd250f5e8bf3c007e7cc9a8b5b620a3c1f.tar.gz
Do not use potentially stale thread in kthread_add()
When an existing process is provided, the thread selected to use to initialize the new thread could have exited and be reaped. Acquire the proc lock earlier to ensure the thread remains valid. Reviewed by: jhb, julian (previous version) MFC after: 3 days
-rw-r--r--sys/kern/kern_kthread.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index d8bbebd..969c513 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -257,18 +257,17 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p,
panic("kthread_add called too soon");
/* If no process supplied, put it on proc0 */
- if (p == NULL) {
+ if (p == NULL)
p = &proc0;
- oldtd = &thread0;
- } else {
- oldtd = FIRST_THREAD_IN_PROC(p);
- }
/* Initialize our new td */
newtd = thread_alloc(pages);
if (newtd == NULL)
return (ENOMEM);
+ PROC_LOCK(p);
+ oldtd = FIRST_THREAD_IN_PROC(p);
+
bzero(&newtd->td_startzero,
__rangeof(struct thread, td_startzero, td_endzero));
bcopy(&oldtd->td_startcopy, &newtd->td_startcopy,
@@ -292,7 +291,6 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p,
newtd->td_ucred = crhold(p->p_ucred);
/* this code almost the same as create_thread() in kern_thr.c */
- PROC_LOCK(p);
p->p_flag |= P_HADTHREADS;
thread_link(newtd, p);
thread_lock(oldtd);
OpenPOWER on IntegriCloud