]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: iwlwifi: mvm: fix a possible underflow
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Wed, 15 Jul 2026 18:57:14 +0000 (21:57 +0300)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Thu, 16 Jul 2026 18:12:20 +0000 (21:12 +0300)
We shouldn't trust the firmware about the length of the wowlan packet.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260715215523.fbd989cc85e2.If68de403bfa4943732c025961154c20b01b09e83@changeid
drivers/net/wireless/intel/iwlwifi/mvm/d3.c

index 4eaba0bc4a1ec74d6cc3764c7e5e15fe67df4b14..109265149963b5d28ff0d689ec3129eec2996105 100644 (file)
@@ -1509,6 +1509,10 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
                if (WARN_ON_ONCE(truncated < 0))
                        truncated = 0;
 
+               /* this would be a firmware bug */
+               if (WARN_ON_ONCE(pktsize < sizeof(*hdr)))
+                       return;
+
                if (ieee80211_is_data(hdr->frame_control)) {
                        int hdrlen = ieee80211_hdrlen(hdr->frame_control);
                        int ivlen = 0, icvlen = 4; /* also FCS */
@@ -1517,10 +1521,6 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
                        if (!pkt)
                                goto report;
 
-                       skb_put_data(pkt, pktdata, hdrlen);
-                       pktdata += hdrlen;
-                       pktsize -= hdrlen;
-
                        if (ieee80211_has_protected(hdr->frame_control)) {
                                /*
                                 * This is unlocked and using gtk_i(c)vlen,
@@ -1546,6 +1546,17 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
                                truncated = 0;
                        }
 
+                       if (IWL_FW_CHECK(mvm,
+                                        pktsize <= hdrlen + ivlen + icvlen,
+                                        "pktsize is too small %d\n",
+                                        pktsize)) {
+                               kfree_skb(pkt);
+                               return;
+                       }
+
+                       skb_put_data(pkt, pktdata, hdrlen);
+                       pktdata += hdrlen;
+                       pktsize -= hdrlen;
                        pktsize -= ivlen + icvlen;
                        pktdata += ivlen;