1 From: Johannes Berg <johannes.berg@intel.com>
2 Date: Mon, 28 Aug 2023 09:54:39 +0200
3 Subject: [PATCH] wifi: cfg80211: annotate iftype_data pointer with sparse
5 There were are a number of cases in mac80211 and iwlwifi (at
6 least) that used the sband->iftype_data pointer directly,
7 instead of using the accessors to find the right array entry
10 Make sparse warn when such a thing is done.
12 To not have a lot of casts, add two helper functions/macros
14 - ieee80211_set_sband_iftype_data()
15 - for_each_sband_iftype_data()
17 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
20 --- a/drivers/net/wireless/ath/ath11k/mac.c
21 +++ b/drivers/net/wireless/ath/ath11k/mac.c
22 @@ -5893,8 +5893,9 @@ static void ath11k_mac_setup_he_cap(stru
23 ar->mac.iftype[NL80211_BAND_2GHZ],
25 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
26 - band->iftype_data = ar->mac.iftype[NL80211_BAND_2GHZ];
27 - band->n_iftype_data = count;
28 + _ieee80211_set_sband_iftype_data(band,
29 + ar->mac.iftype[NL80211_BAND_2GHZ],
33 if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
34 @@ -5902,8 +5903,9 @@ static void ath11k_mac_setup_he_cap(stru
35 ar->mac.iftype[NL80211_BAND_5GHZ],
37 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
38 - band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
39 - band->n_iftype_data = count;
40 + _ieee80211_set_sband_iftype_data(band,
41 + ar->mac.iftype[NL80211_BAND_5GHZ],
45 if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
46 @@ -5912,8 +5914,9 @@ static void ath11k_mac_setup_he_cap(stru
47 ar->mac.iftype[NL80211_BAND_6GHZ],
49 band = &ar->mac.sbands[NL80211_BAND_6GHZ];
50 - band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
51 - band->n_iftype_data = count;
52 + _ieee80211_set_sband_iftype_data(band,
53 + ar->mac.iftype[NL80211_BAND_6GHZ],
58 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
59 +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
60 @@ -1075,8 +1075,8 @@ static void iwl_init_he_hw_capab(struct
62 memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
64 - sband->iftype_data = iftype_data;
65 - sband->n_iftype_data = ARRAY_SIZE(iwl_he_eht_capa);
66 + _ieee80211_set_sband_iftype_data(sband, iftype_data,
67 + ARRAY_SIZE(iwl_he_eht_capa));
69 for (i = 0; i < sband->n_iftype_data; i++)
70 iwl_nvm_fixup_sband_iftd(trans, data, sband, &iftype_data[i],
71 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
72 +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
73 @@ -1119,8 +1119,7 @@ void mt7915_set_stream_he_caps(struct mt
74 n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
76 band = &phy->mt76->sband_2g.sband;
77 - band->iftype_data = data;
78 - band->n_iftype_data = n;
79 + _ieee80211_set_sband_iftype_data(band, data, n);
82 if (phy->mt76->cap.has_5ghz) {
83 @@ -1128,8 +1127,7 @@ void mt7915_set_stream_he_caps(struct mt
84 n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
86 band = &phy->mt76->sband_5g.sband;
87 - band->iftype_data = data;
88 - band->n_iftype_data = n;
89 + _ieee80211_set_sband_iftype_data(band, data, n);
92 if (phy->mt76->cap.has_6ghz) {
93 @@ -1137,8 +1135,7 @@ void mt7915_set_stream_he_caps(struct mt
94 n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data);
96 band = &phy->mt76->sband_6g.sband;
97 - band->iftype_data = data;
98 - band->n_iftype_data = n;
99 + _ieee80211_set_sband_iftype_data(band, data, n);
103 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
104 +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
105 @@ -196,8 +196,7 @@ void mt7921_set_stream_he_caps(struct mt
106 n = mt7921_init_he_caps(phy, NL80211_BAND_2GHZ, data);
108 band = &phy->mt76->sband_2g.sband;
109 - band->iftype_data = data;
110 - band->n_iftype_data = n;
111 + _ieee80211_set_sband_iftype_data(band, data, n);
114 if (phy->mt76->cap.has_5ghz) {
115 @@ -205,16 +204,14 @@ void mt7921_set_stream_he_caps(struct mt
116 n = mt7921_init_he_caps(phy, NL80211_BAND_5GHZ, data);
118 band = &phy->mt76->sband_5g.sband;
119 - band->iftype_data = data;
120 - band->n_iftype_data = n;
121 + _ieee80211_set_sband_iftype_data(band, data, n);
123 if (phy->mt76->cap.has_6ghz) {
124 data = phy->iftype[NL80211_BAND_6GHZ];
125 n = mt7921_init_he_caps(phy, NL80211_BAND_6GHZ, data);
127 band = &phy->mt76->sband_6g.sband;
128 - band->iftype_data = data;
129 - band->n_iftype_data = n;
130 + _ieee80211_set_sband_iftype_data(band, data, n);
134 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
135 +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
136 @@ -823,8 +823,7 @@ __mt7996_set_stream_he_eht_caps(struct m
140 - sband->iftype_data = data;
141 - sband->n_iftype_data = n;
142 + _ieee80211_set_sband_iftype_data(sband, data, n);
145 void mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy)
146 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
147 +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
148 @@ -1335,7 +1335,7 @@ static int qtnf_cmd_band_fill_iftype(con
152 - kfree(band->iftype_data);
153 + kfree((__force void *)band->iftype_data);
154 band->iftype_data = NULL;
155 band->n_iftype_data = tlv->n_iftype_data;
156 if (band->n_iftype_data == 0)
157 @@ -1347,7 +1347,8 @@ static int qtnf_cmd_band_fill_iftype(con
158 band->n_iftype_data = 0;
161 - band->iftype_data = iftype_data;
163 + _ieee80211_set_sband_iftype_data(band, iftype_data, tlv->n_iftype_data);
165 for (i = 0; i < band->n_iftype_data; i++)
166 qtnf_cmd_conv_iftype(iftype_data++, &tlv->iftype_data[i]);
167 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c
168 +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
169 @@ -549,7 +549,7 @@ static void qtnf_core_mac_detach(struct
170 if (!wiphy->bands[band])
173 - kfree(wiphy->bands[band]->iftype_data);
174 + kfree((__force void *)wiphy->bands[band]->iftype_data);
175 wiphy->bands[band]->n_iftype_data = 0;
177 kfree(wiphy->bands[band]->channels);
178 --- a/drivers/net/wireless/realtek/rtw89/core.c
179 +++ b/drivers/net/wireless/realtek/rtw89/core.c
180 @@ -3328,8 +3328,7 @@ static void rtw89_init_he_cap(struct rtw
184 - sband->iftype_data = iftype_data;
185 - sband->n_iftype_data = idx;
186 + _ieee80211_set_sband_iftype_data(sband, iftype_data, idx);
189 static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev)
190 @@ -3374,11 +3373,11 @@ err:
191 hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
192 hw->wiphy->bands[NL80211_BAND_6GHZ] = NULL;
194 - kfree(sband_2ghz->iftype_data);
195 + kfree((__force void *)sband_2ghz->iftype_data);
197 - kfree(sband_5ghz->iftype_data);
198 + kfree((__force void *)sband_5ghz->iftype_data);
200 - kfree(sband_6ghz->iftype_data);
201 + kfree((__force void *)sband_6ghz->iftype_data);
205 @@ -3390,11 +3389,11 @@ static void rtw89_core_clr_supported_ban
206 struct ieee80211_hw *hw = rtwdev->hw;
208 if (hw->wiphy->bands[NL80211_BAND_2GHZ])
209 - kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
210 + kfree((__force void *)hw->wiphy->bands[NL80211_BAND_2GHZ]->iftype_data);
211 if (hw->wiphy->bands[NL80211_BAND_5GHZ])
212 - kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
213 + kfree((__force void *)hw->wiphy->bands[NL80211_BAND_5GHZ]->iftype_data);
214 if (hw->wiphy->bands[NL80211_BAND_6GHZ])
215 - kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
216 + kfree((__force void *)hw->wiphy->bands[NL80211_BAND_6GHZ]->iftype_data);
217 kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]);
218 kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]);
219 kfree(hw->wiphy->bands[NL80211_BAND_6GHZ]);
220 --- a/drivers/net/wireless/realtek/rtw89/regd.c
221 +++ b/drivers/net/wireless/realtek/rtw89/regd.c
222 @@ -376,7 +376,7 @@ bottom:
225 wiphy->bands[NL80211_BAND_6GHZ] = NULL;
226 - kfree(sband->iftype_data);
227 + kfree((__force void *)sband->iftype_data);
231 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c
232 +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
233 @@ -4900,25 +4900,19 @@ static const struct ieee80211_sband_ifty
235 static void mac80211_hwsim_sband_capab(struct ieee80211_supported_band *sband)
239 - if (sband->band == NL80211_BAND_2GHZ) {
240 - n_iftype_data = ARRAY_SIZE(sband_capa_2ghz);
241 - sband->iftype_data =
242 - (struct ieee80211_sband_iftype_data *)sband_capa_2ghz;
243 - } else if (sband->band == NL80211_BAND_5GHZ) {
244 - n_iftype_data = ARRAY_SIZE(sband_capa_5ghz);
245 - sband->iftype_data =
246 - (struct ieee80211_sband_iftype_data *)sband_capa_5ghz;
247 - } else if (sband->band == NL80211_BAND_6GHZ) {
248 - n_iftype_data = ARRAY_SIZE(sband_capa_6ghz);
249 - sband->iftype_data =
250 - (struct ieee80211_sband_iftype_data *)sband_capa_6ghz;
253 + switch (sband->band) {
254 + case NL80211_BAND_2GHZ:
255 + ieee80211_set_sband_iftype_data(sband, sband_capa_2ghz);
257 + case NL80211_BAND_5GHZ:
258 + ieee80211_set_sband_iftype_data(sband, sband_capa_5ghz);
260 + case NL80211_BAND_6GHZ:
261 + ieee80211_set_sband_iftype_data(sband, sband_capa_6ghz);
267 - sband->n_iftype_data = n_iftype_data;
270 #ifdef CPTCFG_MAC80211_MESH
271 --- a/include/net/cfg80211.h
272 +++ b/include/net/cfg80211.h
273 @@ -415,6 +415,19 @@ struct ieee80211_sta_eht_cap {
274 u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN];
277 +/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
280 + * This is used to mark the sband->iftype_data pointer which is supposed
281 + * to be an array with special access semantics (per iftype), but a lot
282 + * of code got it wrong in the past, so with this marking sparse will be
283 + * noisy when the pointer is used directly.
285 +# define __iftd __attribute__((noderef, address_space(__iftype_data)))
288 +#endif /* __CHECKER__ */
291 * struct ieee80211_sband_iftype_data - sband data per interface type
293 @@ -548,10 +561,48 @@ struct ieee80211_supported_band {
294 struct ieee80211_sta_s1g_cap s1g_cap;
295 struct ieee80211_edmg edmg_cap;
297 - const struct ieee80211_sband_iftype_data *iftype_data;
298 + const struct ieee80211_sband_iftype_data __iftd *iftype_data;
302 + * _ieee80211_set_sband_iftype_data - set sband iftype data array
303 + * @sband: the sband to initialize
304 + * @iftd: the iftype data array pointer
305 + * @n_iftd: the length of the iftype data array
307 + * Set the sband iftype data array; use this where the length cannot
308 + * be derived from the ARRAY_SIZE() of the argument, but prefer
309 + * ieee80211_set_sband_iftype_data() where it can be used.
312 +_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *sband,
313 + const struct ieee80211_sband_iftype_data *iftd,
316 + sband->iftype_data = (const void __iftd __force *)iftd;
317 + sband->n_iftype_data = n_iftd;
321 + * ieee80211_set_sband_iftype_data - set sband iftype data array
322 + * @sband: the sband to initialize
323 + * @iftd: the iftype data array
325 +#define ieee80211_set_sband_iftype_data(sband, iftd) \
326 + _ieee80211_set_sband_iftype_data(sband, iftd, ARRAY_SIZE(iftd))
329 + * for_each_sband_iftype_data - iterate sband iftype data entries
330 + * @sband: the sband whose iftype_data array to iterate
331 + * @i: iterator counter
332 + * @iftd: iftype data pointer to set
334 +#define for_each_sband_iftype_data(sband, i, iftd) \
335 + for (i = 0, iftd = (const void __force *)&(sband)->iftype_data[i]; \
336 + i < (sband)->n_iftype_data; \
337 + i++, iftd = (const void __force *)&(sband)->iftype_data[i])
340 * ieee80211_get_sband_iftype_data - return sband data for a given iftype
341 * @sband: the sband to search for the STA on
342 * @iftype: enum nl80211_iftype
343 @@ -562,6 +613,7 @@ static inline const struct ieee80211_sba
344 ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
347 + const struct ieee80211_sband_iftype_data *data;
350 if (WARN_ON(iftype >= NL80211_IFTYPE_MAX))
351 @@ -570,10 +622,7 @@ ieee80211_get_sband_iftype_data(const st
352 if (iftype == NL80211_IFTYPE_AP_VLAN)
353 iftype = NL80211_IFTYPE_AP;
355 - for (i = 0; i < sband->n_iftype_data; i++) {
356 - const struct ieee80211_sband_iftype_data *data =
357 - &sband->iftype_data[i];
359 + for_each_sband_iftype_data(sband, i, data) {
360 if (data->types_mask & BIT(iftype))
363 --- a/net/mac80211/main.c
364 +++ b/net/mac80211/main.c
365 @@ -1055,6 +1055,7 @@ int ieee80211_register_hw(struct ieee802
368 for (band = 0; band < NUM_NL80211_BANDS; band++) {
369 + const struct ieee80211_sband_iftype_data *iftd;
370 struct ieee80211_supported_band *sband;
372 sband = local->hw.wiphy->bands[band];
373 @@ -1101,11 +1102,7 @@ int ieee80211_register_hw(struct ieee802
374 supp_ht = supp_ht || sband->ht_cap.ht_supported;
375 supp_vht = supp_vht || sband->vht_cap.vht_supported;
377 - for (i = 0; i < sband->n_iftype_data; i++) {
378 - const struct ieee80211_sband_iftype_data *iftd;
380 - iftd = &sband->iftype_data[i];
382 + for_each_sband_iftype_data(sband, i, iftd) {
383 supp_he = supp_he || iftd->he_cap.has_he;
384 supp_eht = supp_eht || iftd->eht_cap.has_eht;
386 --- a/net/wireless/chan.c
387 +++ b/net/wireless/chan.c
390 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
391 * Copyright 2013-2014 Intel Mobile Communications GmbH
392 - * Copyright 2018-2022 Intel Corporation
393 + * Copyright 2018-2023 Intel Corporation
396 #include <linux/export.h>
397 @@ -1162,8 +1162,7 @@ bool cfg80211_chandef_usable(struct wiph
401 - for (i = 0; i < sband->n_iftype_data; i++) {
402 - iftd = &sband->iftype_data[i];
403 + for_each_sband_iftype_data(sband, i, iftd) {
404 if (!iftd->eht_cap.has_eht)
407 --- a/net/wireless/core.c
408 +++ b/net/wireless/core.c
410 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
411 * Copyright 2013-2014 Intel Mobile Communications GmbH
412 * Copyright 2015-2017 Intel Deutschland GmbH
413 - * Copyright (C) 2018-2022 Intel Corporation
414 + * Copyright (C) 2018-2023 Intel Corporation
417 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
418 @@ -817,6 +817,7 @@ int wiphy_register(struct wiphy *wiphy)
420 /* sanity check supported bands/channels */
421 for (band = 0; band < NUM_NL80211_BANDS; band++) {
422 + const struct ieee80211_sband_iftype_data *iftd;
424 bool have_he = false;
426 @@ -873,14 +874,11 @@ int wiphy_register(struct wiphy *wiphy)
430 - for (i = 0; i < sband->n_iftype_data; i++) {
431 - const struct ieee80211_sband_iftype_data *iftd;
432 + for_each_sband_iftype_data(sband, i, iftd) {
433 bool has_ap, has_non_ap;
434 u32 ap_bits = BIT(NL80211_IFTYPE_AP) |
435 BIT(NL80211_IFTYPE_P2P_GO);
437 - iftd = &sband->iftype_data[i];
439 if (WARN_ON(!iftd->types_mask))
441 if (WARN_ON(types & iftd->types_mask))
442 --- a/net/wireless/nl80211.c
443 +++ b/net/wireless/nl80211.c
444 @@ -1906,20 +1906,20 @@ static int nl80211_send_band_rateinfo(st
445 struct nlattr *nl_iftype_data =
446 nla_nest_start_noflag(msg,
447 NL80211_BAND_ATTR_IFTYPE_DATA);
448 + const struct ieee80211_sband_iftype_data *iftd;
454 - for (i = 0; i < sband->n_iftype_data; i++) {
455 + for_each_sband_iftype_data(sband, i, iftd) {
456 struct nlattr *iftdata;
458 iftdata = nla_nest_start_noflag(msg, i + 1);
462 - err = nl80211_send_iftype_data(msg, sband,
463 - &sband->iftype_data[i]);
464 + err = nl80211_send_iftype_data(msg, sband, iftd);