summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mei
diff options
context:
space:
mode:
authorAvraham Stern <avraham.stern@intel.com>2026-07-15 22:04:28 +0300
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>2026-07-16 21:10:48 +0300
commitc00a5d65b7ada536eb488280fae53fcf1724a7c3 (patch)
tree1fa043a7f344e86684720d76d3a2f6cda5eb65ae /drivers/net/wireless/intel/iwlwifi/mei
parent7d8cc301bcba233f31b589a45f4c1c97f2bb90d6 (diff)
downloadlinux-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.c20
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));