From: Emmanuel Grumbach Date: Thu, 19 Mar 2026 18:48:50 +0000 (+0200) Subject: wifi: iwlwifi: acpi: validate the WGDS table X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f951689793e6c5e908be143fcc506aafa5bf3c36;p=thirdparty%2Flinux.git wifi: iwlwifi: acpi: validate the WGDS table 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 Reviewed-by: Johannes Berg Signed-off-by: Miri Korenblit Link: https://patch.msgid.link/20260319204647.a398511514ed.Ie4e62e2008f7e117ae7e305967ffadf1a30fc2b1@changeid --- diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 721bd014bbaa6..1c416d3f75ea5 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -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; } }