diff options
| author | Avraham Stern <avraham.stern@intel.com> | 2026-07-15 22:04:28 +0300 |
|---|---|---|
| committer | Miri Korenblit <miriam.rachel.korenblit@intel.com> | 2026-07-16 21:10:48 +0300 |
| commit | c00a5d65b7ada536eb488280fae53fcf1724a7c3 (patch) | |
| tree | 1fa043a7f344e86684720d76d3a2f6cda5eb65ae /drivers/net/wireless/intel/iwlwifi/mei | |
| parent | 7d8cc301bcba233f31b589a45f4c1c97f2bb90d6 (diff) | |
| download | linux-next-c00a5d65b7ada536eb488280fae53fcf1724a7c3.tar.gz linux-next-c00a5d65b7ada536eb488280fae53fcf1724a7c3.zip | |
wifi: iwlwifi: mei: skip data read if length is too short
When calculating the SAP data length, the code subtracts
sizeof(*ethhdr) from len. If the SAP data header indicates a length
that is shorter than ethernet header length, this will result in an
unsigned underflow which will lead to a kernel panic when trying to
put the data into the SKB. Fix it by skipping a message if the
indicated length is too short.
In addition, if the message type is not SAP_MSG_DATA_PACKET or skb
allocation fails, the loop skips to the next message but without
reading the message payload. This may result in reading the payload
as the next message header, which will lead to errors in parsing the
next messages. Fix it by skipping the message payload as well.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715220243.f66b10736047.I4a1dde517c36561d41358dd82a5cec8b6c886c14@changeid
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mei')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mei/main.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c index c01435859349..c462c3b22ec1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -1041,11 +1041,14 @@ static void iwl_mei_read_from_q(const u8 *q_head, u32 q_sz, u32 rd = *_rd; if (rd + len <= q_sz) { - memcpy(buf, q_head + rd, len); + if (buf) + memcpy(buf, q_head + rd, len); rd += len; } else { - memcpy(buf, q_head + rd, q_sz - rd); - memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd)); + if (buf) { + memcpy(buf, q_head + rd, q_sz - rd); + memcpy(buf + q_sz - rd, q_head, len - (q_sz - rd)); + } rd = len - (q_sz - rd); } @@ -1086,24 +1089,29 @@ static void iwl_mei_handle_sap_data(struct mei_cl_device *cldev, break; } + valid_rx_sz -= len; + if (len < sizeof(*ethhdr)) { dev_err(&cldev->dev, "Data len is smaller than an ethernet header? len = %d\n", len); + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); + continue; } - valid_rx_sz -= len; - if (le16_to_cpu(hdr.type) != SAP_MSG_DATA_PACKET) { dev_err(&cldev->dev, "Unsupported Rx data: type %d, len %d\n", le16_to_cpu(hdr.type), len); + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); continue; } /* We need enough room for the WiFi header + SNAP + IV */ skb = netdev_alloc_skb(netdev, len + QOS_HDR_IV_SNAP_LEN); - if (!skb) + if (!skb) { + iwl_mei_read_from_q(q_head, q_sz, &rd, wr, NULL, len); continue; + } skb_reserve(skb, QOS_HDR_IV_SNAP_LEN); ethhdr = skb_push(skb, sizeof(*ethhdr)); |
