diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-04-29 16:00:07 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-04-29 16:00:07 +0000 |
commit | 186ef4c49c3b5c77dce533ac7255688792ce1c98 (patch) | |
tree | 5cbd6589c34b568970c2ec9186f16ae69b081ff5 /sys | |
parent | b0d13f99fc745a16e3ec85281d0e281bf678a967 (diff) |
Use if_get() after every tsleep(), in case the bottom half of the driver
has destroyed or damaged the interface clone.
with mpi
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_tun.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index c0e9ddcd2cb..73073916290 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.137 2015/04/15 10:11:29 mpi Exp $ */ +/* $OpenBSD: if_tun.c,v 1.138 2015/04/29 16:00:06 deraadt Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -717,11 +717,13 @@ tunread(dev_t dev, struct uio *uio, int ioflag) struct ifnet *ifp; struct mbuf *m, *m0; int error = 0, len, s; + unsigned int ifindex; if ((tp = tun_lookup(minor(dev))) == NULL) return (ENXIO); ifp = &tp->tun_if; + ifindex = ifp->if_index; TUNDEBUG(("%s: read\n", ifp->if_xname)); if ((tp->tun_flags & TUN_READY) != TUN_READY) { TUNDEBUG(("%s: not ready %#x\n", ifp->if_xname, tp->tun_flags)); @@ -732,12 +734,17 @@ tunread(dev_t dev, struct uio *uio, int ioflag) s = splnet(); do { - while ((tp->tun_flags & TUN_READY) != TUN_READY) + while ((tp->tun_flags & TUN_READY) != TUN_READY) { if ((error = tsleep((caddr_t)tp, (PZERO + 1)|PCATCH, "tunread", 0)) != 0) { splx(s); return (error); } + if ((ifp = if_get(ifindex)) == NULL) { + splx(s); + return (ENXIO); + } + } IFQ_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) { if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) { @@ -750,6 +757,10 @@ tunread(dev_t dev, struct uio *uio, int ioflag) splx(s); return (error); } + if ((ifp = if_get(ifindex)) == NULL) { + splx(s); + return (ENXIO); + } } } while (m0 == NULL); splx(s); |