Date: Sat, 1 Dec 2007 08:40:06 GMT From: Weongyo Jeong <weongyo.jeong@gmail.com> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/118370: [PATCH] if_ndis - fix a scanning problem of Marvell 88W8335 chipset. Message-ID: <200712010840.lB18e6nk063489@www.freebsd.org> Resent-Message-ID: <200712010850.lB18o18w029206@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712010840.lB18e6nk063489>