diff options
author | tanimura <tanimura@FreeBSD.org> | 2002-05-03 05:32:25 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2002-05-03 05:32:25 +0000 |
commit | 58f1f5c532ae9a81c60b6a1a7e54ad895e064a72 (patch) | |
tree | 5b920d700adbb2e0fafe50281dbb6710febcf995 /sys | |
parent | 20d0f94ddc7dea6947e89c901881ab755ae32d34 (diff) | |
download | FreeBSD-src-58f1f5c532ae9a81c60b6a1a7e54ad895e064a72.zip FreeBSD-src-58f1f5c532ae9a81c60b6a1a7e54ad895e064a72.tar.gz |
Fix the lock order reversal between the sigio lock and a process/pgrp lock in
funsetownlst() by locking the sigio lock across funsetownlst().
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_descrip.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 2 |
3 files changed, 10 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 425cb39..9e9f1de 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -571,6 +571,8 @@ funsetownlst(sigiolst) struct proc *p; struct pgrp *pg; + SIGIO_ASSERT(MA_OWNED); + sigio = SLIST_FIRST(sigiolst); if (sigio == NULL) return; @@ -591,28 +593,30 @@ funsetownlst(sigiolst) } while ((sigio = SLIST_FIRST(sigiolst)) != NULL) { - SIGIO_LOCK(); *(sigio->sio_myref) = NULL; - SIGIO_UNLOCK(); if (pg != NULL) { KASSERT(sigio->sio_pgid < 0, ("Proc sigio in pgrp sigio list")); KASSERT(sigio->sio_pgrp == pg, ("Bogus pgrp in sigio list")); SLIST_REMOVE(&pg->pg_sigiolst, sigio, sigio, sio_pgsigio); PGRP_UNLOCK(pg); + SIGIO_UNLOCK(); crfree(sigio->sio_ucred); mtx_lock(&Giant); FREE(sigio, M_SIGIO); mtx_unlock(&Giant); + SIGIO_LOCK(); PGRP_LOCK(pg); } else /* if (p != NULL) */ { KASSERT(sigio->sio_pgid > 0, ("Pgrp sigio in proc sigio list")); KASSERT(sigio->sio_proc == p, ("Bogus proc in sigio list")); SLIST_REMOVE(&p->p_sigiolst, sigio, sigio, sio_pgsigio); PROC_UNLOCK(p); + SIGIO_UNLOCK(); crfree(sigio->sio_ucred); mtx_lock(&Giant); FREE(sigio, M_SIGIO); mtx_unlock(&Giant); + SIGIO_LOCK(); PROC_LOCK(p); } } diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 2927647..ed6b6f0 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -191,9 +191,11 @@ exit1(td, rv) * Reset any sigio structures pointing to us as a result of * F_SETOWN with our pid. */ + SIGIO_LOCK(); PROC_LOCK(p); funsetownlst(&p->p_sigiolst); PROC_UNLOCK(p); + SIGIO_UNLOCK(); /* * Close open files and release open-file table. diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 7561e60..d68c02e 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -474,6 +474,7 @@ pgdelete(pgrp) PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); + SIGIO_LOCK(); PGRP_LOCK(pgrp); /* @@ -481,6 +482,7 @@ pgdelete(pgrp) * F_SETOWN with our pgid. */ funsetownlst(&pgrp->pg_sigiolst); + SIGIO_UNLOCK(); if (pgrp->pg_session->s_ttyp != NULL && pgrp->pg_session->s_ttyp->t_pgrp == pgrp) |