From owner-freebsd-bugs@FreeBSD.ORG Sat Dec 1 08:50:01 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 59C7516A418 for ; Sat, 1 Dec 2007 08:50:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 4215D13C45D for ; Sat, 1 Dec 2007 08:50:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id lB18o1CA029207 for ; Sat, 1 Dec 2007 08:50:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id lB18o18w029206; Sat, 1 Dec 2007 08:50:01 GMT (envelope-from gnats) Resent-Date: Sat, 1 Dec 2007 08:50:01 GMT Resent-Message-Id: <200712010850.lB18o18w029206@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Weongyo Jeong Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5ACC816A421 for ; Sat, 1 Dec 2007 08:40:20 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 53B8B13C447 for ; Sat, 1 Dec 2007 08:40:20 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.2/8.14.2) with ESMTP id lB18e6F0063490 for ; Sat, 1 Dec 2007 08:40:06 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id lB18e6nk063489; Sat, 1 Dec 2007 08:40:06 GMT (envelope-from nobody) Message-Id: <200712010840.lB18e6nk063489@www.freebsd.org> Date: Sat, 1 Dec 2007 08:40:06 GMT From: Weongyo Jeong To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/118370: [PATCH] if_ndis - fix a scanning problem of Marvell 88W8335 chipset. X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 Dec 2007 08:50:01 -0000 >Number: 118370 >Category: kern >Synopsis: [PATCH] if_ndis - fix a scanning problem of Marvell 88W8335 chipset. >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Dec 01 08:50:00 UTC 2007 >Closed-Date: >Last-Modified: >Originator: Weongyo Jeong >Release: FreeBSD-CURRENT >Organization: CDNetworks >Environment: >Description: I have a Marvell 88W8335 chipset wireless NIC card and tested it with ndis(4). However, I was succeed to load drivers using ndisgen(8) but can't scan and associate with my APs. After analyzing, I found a problem of handling OID_802_11_BSSID_LIST in if_ndis.c. The problem was that if we requests NDIS driver using querying OID_802_11_BSSID_LIST with no buffer space to get a necessary buffer size like below: len = 4; error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); The return value was always 4 so I patched that when we query OID_802_11_BSSID_LIST, firstly we allocated a small space to save structures then we request like ndiswrapper of linux did. Now it works well in my case except some problems. >How-To-Repeat: >Fix: Index: if_ndis.c =================================================================== RCS file: /data/ndis/if_ndis/if_ndis.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 if_ndis.c --- if_ndis.c 1 Dec 2007 06:23:58 -0000 1.1.1.1 +++ if_ndis.c 1 Dec 2007 07:34:01 -0000 @@ -2629,13 +2629,20 @@ return(ENOENT); } - len = 4; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); + bl = malloc(len, M_TEMP, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); - bl = malloc(len, M_TEMP, M_NOWAIT|M_ZERO); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_TEMP); + bl = malloc(len, M_TEMP, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + } if (error) { free(bl, M_TEMP); device_printf(sc->ndis_dev, "bssid_list failed\n"); @@ -3066,16 +3073,28 @@ NULL, &len); if (error == 0) tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); - len = 0; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; - bl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO); + + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_DEVBUF); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, + &len); + } if (error) { free(bl, M_DEVBUF); + device_printf(sc->ndis_dev, "bssid_list failed\n"); break; } + maxaps = (2 * wreq.wi_len - sizeof(int)) / sizeof(*api); maxaps = MIN(maxaps, bl->nblx_items); wreq.wi_len = (maxaps * sizeof(*api) + sizeof(int)) / 2; @@ -3561,13 +3580,22 @@ uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; - len = 0; noise = -96; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; + + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return; + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_DEVBUF); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return; + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + } if (error) { DPRINTF(("%s: failed to read\n", __func__)); free(bl, M_DEVBUF); Patch attached with submission follows: Index: if_ndis.c =================================================================== RCS file: /data/ndis/if_ndis/if_ndis.c,v retrieving revision 1.1.1.1 diff -u -r1.1.1.1 if_ndis.c --- if_ndis.c 1 Dec 2007 06:23:58 -0000 1.1.1.1 +++ if_ndis.c 1 Dec 2007 07:34:01 -0000 @@ -2629,13 +2629,20 @@ return(ENOENT); } - len = 4; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); + bl = malloc(len, M_TEMP, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); - bl = malloc(len, M_TEMP, M_NOWAIT|M_ZERO); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_TEMP); + bl = malloc(len, M_TEMP, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + } if (error) { free(bl, M_TEMP); device_printf(sc->ndis_dev, "bssid_list failed\n"); @@ -3066,16 +3073,28 @@ NULL, &len); if (error == 0) tsleep(&error, PPAUSE|PCATCH, "ssidscan", hz * 2); - len = 0; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; - bl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO); + + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_DEVBUF); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return (ENOMEM); + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, + &len); + } if (error) { free(bl, M_DEVBUF); + device_printf(sc->ndis_dev, "bssid_list failed\n"); break; } + maxaps = (2 * wreq.wi_len - sizeof(int)) / sizeof(*api); maxaps = MIN(maxaps, bl->nblx_items); wreq.wi_len = (maxaps * sizeof(*api) + sizeof(int)) / 2; @@ -3561,13 +3580,22 @@ uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; - len = 0; noise = -96; - error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) - len = 65536; + + len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return; + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + if (error == ENOSPC) { + free(bl, M_DEVBUF); + bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (bl == NULL) + return; + + error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); + } if (error) { DPRINTF(("%s: failed to read\n", __func__)); free(bl, M_DEVBUF); >Release-Note: >Audit-Trail: >Unformatted: