aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-08-28 05:59:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:56 -0400
commit5fd8f2503b0888ed0c8e0017264059a3f9dc51c0 (patch)
treeaf5b0d441c535ebd1cc01b38662ddad92a9f2d1b /drivers/net/wireless/rndis_wlan.c
parentdb0dd396da45502e02c64c4153c5822ab5a59a5f (diff)
rndis_wlan: resize bssid list if too small
Buffer used for bssid list might be too small. Change rndis_query_oid() to return required buffer length to caller and make rndis_check_bssid_list() resize buffer when needed. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r--drivers/net/wireless/rndis_wlan.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 37796210db55..2309ad2214a0 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -676,7 +676,8 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
676 676
677 if (ret == 0) { 677 if (ret == 0) {
678 ret = le32_to_cpu(u.get_c->len); 678 ret = le32_to_cpu(u.get_c->len);
679 *len = (*len > ret) ? ret : *len; 679 if (ret > *len)
680 *len = ret;
680 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); 681 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
681 ret = rndis_error_status(u.get_c->status); 682 ret = rndis_error_status(u.get_c->status);
682 683
@@ -1656,6 +1657,9 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
1656 int ie_len, bssid_len; 1657 int ie_len, bssid_len;
1657 u8 *ie; 1658 u8 *ie;
1658 1659
1660 devdbg(usbdev, " found bssid: '%.32s' [%pM]", bssid->ssid.essid,
1661 bssid->mac);
1662
1659 /* parse bssid structure */ 1663 /* parse bssid structure */
1660 bssid_len = le32_to_cpu(bssid->length); 1664 bssid_len = le32_to_cpu(bssid->length);
1661 1665
@@ -1695,10 +1699,12 @@ static int rndis_check_bssid_list(struct usbnet *usbdev)
1695 struct ndis_80211_bssid_list_ex *bssid_list; 1699 struct ndis_80211_bssid_list_ex *bssid_list;
1696 struct ndis_80211_bssid_ex *bssid; 1700 struct ndis_80211_bssid_ex *bssid;
1697 int ret = -EINVAL, len, count, bssid_len; 1701 int ret = -EINVAL, len, count, bssid_len;
1702 bool resized = false;
1698 1703
1699 devdbg(usbdev, "check_bssid_list"); 1704 devdbg(usbdev, "check_bssid_list");
1700 1705
1701 len = CONTROL_BUFFER_SIZE; 1706 len = CONTROL_BUFFER_SIZE;
1707resize_buf:
1702 buf = kmalloc(len, GFP_KERNEL); 1708 buf = kmalloc(len, GFP_KERNEL);
1703 if (!buf) { 1709 if (!buf) {
1704 ret = -ENOMEM; 1710 ret = -ENOMEM;
@@ -1709,11 +1715,18 @@ static int rndis_check_bssid_list(struct usbnet *usbdev)
1709 if (ret != 0) 1715 if (ret != 0)
1710 goto out; 1716 goto out;
1711 1717
1718 if (!resized && len > CONTROL_BUFFER_SIZE) {
1719 resized = true;
1720 kfree(buf);
1721 goto resize_buf;
1722 }
1723
1712 bssid_list = buf; 1724 bssid_list = buf;
1713 bssid = bssid_list->bssid; 1725 bssid = bssid_list->bssid;
1714 bssid_len = le32_to_cpu(bssid->length); 1726 bssid_len = le32_to_cpu(bssid->length);
1715 count = le32_to_cpu(bssid_list->num_items); 1727 count = le32_to_cpu(bssid_list->num_items);
1716 devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count); 1728 devdbg(usbdev, "check_bssid_list: %d BSSIDs found (buflen: %d)", count,
1729 len);
1717 1730
1718 while (count && ((void *)bssid + bssid_len) <= (buf + len)) { 1731 while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
1719 rndis_bss_info_update(usbdev, bssid); 1732 rndis_bss_info_update(usbdev, bssid);