Skip to content

Commit fe0a777

Browse files
dmantipovKalle Valo
authored andcommitted
wifi: wfx: fix possible NULL pointer dereference in wfx_set_mfp_ap()
Since 'ieee80211_beacon_get()' can return NULL, 'wfx_set_mfp_ap()' should check the return value before examining skb data. So convert the latter to return an appropriate error code and propagate it to return from 'wfx_start_ap()' as well. Compile tested only. Signed-off-by: Dmitry Antipov <[email protected]> Tested-by: Jérôme Pouiller <[email protected]> Acked-by: Jérôme Pouiller <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 595b128 commit fe0a777

File tree

1 file changed

+25
-17
lines changed
  • drivers/net/wireless/silabs/wfx

1 file changed

+25
-17
lines changed

drivers/net/wireless/silabs/wfx/sta.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -336,29 +336,38 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
336336
return 0;
337337
}
338338

339-
static void wfx_set_mfp_ap(struct wfx_vif *wvif)
339+
static int wfx_set_mfp_ap(struct wfx_vif *wvif)
340340
{
341341
struct ieee80211_vif *vif = wvif_to_vif(wvif);
342342
struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
343343
const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
344-
const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
345-
skb->len - ieoffset);
346344
const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
347345
const int pairwise_cipher_suite_size = 4 / sizeof(u16);
348346
const int akm_suite_size = 4 / sizeof(u16);
347+
const u16 *ptr;
349348

350-
if (ptr) {
351-
ptr += pairwise_cipher_suite_count_offset;
352-
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
353-
return;
354-
ptr += 1 + pairwise_cipher_suite_size * *ptr;
355-
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
356-
return;
357-
ptr += 1 + akm_suite_size * *ptr;
358-
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
359-
return;
360-
wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
361-
}
349+
if (unlikely(!skb))
350+
return -ENOMEM;
351+
352+
ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
353+
skb->len - ieoffset);
354+
if (unlikely(!ptr))
355+
return -EINVAL;
356+
357+
ptr += pairwise_cipher_suite_count_offset;
358+
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
359+
return -EINVAL;
360+
361+
ptr += 1 + pairwise_cipher_suite_size * *ptr;
362+
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
363+
return -EINVAL;
364+
365+
ptr += 1 + akm_suite_size * *ptr;
366+
if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
367+
return -EINVAL;
368+
369+
wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
370+
return 0;
362371
}
363372

364373
int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -376,8 +385,7 @@ int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
376385
ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel);
377386
if (ret > 0)
378387
return -EIO;
379-
wfx_set_mfp_ap(wvif);
380-
return ret;
388+
return wfx_set_mfp_ap(wvif);
381389
}
382390

383391
void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,

0 commit comments

Comments
 (0)