diff options
author | kib <kib@FreeBSD.org> | 2008-05-23 16:47:55 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-05-23 16:47:55 +0000 |
commit | 797c3188c07ea75e3dec375470a12724a500a856 (patch) | |
tree | 0e4cb5c91c1a42033c1b2fa3ee7b7d3b5bfaf5fb /sys | |
parent | 90775e30dbdf185e0d078b6b11fbf16866097173 (diff) | |
download | FreeBSD-src-797c3188c07ea75e3dec375470a12724a500a856.zip FreeBSD-src-797c3188c07ea75e3dec375470a12724a500a856.tar.gz |
Rev. 1.274 put the ttyrel() call before the destroy_dev() in the
ttyfree(), freeing the tty. Since destroy_dev() may call d_purge()
cdevsw method, that is the ttypurge() for the tty, the code ends up
accessing freed tty structure.
Put the ttyrel() after destroy_dev() in the ttyfree. To prevent the
panic the rev. 1.274 provided fix for, check the TS_GONE in sysctl
handler and refuse to provide information on such tty.
Reported, debugging help and tested by: pho
DIscussed with and reviewed by: jhb
MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/tty.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 8d26f1c..513ba3f 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -3057,9 +3057,10 @@ ttyfree(struct tty *tp) ttygone(tp); unit = tp->t_devunit; dev = tp->t_mdev; + dev->si_tty = NULL; tp->t_dev = NULL; - ttyrel(tp); destroy_dev(dev); + ttyrel(tp); free_unr(tty_unit, unit); } @@ -3076,6 +3077,8 @@ sysctl_kern_ttys(SYSCTL_HANDLER_ARGS) if (tp != NULL) ttyref(tp); while (tp != NULL) { + if (tp->t_state & TS_GONE) + goto nexttp; bzero(&xt, sizeof xt); xt.xt_size = sizeof xt; #define XT_COPY(field) xt.xt_##field = tp->t_##field @@ -3124,7 +3127,7 @@ sysctl_kern_ttys(SYSCTL_HANDLER_ARGS) return (error); } mtx_lock(&tty_list_mutex); - tp2 = TAILQ_NEXT(tp, t_list); +nexttp: tp2 = TAILQ_NEXT(tp, t_list); if (tp2 != NULL) ttyref(tp2); mtx_unlock(&tty_list_mutex); |