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)
This commit is contained in:
parent
0e41462ff3
commit
572b4402d1
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -714,10 +714,8 @@ MALLOC_DECLARE(M_ZOMBIE);
|
||||
|
||||
#define SESS_LEADER(p) ((p)->p_session->s_leader == (p))
|
||||
#define SESSHOLD(s) ((s)->s_count++)
|
||||
#define SESSRELE(s) { \
|
||||
if (--(s)->s_count == 0) \
|
||||
FREE(s, M_SESSION); \
|
||||
}
|
||||
#define SESSRELE(s) sessrele(s)
|
||||
|
||||
|
||||
#define STOPEVENT(p, e, v) do { \
|
||||
if ((p)->p_stops & (e)) { \
|
||||
@ -860,6 +858,7 @@ void pstats_fork(struct pstats *src, struct pstats *dst);
|
||||
void pstats_free(struct pstats *ps);
|
||||
int securelevel_ge(struct ucred *cr, int level);
|
||||
int securelevel_gt(struct ucred *cr, int level);
|
||||
void sessrele(struct session *);
|
||||
void setrunnable(struct thread *);
|
||||
void setrunqueue(struct thread *, int flags);
|
||||
void setsugid(struct proc *p);
|
||||
|
Loading…
Reference in New Issue
Block a user