diff options
author | phk <phk@FreeBSD.org> | 2005-03-17 08:44:41 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2005-03-17 08:44:41 +0000 |
commit | d6c8765efc947151e1249f9407fd0efd6bdee75f (patch) | |
tree | 30127f90b85ee3d8ac2133807d20b6b432480798 /sys/kern | |
parent | 5deecb8ce75ed6db68309784b436bf6aac0e5ef4 (diff) | |
download | FreeBSD-src-d6c8765efc947151e1249f9407fd0efd6bdee75f.zip FreeBSD-src-d6c8765efc947151e1249f9407fd0efd6bdee75f.tar.gz |
In stange circumstances we may end up being the last reference to a
session in tprintf(). SESSRELE() needs to properly dispose of the
sessions mutex.
Add sessrele() which does the proper cleanup and have SESSRELE() call it.
Use SESSRELE also in pgdelete().
Found by: Coverity (ID:526)
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_proc.c | 27 | ||||
-rw-r--r-- | sys/kern/subr_prf.c | 5 |
2 files changed, 18 insertions, 14 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 2e74cc3..0924325 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -429,7 +429,6 @@ pgdelete(pgrp) register struct pgrp *pgrp; { struct session *savesess; - int i; sx_assert(&proctree_lock, SX_XLOCKED); PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); @@ -447,16 +446,8 @@ pgdelete(pgrp) pgrp->pg_session->s_ttyp->t_pgrp = NULL; LIST_REMOVE(pgrp, pg_hash); savesess = pgrp->pg_session; - SESS_LOCK(savesess); - i = --savesess->s_count; - SESS_UNLOCK(savesess); + SESSRELE(savesess); PGRP_UNLOCK(pgrp); - if (i == 0) { - if (savesess->s_ttyp != NULL) - ttyrel(savesess->s_ttyp); - mtx_destroy(&savesess->s_mtx); - FREE(savesess, M_SESSION); - } mtx_destroy(&pgrp->pg_mtx); FREE(pgrp, M_PGRP); } @@ -560,6 +551,22 @@ orphanpg(pg) } } +void +sessrele(struct session *s) +{ + int i; + + SESS_LOCK(s); + i = --s->s_count; + SESS_UNLOCK(s); + if (i == 0) { + if (s->s_ttyp != NULL) + ttyrel(s->s_ttyp); + mtx_destroy(&s->s_mtx); + FREE(s, M_SESSION); + } +} + #include "opt_ddb.h" #ifdef DDB #include <ddb/ddb.h> diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 393906f..26d4d41 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -189,11 +189,8 @@ tprintf(struct proc *p, int pri, const char *fmt, ...) va_start(ap, fmt); kvprintf(fmt, putchar, &pca, 10, ap); va_end(ap); - if (sess != NULL) { - SESS_LOCK(sess); + if (sess != NULL) SESSRELE(sess); - SESS_UNLOCK(sess); - } msgbuftrigger = 1; } |