summaryrefslogtreecommitdiff
path: root/sys/net/if_tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_tun.c')
-rw-r--r--sys/net/if_tun.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index 6b974dbe9f4..e1a10a35412 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tun.c,v 1.235 2022/02/22 01:15:02 guenther Exp $ */
+/* $OpenBSD: if_tun.c,v 1.236 2022/02/26 02:15:45 dlg Exp $ */
/* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */
/*
@@ -373,10 +373,19 @@ tun_dev_open(dev_t dev, const struct if_clone *ifc, int mode, struct proc *p)
struct ifnet *ifp;
int error;
u_short stayup = 0;
+ struct vnode *vp;
char name[IFNAMSIZ];
unsigned int rdomain;
+ /*
+ * Find the vnode associated with this open before we sleep
+ * and let something else revoke it. Our caller has a reference
+ * to it so we don't need to account for it.
+ */
+ if (!vfinddev(dev, VCHR, &vp))
+ panic("%s vfinddev failed", __func__);
+
snprintf(name, sizeof(name), "%s%u", ifc->ifc_name, minor(dev));
rdomain = rtable_l2(p->p_p->ps_rtableid);
@@ -413,6 +422,12 @@ tun_dev_open(dev_t dev, const struct if_clone *ifc, int mode, struct proc *p)
}
}
+ /* Has tun_clone_destroy torn the rug out under us? */
+ if (vp->v_type == VBAD) {
+ error = ENXIO;
+ goto done;
+ }
+
if (sc->sc_dev != 0) {
/* aww, we lost */
error = EBUSY;