]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: fix overflow warning on num_pwr_levels
authorBaochen Qiang <quic_bqiang@quicinc.com>
Mon, 4 Aug 2025 03:03:11 +0000 (11:03 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 18 Sep 2025 23:43:47 +0000 (16:43 -0700)
In ath12k_mac_parse_tx_pwr_env(), for the non-PSD case num_pwr_levels is
limited by ATH12K_NUM_PWR_LEVELS which is 16:

if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;

Then it is used to iterate entries in local_non_psd->power[] and
reg_non_psd->power[]:

for (i = 0; i < tpc_info->num_pwr_levels; i++) {
tpc_info->tpe[i] = min(local_non_psd->power[i],
       reg_non_psd->power[i]) / 2;

Since the two array are of size 5, Smatch warns:

drivers/net/wireless/ath/ath12k/mac.c:9812
ath12k_mac_parse_tx_pwr_env() error: buffer overflow 'local_non_psd->power' 5 <= 15
drivers/net/wireless/ath/ath12k/mac.c:9812
ath12k_mac_parse_tx_pwr_env() error: buffer overflow 'reg_non_psd->power' 5 <= 15

This is a false positive as there is already implicit limitation:

tpc_info->num_pwr_levels = max(local_non_psd->count,
       reg_non_psd->count);

meaning it won't exceed 5.

However, to make robot happy, add explicit limit there.

Also add the same to the PSD case, although no warning due to
ATH12K_NUM_PWR_LEVELS equals IEEE80211_TPE_PSD_ENTRIES_320MHZ.

Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1

Fixes: cccbb9d0dd6a ("wifi: ath12k: add parse of transmit power envelope element")
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Closes: https://lore.kernel.org/r/202505180703.Kr9OfQRP-lkp@intel.com/
Signed-off-by: Baochen Qiang <quic_bqiang@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20250804-ath12k-fix-smatch-warning-on-6g-vlp-v1-2-56f1e54152ab@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/mac.c

index 63b7129f224591045eaf08fada547991b6c53a5a..7a43f2e8f905db05d17ab58eba5e370db462edfe 100644 (file)
@@ -11448,8 +11448,10 @@ static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar,
 
                tpc_info->num_pwr_levels = max(local_psd->count,
                                               reg_psd->count);
-               if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
-                       tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
+               tpc_info->num_pwr_levels =
+                               min3(tpc_info->num_pwr_levels,
+                                    IEEE80211_TPE_PSD_ENTRIES_320MHZ,
+                                    ATH12K_NUM_PWR_LEVELS);
 
                for (i = 0; i < tpc_info->num_pwr_levels; i++) {
                        tpc_info->tpe[i] = min(local_psd->power[i],
@@ -11464,8 +11466,10 @@ static void ath12k_mac_parse_tx_pwr_env(struct ath12k *ar,
 
                tpc_info->num_pwr_levels = max(local_non_psd->count,
                                               reg_non_psd->count);
-               if (tpc_info->num_pwr_levels > ATH12K_NUM_PWR_LEVELS)
-                       tpc_info->num_pwr_levels = ATH12K_NUM_PWR_LEVELS;
+               tpc_info->num_pwr_levels =
+                               min3(tpc_info->num_pwr_levels,
+                                    IEEE80211_TPE_EIRP_ENTRIES_320MHZ,
+                                    ATH12K_NUM_PWR_LEVELS);
 
                for (i = 0; i < tpc_info->num_pwr_levels; i++) {
                        tpc_info->tpe[i] = min(local_non_psd->power[i],