diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2014-11-27 04:11:16 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-12-01 02:09:21 -0500 |
commit | 37b9f933e0a82dcf61eb692d99d7106395b8e50f (patch) | |
tree | 526c5615cb8e8f14640e3cdb6044e971ce38c486 | |
parent | 2a3e60d37fc662e9c3bac2f3b960062238edb2a0 (diff) |
ath10k: add sanity checks for service bmap parsing
This shouldn't really happen but take into account
the original service bitmap length when mapping
service ids.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.h | 121 |
2 files changed, 66 insertions, 61 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c6c03e540747..81ccc2eda47e 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -2516,10 +2516,12 @@ static void ath10k_wmi_event_service_ready(struct ath10k *ar, | |||
2516 | 2516 | ||
2517 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { | 2517 | if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { |
2518 | ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg); | 2518 | ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg); |
2519 | wmi_10x_svc_map(arg.service_map, svc_bmap); | 2519 | wmi_10x_svc_map(arg.service_map, svc_bmap, |
2520 | arg.service_map_len); | ||
2520 | } else { | 2521 | } else { |
2521 | ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg); | 2522 | ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg); |
2522 | wmi_main_svc_map(arg.service_map, svc_bmap); | 2523 | wmi_main_svc_map(arg.service_map, svc_bmap, |
2524 | arg.service_map_len); | ||
2523 | } | 2525 | } |
2524 | 2526 | ||
2525 | if (ret) { | 2527 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index b264c403e5e0..21391929d318 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h | |||
@@ -222,128 +222,131 @@ static inline char *wmi_service_name(int service_id) | |||
222 | #undef SVCSTR | 222 | #undef SVCSTR |
223 | } | 223 | } |
224 | 224 | ||
225 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ | 225 | #define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \ |
226 | (__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ | 226 | ((svc_id) < (len) && \ |
227 | __le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ | ||
227 | BIT((svc_id)%(sizeof(u32)))) | 228 | BIT((svc_id)%(sizeof(u32)))) |
228 | 229 | ||
229 | #define SVCMAP(x, y) \ | 230 | #define SVCMAP(x, y, len) \ |
230 | do { \ | 231 | do { \ |
231 | if (WMI_SERVICE_IS_ENABLED((in), (x))) \ | 232 | if (WMI_SERVICE_IS_ENABLED((in), (x), (len))) \ |
232 | __set_bit(y, out); \ | 233 | __set_bit(y, out); \ |
233 | } while (0) | 234 | } while (0) |
234 | 235 | ||
235 | static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out) | 236 | static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out, |
237 | size_t len) | ||
236 | { | 238 | { |
237 | SVCMAP(WMI_10X_SERVICE_BEACON_OFFLOAD, | 239 | SVCMAP(WMI_10X_SERVICE_BEACON_OFFLOAD, |
238 | WMI_SERVICE_BEACON_OFFLOAD); | 240 | WMI_SERVICE_BEACON_OFFLOAD, len); |
239 | SVCMAP(WMI_10X_SERVICE_SCAN_OFFLOAD, | 241 | SVCMAP(WMI_10X_SERVICE_SCAN_OFFLOAD, |
240 | WMI_SERVICE_SCAN_OFFLOAD); | 242 | WMI_SERVICE_SCAN_OFFLOAD, len); |
241 | SVCMAP(WMI_10X_SERVICE_ROAM_OFFLOAD, | 243 | SVCMAP(WMI_10X_SERVICE_ROAM_OFFLOAD, |
242 | WMI_SERVICE_ROAM_OFFLOAD); | 244 | WMI_SERVICE_ROAM_OFFLOAD, len); |
243 | SVCMAP(WMI_10X_SERVICE_BCN_MISS_OFFLOAD, | 245 | SVCMAP(WMI_10X_SERVICE_BCN_MISS_OFFLOAD, |
244 | WMI_SERVICE_BCN_MISS_OFFLOAD); | 246 | WMI_SERVICE_BCN_MISS_OFFLOAD, len); |
245 | SVCMAP(WMI_10X_SERVICE_STA_PWRSAVE, | 247 | SVCMAP(WMI_10X_SERVICE_STA_PWRSAVE, |
246 | WMI_SERVICE_STA_PWRSAVE); | 248 | WMI_SERVICE_STA_PWRSAVE, len); |
247 | SVCMAP(WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, | 249 | SVCMAP(WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, |
248 | WMI_SERVICE_STA_ADVANCED_PWRSAVE); | 250 | WMI_SERVICE_STA_ADVANCED_PWRSAVE, len); |
249 | SVCMAP(WMI_10X_SERVICE_AP_UAPSD, | 251 | SVCMAP(WMI_10X_SERVICE_AP_UAPSD, |
250 | WMI_SERVICE_AP_UAPSD); | 252 | WMI_SERVICE_AP_UAPSD, len); |
251 | SVCMAP(WMI_10X_SERVICE_AP_DFS, | 253 | SVCMAP(WMI_10X_SERVICE_AP_DFS, |
252 | WMI_SERVICE_AP_DFS); | 254 | WMI_SERVICE_AP_DFS, len); |
253 | SVCMAP(WMI_10X_SERVICE_11AC, | 255 | SVCMAP(WMI_10X_SERVICE_11AC, |
254 | WMI_SERVICE_11AC); | 256 | WMI_SERVICE_11AC, len); |
255 | SVCMAP(WMI_10X_SERVICE_BLOCKACK, | 257 | SVCMAP(WMI_10X_SERVICE_BLOCKACK, |
256 | WMI_SERVICE_BLOCKACK); | 258 | WMI_SERVICE_BLOCKACK, len); |
257 | SVCMAP(WMI_10X_SERVICE_PHYERR, | 259 | SVCMAP(WMI_10X_SERVICE_PHYERR, |
258 | WMI_SERVICE_PHYERR); | 260 | WMI_SERVICE_PHYERR, len); |
259 | SVCMAP(WMI_10X_SERVICE_BCN_FILTER, | 261 | SVCMAP(WMI_10X_SERVICE_BCN_FILTER, |
260 | WMI_SERVICE_BCN_FILTER); | 262 | WMI_SERVICE_BCN_FILTER, len); |
261 | SVCMAP(WMI_10X_SERVICE_RTT, | 263 | SVCMAP(WMI_10X_SERVICE_RTT, |
262 | WMI_SERVICE_RTT); | 264 | WMI_SERVICE_RTT, len); |
263 | SVCMAP(WMI_10X_SERVICE_RATECTRL, | 265 | SVCMAP(WMI_10X_SERVICE_RATECTRL, |
264 | WMI_SERVICE_RATECTRL); | 266 | WMI_SERVICE_RATECTRL, len); |
265 | SVCMAP(WMI_10X_SERVICE_WOW, | 267 | SVCMAP(WMI_10X_SERVICE_WOW, |
266 | WMI_SERVICE_WOW); | 268 | WMI_SERVICE_WOW, len); |
267 | SVCMAP(WMI_10X_SERVICE_RATECTRL_CACHE, | 269 | SVCMAP(WMI_10X_SERVICE_RATECTRL_CACHE, |
268 | WMI_SERVICE_RATECTRL_CACHE); | 270 | WMI_SERVICE_RATECTRL_CACHE, len); |
269 | SVCMAP(WMI_10X_SERVICE_IRAM_TIDS, | 271 | SVCMAP(WMI_10X_SERVICE_IRAM_TIDS, |
270 | WMI_SERVICE_IRAM_TIDS); | 272 | WMI_SERVICE_IRAM_TIDS, len); |
271 | SVCMAP(WMI_10X_SERVICE_BURST, | 273 | SVCMAP(WMI_10X_SERVICE_BURST, |
272 | WMI_SERVICE_BURST); | 274 | WMI_SERVICE_BURST, len); |
273 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, | 275 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, |
274 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); | 276 | WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, len); |
275 | SVCMAP(WMI_10X_SERVICE_FORCE_FW_HANG, | 277 | SVCMAP(WMI_10X_SERVICE_FORCE_FW_HANG, |
276 | WMI_SERVICE_FORCE_FW_HANG); | 278 | WMI_SERVICE_FORCE_FW_HANG, len); |
277 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, | 279 | SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, |
278 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); | 280 | WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, len); |
279 | } | 281 | } |
280 | 282 | ||
281 | static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out) | 283 | static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, |
284 | size_t len) | ||
282 | { | 285 | { |
283 | SVCMAP(WMI_MAIN_SERVICE_BEACON_OFFLOAD, | 286 | SVCMAP(WMI_MAIN_SERVICE_BEACON_OFFLOAD, |
284 | WMI_SERVICE_BEACON_OFFLOAD); | 287 | WMI_SERVICE_BEACON_OFFLOAD, len); |
285 | SVCMAP(WMI_MAIN_SERVICE_SCAN_OFFLOAD, | 288 | SVCMAP(WMI_MAIN_SERVICE_SCAN_OFFLOAD, |
286 | WMI_SERVICE_SCAN_OFFLOAD); | 289 | WMI_SERVICE_SCAN_OFFLOAD, len); |
287 | SVCMAP(WMI_MAIN_SERVICE_ROAM_OFFLOAD, | 290 | SVCMAP(WMI_MAIN_SERVICE_ROAM_OFFLOAD, |
288 | WMI_SERVICE_ROAM_OFFLOAD); | 291 | WMI_SERVICE_ROAM_OFFLOAD, len); |
289 | SVCMAP(WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, | 292 | SVCMAP(WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, |
290 | WMI_SERVICE_BCN_MISS_OFFLOAD); | 293 | WMI_SERVICE_BCN_MISS_OFFLOAD, len); |
291 | SVCMAP(WMI_MAIN_SERVICE_STA_PWRSAVE, | 294 | SVCMAP(WMI_MAIN_SERVICE_STA_PWRSAVE, |
292 | WMI_SERVICE_STA_PWRSAVE); | 295 | WMI_SERVICE_STA_PWRSAVE, len); |
293 | SVCMAP(WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, | 296 | SVCMAP(WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, |
294 | WMI_SERVICE_STA_ADVANCED_PWRSAVE); | 297 | WMI_SERVICE_STA_ADVANCED_PWRSAVE, len); |
295 | SVCMAP(WMI_MAIN_SERVICE_AP_UAPSD, | 298 | SVCMAP(WMI_MAIN_SERVICE_AP_UAPSD, |
296 | WMI_SERVICE_AP_UAPSD); | 299 | WMI_SERVICE_AP_UAPSD, len); |
297 | SVCMAP(WMI_MAIN_SERVICE_AP_DFS, | 300 | SVCMAP(WMI_MAIN_SERVICE_AP_DFS, |
298 | WMI_SERVICE_AP_DFS); | 301 | WMI_SERVICE_AP_DFS, len); |
299 | SVCMAP(WMI_MAIN_SERVICE_11AC, | 302 | SVCMAP(WMI_MAIN_SERVICE_11AC, |
300 | WMI_SERVICE_11AC); | 303 | WMI_SERVICE_11AC, len); |
301 | SVCMAP(WMI_MAIN_SERVICE_BLOCKACK, | 304 | SVCMAP(WMI_MAIN_SERVICE_BLOCKACK, |
302 | WMI_SERVICE_BLOCKACK); | 305 | WMI_SERVICE_BLOCKACK, len); |
303 | SVCMAP(WMI_MAIN_SERVICE_PHYERR, | 306 | SVCMAP(WMI_MAIN_SERVICE_PHYERR, |
304 | WMI_SERVICE_PHYERR); | 307 | WMI_SERVICE_PHYERR, len); |
305 | SVCMAP(WMI_MAIN_SERVICE_BCN_FILTER, | 308 | SVCMAP(WMI_MAIN_SERVICE_BCN_FILTER, |
306 | WMI_SERVICE_BCN_FILTER); | 309 | WMI_SERVICE_BCN_FILTER, len); |
307 | SVCMAP(WMI_MAIN_SERVICE_RTT, | 310 | SVCMAP(WMI_MAIN_SERVICE_RTT, |
308 | WMI_SERVICE_RTT); | 311 | WMI_SERVICE_RTT, len); |
309 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL, | 312 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL, |
310 | WMI_SERVICE_RATECTRL); | 313 | WMI_SERVICE_RATECTRL, len); |
311 | SVCMAP(WMI_MAIN_SERVICE_WOW, | 314 | SVCMAP(WMI_MAIN_SERVICE_WOW, |
312 | WMI_SERVICE_WOW); | 315 | WMI_SERVICE_WOW, len); |
313 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL_CACHE, | 316 | SVCMAP(WMI_MAIN_SERVICE_RATECTRL_CACHE, |
314 | WMI_SERVICE_RATECTRL_CACHE); | 317 | WMI_SERVICE_RATECTRL_CACHE, len); |
315 | SVCMAP(WMI_MAIN_SERVICE_IRAM_TIDS, | 318 | SVCMAP(WMI_MAIN_SERVICE_IRAM_TIDS, |
316 | WMI_SERVICE_IRAM_TIDS); | 319 | WMI_SERVICE_IRAM_TIDS, len); |
317 | SVCMAP(WMI_MAIN_SERVICE_ARPNS_OFFLOAD, | 320 | SVCMAP(WMI_MAIN_SERVICE_ARPNS_OFFLOAD, |
318 | WMI_SERVICE_ARPNS_OFFLOAD); | 321 | WMI_SERVICE_ARPNS_OFFLOAD, len); |
319 | SVCMAP(WMI_MAIN_SERVICE_NLO, | 322 | SVCMAP(WMI_MAIN_SERVICE_NLO, |
320 | WMI_SERVICE_NLO); | 323 | WMI_SERVICE_NLO, len); |
321 | SVCMAP(WMI_MAIN_SERVICE_GTK_OFFLOAD, | 324 | SVCMAP(WMI_MAIN_SERVICE_GTK_OFFLOAD, |
322 | WMI_SERVICE_GTK_OFFLOAD); | 325 | WMI_SERVICE_GTK_OFFLOAD, len); |
323 | SVCMAP(WMI_MAIN_SERVICE_SCAN_SCH, | 326 | SVCMAP(WMI_MAIN_SERVICE_SCAN_SCH, |
324 | WMI_SERVICE_SCAN_SCH); | 327 | WMI_SERVICE_SCAN_SCH, len); |
325 | SVCMAP(WMI_MAIN_SERVICE_CSA_OFFLOAD, | 328 | SVCMAP(WMI_MAIN_SERVICE_CSA_OFFLOAD, |
326 | WMI_SERVICE_CSA_OFFLOAD); | 329 | WMI_SERVICE_CSA_OFFLOAD, len); |
327 | SVCMAP(WMI_MAIN_SERVICE_CHATTER, | 330 | SVCMAP(WMI_MAIN_SERVICE_CHATTER, |
328 | WMI_SERVICE_CHATTER); | 331 | WMI_SERVICE_CHATTER, len); |
329 | SVCMAP(WMI_MAIN_SERVICE_COEX_FREQAVOID, | 332 | SVCMAP(WMI_MAIN_SERVICE_COEX_FREQAVOID, |
330 | WMI_SERVICE_COEX_FREQAVOID); | 333 | WMI_SERVICE_COEX_FREQAVOID, len); |
331 | SVCMAP(WMI_MAIN_SERVICE_PACKET_POWER_SAVE, | 334 | SVCMAP(WMI_MAIN_SERVICE_PACKET_POWER_SAVE, |
332 | WMI_SERVICE_PACKET_POWER_SAVE); | 335 | WMI_SERVICE_PACKET_POWER_SAVE, len); |
333 | SVCMAP(WMI_MAIN_SERVICE_FORCE_FW_HANG, | 336 | SVCMAP(WMI_MAIN_SERVICE_FORCE_FW_HANG, |
334 | WMI_SERVICE_FORCE_FW_HANG); | 337 | WMI_SERVICE_FORCE_FW_HANG, len); |
335 | SVCMAP(WMI_MAIN_SERVICE_GPIO, | 338 | SVCMAP(WMI_MAIN_SERVICE_GPIO, |
336 | WMI_SERVICE_GPIO); | 339 | WMI_SERVICE_GPIO, len); |
337 | SVCMAP(WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, | 340 | SVCMAP(WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, |
338 | WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); | 341 | WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, len); |
339 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, | 342 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, |
340 | WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); | 343 | WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, len); |
341 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, | 344 | SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, |
342 | WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); | 345 | WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, len); |
343 | SVCMAP(WMI_MAIN_SERVICE_STA_KEEP_ALIVE, | 346 | SVCMAP(WMI_MAIN_SERVICE_STA_KEEP_ALIVE, |
344 | WMI_SERVICE_STA_KEEP_ALIVE); | 347 | WMI_SERVICE_STA_KEEP_ALIVE, len); |
345 | SVCMAP(WMI_MAIN_SERVICE_TX_ENCAP, | 348 | SVCMAP(WMI_MAIN_SERVICE_TX_ENCAP, |
346 | WMI_SERVICE_TX_ENCAP); | 349 | WMI_SERVICE_TX_ENCAP, len); |
347 | } | 350 | } |
348 | 351 | ||
349 | #undef SVCMAP | 352 | #undef SVCMAP |