Quick fix for locking fixes in r172250. The lock added there was per-

virtual-device, but needs to be per-physical-device so that it protects
shared data.  Usually, scp->sc->write_in_progress got corrupted first
and further corruption was limited when this variable was left at nonzero
with no write in progress.

Attempt to fix missing lock destruction in r162285.  Put it with the
lock destruction for r172250 after moving the latter.  Both might be
unreachable.

To demonstrate the bug, find a buggy syscall or sysctl that calls
printf(9) and run this often.  Run hd /dev/zero >/dev/ttyvN for any
N != 0.  The console spam goes to ttyv0 and the non-console spam goes
to ttyvN, so the lock provided no protection (but it helped for
N == 0).
This commit is contained in:
Bruce Evans 2016-08-15 12:56:45 +00:00
parent 0df377cbb8
commit 40de550ba7
2 changed files with 9 additions and 8 deletions

View File

@ -2688,13 +2688,13 @@ sc_puts(scr_stat *scp, u_char *buf, int len, int kernel)
#endif
if (scp->tsw) {
if (!kdb_active && !mtx_owned(&scp->scr_lock)) {
if (!kdb_active && !mtx_owned(&scp->sc->scr_lock)) {
need_unlock = 1;
mtx_lock_spin(&scp->scr_lock);
mtx_lock_spin(&scp->sc->scr_lock);
}
(*scp->tsw->te_puts)(scp, buf, len, kernel);
if (need_unlock)
mtx_unlock_spin(&scp->scr_lock);
mtx_unlock_spin(&scp->sc->scr_lock);
}
if (scp->sc->delayed_next_scr)
@ -2859,8 +2859,10 @@ scinit(int unit, int flags)
* disappeared...
*/
sc = sc_get_softc(unit, flags & SC_KERNEL_CONSOLE);
if ((sc->flags & SC_INIT_DONE) == 0)
if ((sc->flags & SC_INIT_DONE) == 0) {
mtx_init(&sc->scr_lock, "scrlock", NULL, MTX_SPIN);
SC_VIDEO_LOCKINIT(sc);
}
adp = NULL;
if (sc->adapter >= 0) {
@ -3077,7 +3079,8 @@ scterm(int unit, int flags)
(*scp->tsw->te_term)(scp, &scp->ts);
if (scp->ts != NULL)
free(scp->ts, M_DEVBUF);
mtx_destroy(&scp->scr_lock);
mtx_destroy(&sc->scr_lock);
mtx_destroy(&sc->video_mtx);
/* clear the structure */
if (!(flags & SC_KERNEL_CONSOLE)) {
@ -3302,8 +3305,6 @@ init_scp(sc_softc_t *sc, int vty, scr_stat *scp)
scp->history = NULL;
scp->history_pos = 0;
scp->history_size = 0;
mtx_init(&scp->scr_lock, "scrlock", NULL, MTX_SPIN);
}
int

View File

@ -230,6 +230,7 @@ typedef struct sc_softc {
char switch_in_progress;
char write_in_progress;
char blink_in_progress;
struct mtx scr_lock; /* mutex for sc_puts() */
struct mtx video_mtx;
long scrn_time_stamp;
@ -344,7 +345,6 @@ typedef struct scr_stat {
int splash_save_mode; /* saved mode for splash screen */
int splash_save_status; /* saved status for splash screen */
struct mtx scr_lock; /* mutex for sc_puts() */
#ifdef _SCR_MD_STAT_DECLARED_
scr_md_stat_t md; /* machine dependent vars */
#endif