git: 81a67bfebc60 - main - rsu: add a runtime TX buffer bound check for a kernel buffer overflow
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 20 Aug 2026 14:30:38 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=81a67bfebc60055bbf19ce6e39537fb5f53eeee5
commit 81a67bfebc60055bbf19ce6e39537fb5f53eeee5
Author: Andrew Griffiths <andrew@calif.io>
AuthorDate: 2026-08-20 14:30:03 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
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;