]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: iwlwifi: acpi: validate the WGDS table
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Thu, 19 Mar 2026 18:48:50 +0000 (20:48 +0200)
committerMiri Korenblit <miriam.rachel.korenblit@intel.com>
Wed, 25 Mar 2026 09:31:56 +0000 (11:31 +0200)
Prefer to use ARRAY_SIZE when we check array-length.
Make sure num_profile isn't bigger than the number of profiles we can
actually store in the firmware runtime object.
Same of the number of bands.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260319204647.a398511514ed.Ie4e62e2008f7e117ae7e305967ffadf1a30fc2b1@changeid
drivers/net/wireless/intel/iwlwifi/fw/acpi.c

index 721bd014bbaa6c4dd2e857b00f4101860fcd2105..1c416d3f75ea5f456f5278c77c6862359994d655 100644 (file)
@@ -865,6 +865,18 @@ int iwl_acpi_get_wgds_table(struct iwl_fw_runtime *fwrt)
                        num_bands = rev_data[idx].bands;
                        num_profiles = rev_data[idx].profiles;
 
+                       if (WARN_ON(num_profiles >
+                                   ARRAY_SIZE(fwrt->geo_profiles))) {
+                               ret = -EINVAL;
+                               goto out_free;
+                       }
+
+                       if (WARN_ON(num_bands >
+                                   ARRAY_SIZE(fwrt->geo_profiles[0].bands))) {
+                               ret = -EINVAL;
+                               goto out_free;
+                       }
+
                        if (rev_data[idx].min_profiles) {
                                /* read header that says # of profiles */
                                union acpi_object *entry;
@@ -904,18 +916,20 @@ int iwl_acpi_get_wgds_table(struct iwl_fw_runtime *fwrt)
 
 read_table:
        fwrt->geo_rev = tbl_rev;
+
        for (i = 0; i < num_profiles; i++) {
-               for (j = 0; j < BIOS_GEO_MAX_NUM_BANDS; j++) {
+               struct iwl_geo_profile *prof = &fwrt->geo_profiles[i];
+
+               for (j = 0; j < ARRAY_SIZE(prof->bands); j++) {
                        union acpi_object *entry;
 
                        /*
-                        * num_bands is either 2 or 3, if it's only 2 then
-                        * fill the third band (6 GHz) with the values from
-                        * 5 GHz (second band)
+                        * num_bands is either 2 or 3 or 4, if it's lower
+                        * than 4, fill the third band (6 GHz) with the values
+                        * from 5 GHz (second band)
                         */
                        if (j >= num_bands) {
-                               fwrt->geo_profiles[i].bands[j].max =
-                                       fwrt->geo_profiles[i].bands[1].max;
+                               prof->bands[j].max = prof->bands[1].max;
                        } else {
                                entry = &wifi_pkg->package.elements[entry_idx];
                                entry_idx++;
@@ -925,15 +939,17 @@ read_table:
                                        goto out_free;
                                }
 
-                               fwrt->geo_profiles[i].bands[j].max =
+                               prof->bands[j].max =
                                        entry->integer.value;
                        }
 
-                       for (k = 0; k < BIOS_GEO_NUM_CHAINS; k++) {
+                       for (k = 0;
+                            k < ARRAY_SIZE(prof->bands[0].chains);
+                            k++) {
                                /* same here as above */
                                if (j >= num_bands) {
-                                       fwrt->geo_profiles[i].bands[j].chains[k] =
-                                               fwrt->geo_profiles[i].bands[1].chains[k];
+                                       prof->bands[j].chains[k] =
+                                               prof->bands[1].chains[k];
                                } else {
                                        entry = &wifi_pkg->package.elements[entry_idx];
                                        entry_idx++;
@@ -943,7 +959,7 @@ read_table:
                                                goto out_free;
                                        }
 
-                                       fwrt->geo_profiles[i].bands[j].chains[k] =
+                                       prof->bands[j].chains[k] =
                                                entry->integer.value;
                                }
                        }