aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-11-27 04:11:16 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2014-12-01 02:09:21 -0500
commit37b9f933e0a82dcf61eb692d99d7106395b8e50f (patch)
tree526c5615cb8e8f14640e3cdb6044e971ce38c486
parent2a3e60d37fc662e9c3bac2f3b960062238edb2a0 (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.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h121
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
235static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out) 236static 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
281static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out) 283static 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