Skip to content

Commit bcde724

Browse files
huanghuihui0904gregkh
authored andcommitted
wifi: at76c50x-usb: avoid length underflow in at76_guess_freq()
commit 61a799f upstream. at76_guess_freq() checks only that the received frame is at least a bare 802.11 header (24 bytes) before subtracting the fixed management-body offset: len -= el_off; For both beacon and probe response frames, el_off is 36. If the frame is shorter than el_off, subtracting it causes the calculated IE length to wrap. The length is eventually passed to cfg80211_find_elem_match() as a very large unsigned value, so the element walk runs beyond the RX skb. This path is reached from at76_rx_tasklet() while scanning. If the device delivers a truncated beacon or probe response, the oversized IE length causes an out-of-bounds read during scanning. Skip the IE lookup if the frame does not reach the variable elements, before subtracting el_off. Fixes: 1264b95 ("at76c50x-usb: add driver") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Huihui Huang <hhhuang@smu.edu.sg> Link: https://patch.msgid.link/20260715140815.1242033-1-hhhuang@smu.edu.sg Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c07caee commit bcde724

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

drivers/net/wireless/atmel/at76c50x-usb.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,13 +1521,16 @@ static inline int at76_guess_freq(struct at76_priv *priv)
15211521

15221522
if (ieee80211_is_probe_resp(hdr->frame_control)) {
15231523
el_off = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
1524-
el = ((struct ieee80211_mgmt *)hdr)->u.probe_resp.variable;
15251524
} else if (ieee80211_is_beacon(hdr->frame_control)) {
15261525
el_off = offsetof(struct ieee80211_mgmt, u.beacon.variable);
1527-
el = ((struct ieee80211_mgmt *)hdr)->u.beacon.variable;
15281526
} else {
15291527
goto exit;
15301528
}
1529+
1530+
if (len < el_off)
1531+
goto exit;
1532+
1533+
el = priv->rx_skb->data + el_off;
15311534
len -= el_off;
15321535

15331536
el = cfg80211_find_ie(WLAN_EID_DS_PARAMS, el, len);

0 commit comments

Comments
 (0)