1: f87fb8907b5f ! 1: f26563be7088 wifi: nxpwifi: validate extra-header length in monitor RX @@ Metadata Author: Heyang Tan   ## Commit message ## - wifi: nxpwifi: validate extra-header length in monitor RX + wifi: nxpwifi: validate monitor RX extra-header length  - nxpwifi_recv_packet_to_monif() reads the rxpd_extra_info structure - right after the rxpd header when RXPD_FLAG_EXTRA_HEADER is set, but it - only validates that rx_pkt_offset is at least sizeof(struct rxpd). When - the descriptor reports rx_pkt_offset smaller than - sizeof(struct rxpd) + sizeof(struct rxpd_extra_info) while the extra - header flag is set, the memcpy() of the extra header runs past the end - of the received frame and reads beyond skb->len. + nxpwifi_recv_packet_to_monif() assumes that rxpd_extra_info fits + between the rxpd header and the start of the 802.11 frame. It ensures + that rx_pkt_offset is at least sizeof(*rxpd), but the following check + only proves that sizeof(struct ieee80211_hdr) bytes starting at + rx_pkt_offset are present.  - Reject such descriptors before copying the extra header. A single check - placed next to the existing flag computation covers both the regular and - the HE copy sites. + If a malformed descriptor sets RXPD_FLAG_EXTRA_HEADER with a + rx_pkt_offset below sizeof(*rxpd) + sizeof(ext), the 32-byte copy from + rxpd + 1 can extend past the descriptor-reported end of the frame. For + example, when rx_pkt_offset is sizeof(*rxpd), skb->len can be only + sizeof(*rxpd) + sizeof(struct ieee80211_hdr), while the extra-header + copy reads through offset sizeof(*rxpd) + sizeof(ext) - 1.  - This was found by static analysis and confirmed with a KASAN - reproducer; in the real driver path the over-read stays inside the skb - headroom/tailroom slack, so it is a defensive fix rather than a memory - corruption issue. + Reject such descriptors before copying rxpd_extra_info. A single check + next to the existing flag extraction also covers the HE copy site. + + The normal skb allocation has enough slack that the over-read stays + within the allocation, so this is a defensive bounds fix.  Signed-off-by: Heyang Tan   @@ drivers/net/wireless/nxp/nxpwifi/util.c: int nxpwifi_recv_packet_to_monif(struct has_ext = rxpd->flags & RXPD_FLAG_EXTRA_HEADER;   + if (has_ext && -+ rx_pkt_offset < sizeof(struct rxpd) + sizeof(struct rxpd_extra_info)) ++ rx_pkt_offset < sizeof(*rxpd) + sizeof(ext))  + return -EINVAL;  + if (has_ext)