git: 81a67bfebc60 - main - rsu: add a runtime TX buffer bound check for a kernel buffer overflow

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by markj:

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

commit 81a67bfebc60055bbf19ce6e39537fb5f53eeee5
Author:     Andrew Griffiths <[email protected]>
AuthorDate: 2026-08-20 14:30:03 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-20 14:30:03 +0000

    rsu: add a runtime TX buffer bound check for a kernel buffer overflow
    
    The rsu driver currently relies on a `KASSERT` to prove that the mbuf payload
    plus TX descriptor fits in the per-transfer USB TX buffer. On production
    kernels without `INVARIANTS`, an oversized raw 802.11 frame can reach
    `m_copydata()` and overwrite past that buffer, causing local kernel memory
    corruption.
    
    This suggested patch replaces the assertion-only guard with a runtime size
    check before the copy. Oversized frames return `EMSGSIZE`, leaving the existing
    caller cleanup paths responsible for freeing `m0`, `ni`, and the unused
    transfer buffer.
    
    Reachable via root / bpf access
    
    Reviewed by:    bz, adrian
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D58898
---
 sys/dev/usb/wlan/if_rsu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 2f934737f699..68271f365dd5 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -2917,6 +2917,9 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
 	 */
 	txd->txdw3 |= htole32(SM(R92S_TXDW3_SEQ, prio));
 
+	if (m0->m_pkthdr.len > RSU_TXBUFSZ - sizeof(*txd))
+		return (EMSGSIZE);
+
 	if (ieee80211_radiotap_active_vap(vap)) {
 		struct rsu_tx_radiotap_header *tap = &sc->sc_txtap;
 
@@ -2925,7 +2928,6 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
 	}
 
 	xferlen = sizeof(*txd) + m0->m_pkthdr.len;
-	KASSERT(xferlen <= RSU_TXBUFSZ, ("%s: invalid length", __func__));
 	m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&txd[1]);
 
 	data->buflen = xferlen;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.