From patchwork Tue May 18 08:27:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jussi Kivilinna X-Patchwork-Id: 100369 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4I8RckE021177 for ; Tue, 18 May 2010 08:27:38 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756458Ab0ERI1h (ORCPT ); Tue, 18 May 2010 04:27:37 -0400 Received: from sirokuusama.dnainternet.net ([83.102.40.133]:53133 "EHLO sirokuusama.dnainternet.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752490Ab0ERI1e (ORCPT ); Tue, 18 May 2010 04:27:34 -0400 Received: from localhost (localhost [127.0.0.1]) by sirokuusama.dnainternet.net (Postfix) with ESMTP id 516542BECA; Tue, 18 May 2010 11:27:32 +0300 (EEST) X-Virus-Scanned: DNA Postiturva at dnainternet.net X-Spam-Flag: NO X-Spam-Score: -1.36 X-Spam-Level: X-Spam-Status: No, score=-1.36 tagged_above=-9999 required=6 tests=[ALL_TRUSTED=-1.36] Received: from sirokuusama.dnainternet.net ([83.102.40.133]) by localhost (sirokuusama.dnainternet.net [127.0.0.1]) (amavisd-new, port 10041) with ESMTP id mZ3Ws2Vn6dO6; Tue, 18 May 2010 11:27:32 +0300 (EEST) Received: from omenapuu.dnainternet.net (omenapuu.dnainternet.net [83.102.40.212]) by sirokuusama.dnainternet.net (Postfix) with ESMTP id DF4842C141; Tue, 18 May 2010 11:27:31 +0300 (EEST) Received: from fate.lan (dyn2-85-23-163-72.psoas.suomi.net [85.23.163.72]) by omenapuu.dnainternet.net (Postfix) with ESMTP id 9940E2BAED; Tue, 18 May 2010 11:27:31 +0300 (EEST) Subject: [PATCH] rndis_wlan: increase assocbuf size and validate association info offsets from driver To: "John W. Linville" From: Jussi Kivilinna Cc: linux-wireless@vger.kernel.org Date: Tue, 18 May 2010 11:27:31 +0300 Message-ID: <20100518082731.25486.42902.stgit@fate.lan> User-Agent: StGit/0.15 MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 18 May 2010 08:27:39 +0000 (UTC) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index b280ad1..939e66e 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) static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); - struct ndis_80211_assoc_info *info; - u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32]; + struct ndis_80211_assoc_info *info = NULL; u8 bssid[ETH_ALEN]; int resp_ie_len, req_ie_len; u8 *req_ie, *resp_ie; @@ -2515,23 +2514,43 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) resp_ie = NULL; if (priv->infra_mode == NDIS_80211_INFRA_INFRA) { - memset(assoc_buf, 0, sizeof(assoc_buf)); - info = (void *)assoc_buf; + info = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); + if (!info) { + /* No memory? Try resume work later */ + set_bit(WORK_LINK_UP, &priv->work_pending); + queue_work(priv->workqueue, &priv->work); + return; + } - /* Get association info IEs from device and send them back to - * userspace. */ - ret = get_association_info(usbdev, info, sizeof(assoc_buf)); + /* Get association info IEs from device. */ + ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); if (!ret) { req_ie_len = le32_to_cpu(info->req_ie_length); if (req_ie_len > 0) { offset = le32_to_cpu(info->offset_req_ies); + + if (offset > CONTROL_BUFFER_SIZE) + offset = CONTROL_BUFFER_SIZE; + req_ie = (u8 *)info + offset; + + if (offset + req_ie_len > CONTROL_BUFFER_SIZE) + req_ie_len = + CONTROL_BUFFER_SIZE - offset; } resp_ie_len = le32_to_cpu(info->resp_ie_length); if (resp_ie_len > 0) { offset = le32_to_cpu(info->offset_resp_ies); + + if (offset > CONTROL_BUFFER_SIZE) + offset = CONTROL_BUFFER_SIZE; + resp_ie = (u8 *)info + offset; + + if (offset + resp_ie_len > CONTROL_BUFFER_SIZE) + resp_ie_len = + CONTROL_BUFFER_SIZE - offset; } } } 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) } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); + if (info != NULL) + kfree(info); + priv->connected = true; memcpy(priv->bssid, bssid, ETH_ALEN);