summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-05-23 16:47:55 +0000
committerkib <kib@FreeBSD.org>2008-05-23 16:47:55 +0000
commit797c3188c07ea75e3dec375470a12724a500a856 (patch)
tree0e4cb5c91c1a42033c1b2fa3ee7b7d3b5bfaf5fb /sys
parent90775e30dbdf185e0d078b6b11fbf16866097173 (diff)
downloadFreeBSD-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.c7
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);
OpenPOWER on IntegriCloud