git: fb1526ca2783 - main - wtap(4): Fix bug in wtap_node_write() and wtap_vap_create()

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Mon, 01 Aug 2022 19:52:39 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=fb1526ca278301a495ea547ba18e22c4509e36e5

commit fb1526ca278301a495ea547ba18e22c4509e36e5
Author:     En-Wei Wu <enweiwu@FreeBSD.org>
AuthorDate: 2022-08-01 19:40:13 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-08-01 19:40:13 +0000

    wtap(4): Fix bug in wtap_node_write() and wtap_vap_create()
    
    Originally, wtap_node_write() gets the wrong softc by iterating V_inet and
    gets the ifp by string comparison, then gets softc by ifp->if_softc.
    However, ifp->if_softc will not point to the correct softc owned by
    ieee80211com, and thus causes a kernel panic.
    Fix it by assigning softc to cdev's si_drv1 in wtap_vap_create()
    and get the softc directly via dev->si_drv1 in wtap_node_write().
    
    The cdev created by wtap_vap_create() use the name of ieee80211com
    rather than the vap's name. It will cause the second vap based on
    the same ieee80211com as first vap fail to create a device node
    because the device node is already exists. Fix it by assigning
    vap->iv_ifp->if_xname to cdev's name.
    
    Sponsored by:   Google, Inc. (GSoC 2022)
    Reviewed by:    adrian, cy, bz
    Differential Revision: https://reviews.freebsd.org/D35752
---
 sys/dev/wtap/if_wtap.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c
index 26d932f250c7..214f9f739407 100644
--- a/sys/dev/wtap/if_wtap.c
+++ b/sys/dev/wtap/if_wtap.c
@@ -88,7 +88,6 @@ wtap_node_write(struct cdev *dev, struct uio *uio, int ioflag)
 {
 	int err = 0;
 	struct mbuf *m;
-	struct ifnet *ifp;
 	struct wtap_softc *sc;
 	uint8_t buf[1024];
 	struct epoch_tracker et;
@@ -106,22 +105,13 @@ wtap_node_write(struct cdev *dev, struct uio *uio, int ioflag)
 	MGETHDR(m, M_NOWAIT, MT_DATA);
 	m_copyback(m, 0, buf_len, buf);
 
-	CURVNET_SET(TD_TO_VNET(curthread));
 	NET_EPOCH_ENTER(et);
 
-	CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
-		printf("ifp->if_xname = %s\n", ifp->if_xname);
-		if(strcmp(devtoname(dev), ifp->if_xname) == 0){
-			printf("found match, correspoding wtap = %s\n",
-			    ifp->if_xname);
-			sc = (struct wtap_softc *)ifp->if_softc;
-			printf("wtap id = %d\n", sc->id);
-			wtap_inject(sc, m);
-		}
-	}
+	sc = (struct wtap_softc *)dev->si_drv1;
+	printf("wtap id = %d\n", sc->id);
+	wtap_inject(sc, m);
 
 	NET_EPOCH_EXIT(et);
-	CURVNET_RESTORE();
 
 	return(err);
 }
@@ -345,7 +335,8 @@ wtap_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
 	ieee80211_vap_attach(vap, ieee80211_media_change,
 	    ieee80211_media_status, mac);
 	avp->av_dev = make_dev(&wtap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
-	    "%s", (const char *)sc->name);
+	    "%s", (const char *)vap->iv_ifp->if_xname);
+	avp->av_dev->si_drv1 = sc;
 
 	/* TODO this is a hack to force it to choose the rate we want */
 	ni = ieee80211_ref_node(vap->iv_bss);