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;