18420a80cf9e84d7ba96f2cbe1dfc6ace182c15a
[openwrt/staging/jow.git] /
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
4
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
8 to use.
9
10 Make sparse warn when such a thing is done.
11
12 To not have a lot of casts, add two helper functions/macros
13
14 - ieee80211_set_sband_iftype_data()
15 - for_each_sband_iftype_data()
16
17 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
18 ---
19
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],
24 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],
30 + count);
31 }
32
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],
36 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],
42 + count);
43 }
44
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],
48 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],
54 + count);
55 }
56 }
57
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
61
62 memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
63
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));
68
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);
75
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);
80 }
81
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);
85
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);
90 }
91
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);
95
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);
100 }
101 }
102
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);
107
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);
112 }
113
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);
117
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);
122
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);
126
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);
131 }
132 }
133 }
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
137 n++;
138 }
139
140 - sband->iftype_data = data;
141 - sband->n_iftype_data = n;
142 + _ieee80211_set_sband_iftype_data(sband, data, n);
143 }
144
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
149 return -EINVAL;
150 }
151
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;
159 return -ENOMEM;
160 }
161 - band->iftype_data = iftype_data;
162 +
163 + _ieee80211_set_sband_iftype_data(band, iftype_data, tlv->n_iftype_data);
164
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])
171 continue;
172
173 - kfree(wiphy->bands[band]->iftype_data);
174 + kfree((__force void *)wiphy->bands[band]->iftype_data);
175 wiphy->bands[band]->n_iftype_data = 0;
176
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
181 idx++;
182 }
183
184 - sband->iftype_data = iftype_data;
185 - sband->n_iftype_data = idx;
186 + _ieee80211_set_sband_iftype_data(sband, iftype_data, idx);
187 }
188
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;
193 if (sband_2ghz)
194 - kfree(sband_2ghz->iftype_data);
195 + kfree((__force void *)sband_2ghz->iftype_data);
196 if (sband_5ghz)
197 - kfree(sband_5ghz->iftype_data);
198 + kfree((__force void *)sband_5ghz->iftype_data);
199 if (sband_6ghz)
200 - kfree(sband_6ghz->iftype_data);
201 + kfree((__force void *)sband_6ghz->iftype_data);
202 kfree(sband_2ghz);
203 kfree(sband_5ghz);
204 kfree(sband_6ghz);
205 @@ -3390,11 +3389,11 @@ static void rtw89_core_clr_supported_ban
206 struct ieee80211_hw *hw = rtwdev->hw;
207
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:
223 return;
224
225 wiphy->bands[NL80211_BAND_6GHZ] = NULL;
226 - kfree(sband->iftype_data);
227 + kfree((__force void *)sband->iftype_data);
228 kfree(sband);
229 }
230
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
234
235 static void mac80211_hwsim_sband_capab(struct ieee80211_supported_band *sband)
236 {
237 - u16 n_iftype_data;
238 -
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;
251 - } else {
252 - return;
253 + switch (sband->band) {
254 + case NL80211_BAND_2GHZ:
255 + ieee80211_set_sband_iftype_data(sband, sband_capa_2ghz);
256 + break;
257 + case NL80211_BAND_5GHZ:
258 + ieee80211_set_sband_iftype_data(sband, sband_capa_5ghz);
259 + break;
260 + case NL80211_BAND_6GHZ:
261 + ieee80211_set_sband_iftype_data(sband, sband_capa_6ghz);
262 + break;
263 + default:
264 + break;
265 }
266 -
267 - sband->n_iftype_data = n_iftype_data;
268 }
269
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];
275 };
276
277 +/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
278 +#ifdef __CHECKER__
279 +/*
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.
284 + */
285 +# define __iftd __attribute__((noderef, address_space(__iftype_data)))
286 +#else
287 +# define __iftd
288 +#endif /* __CHECKER__ */
289 +
290 /**
291 * struct ieee80211_sband_iftype_data - sband data per interface type
292 *
293 @@ -548,10 +561,48 @@ struct ieee80211_supported_band {
294 struct ieee80211_sta_s1g_cap s1g_cap;
295 struct ieee80211_edmg edmg_cap;
296 u16 n_iftype_data;
297 - const struct ieee80211_sband_iftype_data *iftype_data;
298 + const struct ieee80211_sband_iftype_data __iftd *iftype_data;
299 };
300
301 /**
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
306 + *
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.
310 + */
311 +static inline void
312 +_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *sband,
313 + const struct ieee80211_sband_iftype_data *iftd,
314 + u16 n_iftd)
315 +{
316 + sband->iftype_data = (const void __iftd __force *)iftd;
317 + sband->n_iftype_data = n_iftd;
318 +}
319 +
320 +/**
321 + * ieee80211_set_sband_iftype_data - set sband iftype data array
322 + * @sband: the sband to initialize
323 + * @iftd: the iftype data array
324 + */
325 +#define ieee80211_set_sband_iftype_data(sband, iftd) \
326 + _ieee80211_set_sband_iftype_data(sband, iftd, ARRAY_SIZE(iftd))
327 +
328 +/**
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
333 + */
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])
338 +
339 +/**
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,
345 u8 iftype)
346 {
347 + const struct ieee80211_sband_iftype_data *data;
348 int i;
349
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;
354
355 - for (i = 0; i < sband->n_iftype_data; i++) {
356 - const struct ieee80211_sband_iftype_data *data =
357 - &sband->iftype_data[i];
358 -
359 + for_each_sband_iftype_data(sband, i, data) {
360 if (data->types_mask & BIT(iftype))
361 return data;
362 }
363 --- a/net/mac80211/main.c
364 +++ b/net/mac80211/main.c
365 @@ -1055,6 +1055,7 @@ int ieee80211_register_hw(struct ieee802
366 supp_he = false;
367 supp_eht = false;
368 for (band = 0; band < NUM_NL80211_BANDS; band++) {
369 + const struct ieee80211_sband_iftype_data *iftd;
370 struct ieee80211_supported_band *sband;
371
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;
376
377 - for (i = 0; i < sband->n_iftype_data; i++) {
378 - const struct ieee80211_sband_iftype_data *iftd;
379 -
380 - iftd = &sband->iftype_data[i];
381 -
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;
385 }
386 --- a/net/wireless/chan.c
387 +++ b/net/wireless/chan.c
388 @@ -6,7 +6,7 @@
389 *
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
394 */
395
396 #include <linux/export.h>
397 @@ -1162,8 +1162,7 @@ bool cfg80211_chandef_usable(struct wiph
398 if (!sband)
399 return false;
400
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)
405 continue;
406
407 --- a/net/wireless/core.c
408 +++ b/net/wireless/core.c
409 @@ -5,7 +5,7 @@
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
415 */
416
417 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
418 @@ -817,6 +817,7 @@ int wiphy_register(struct wiphy *wiphy)
419
420 /* sanity check supported bands/channels */
421 for (band = 0; band < NUM_NL80211_BANDS; band++) {
422 + const struct ieee80211_sband_iftype_data *iftd;
423 u16 types = 0;
424 bool have_he = false;
425
426 @@ -873,14 +874,11 @@ int wiphy_register(struct wiphy *wiphy)
427 return -EINVAL;
428 }
429
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);
436
437 - iftd = &sband->iftype_data[i];
438 -
439 if (WARN_ON(!iftd->types_mask))
440 return -EINVAL;
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;
449 int err;
450
451 if (!nl_iftype_data)
452 return -ENOBUFS;
453
454 - for (i = 0; i < sband->n_iftype_data; i++) {
455 + for_each_sband_iftype_data(sband, i, iftd) {
456 struct nlattr *iftdata;
457
458 iftdata = nla_nest_start_noflag(msg, i + 1);
459 if (!iftdata)
460 return -ENOBUFS;
461
462 - err = nl80211_send_iftype_data(msg, sband,
463 - &sband->iftype_data[i]);
464 + err = nl80211_send_iftype_data(msg, sband, iftd);
465 if (err)
466 return err;
467