aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r--drivers/net/wireless/rndis_wlan.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 989b0561c01b..5e7f344b000d 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2495,8 +2495,7 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
2495static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) 2495static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2496{ 2496{
2497 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2497 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2498 struct ndis_80211_assoc_info *info; 2498 struct ndis_80211_assoc_info *info = NULL;
2499 u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32];
2500 u8 bssid[ETH_ALEN]; 2499 u8 bssid[ETH_ALEN];
2501 int resp_ie_len, req_ie_len; 2500 int resp_ie_len, req_ie_len;
2502 u8 *req_ie, *resp_ie; 2501 u8 *req_ie, *resp_ie;
@@ -2515,23 +2514,43 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2515 resp_ie = NULL; 2514 resp_ie = NULL;
2516 2515
2517 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) { 2516 if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
2518 memset(assoc_buf, 0, sizeof(assoc_buf)); 2517 info = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
2519 info = (void *)assoc_buf; 2518 if (!info) {
2519 /* No memory? Try resume work later */
2520 set_bit(WORK_LINK_UP, &priv->work_pending);
2521 queue_work(priv->workqueue, &priv->work);
2522 return;
2523 }
2520 2524
2521 /* Get association info IEs from device and send them back to 2525 /* Get association info IEs from device. */
2522 * userspace. */ 2526 ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE);
2523 ret = get_association_info(usbdev, info, sizeof(assoc_buf));
2524 if (!ret) { 2527 if (!ret) {
2525 req_ie_len = le32_to_cpu(info->req_ie_length); 2528 req_ie_len = le32_to_cpu(info->req_ie_length);
2526 if (req_ie_len > 0) { 2529 if (req_ie_len > 0) {
2527 offset = le32_to_cpu(info->offset_req_ies); 2530 offset = le32_to_cpu(info->offset_req_ies);
2531
2532 if (offset > CONTROL_BUFFER_SIZE)
2533 offset = CONTROL_BUFFER_SIZE;
2534
2528 req_ie = (u8 *)info + offset; 2535 req_ie = (u8 *)info + offset;
2536
2537 if (offset + req_ie_len > CONTROL_BUFFER_SIZE)
2538 req_ie_len =
2539 CONTROL_BUFFER_SIZE - offset;
2529 } 2540 }
2530 2541
2531 resp_ie_len = le32_to_cpu(info->resp_ie_length); 2542 resp_ie_len = le32_to_cpu(info->resp_ie_length);
2532 if (resp_ie_len > 0) { 2543 if (resp_ie_len > 0) {
2533 offset = le32_to_cpu(info->offset_resp_ies); 2544 offset = le32_to_cpu(info->offset_resp_ies);
2545
2546 if (offset > CONTROL_BUFFER_SIZE)
2547 offset = CONTROL_BUFFER_SIZE;
2548
2534 resp_ie = (u8 *)info + offset; 2549 resp_ie = (u8 *)info + offset;
2550
2551 if (offset + resp_ie_len > CONTROL_BUFFER_SIZE)
2552 resp_ie_len =
2553 CONTROL_BUFFER_SIZE - offset;
2535 } 2554 }
2536 } 2555 }
2537 } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC)) 2556 } else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
@@ -2563,6 +2582,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2563 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 2582 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2564 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); 2583 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
2565 2584
2585 if (info != NULL)
2586 kfree(info);
2587
2566 priv->connected = true; 2588 priv->connected = true;
2567 memcpy(priv->bssid, bssid, ETH_ALEN); 2589 memcpy(priv->bssid, bssid, ETH_ALEN);
2568 2590