aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/if_ndis
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2004-03-24 05:35:03 +0000
committerBill Paul <wpaul@FreeBSD.org>2004-03-24 05:35:03 +0000
commitee219b3e07b31f6cd14d04b393d36ce876be8855 (patch)
tree9453dec0df35cf870815752ffc280a0f10a3877f /sys/dev/if_ndis
parent4d2e8e5fb815d5597ab61e62a5f907880af932d8 (diff)
downloadsrc-ee219b3e07b31f6cd14d04b393d36ce876be8855.tar.gz
src-ee219b3e07b31f6cd14d04b393d36ce876be8855.zip
The ndis_wlan_bssid_ex structure we retrieve in ndis_get_assoc() is
variable length, so we should not be trying to copy it into a fixed length buffer, especially one on the stack. malloc() a buffer of the right size and return a pointer to that instead. Fixes a crash I discovered when testing whe a Cisco AP in infrastructure mode, which returns several information elements that make the ndis_wlan_bssid_ex structure larger than expected.
Notes
Notes: svn path=/head/; revision=127349
Diffstat (limited to 'sys/dev/if_ndis')
-rw-r--r--sys/dev/if_ndis/if_ndis.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 2952405e19bd..2d5f0c6c1a73 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -112,7 +112,7 @@ static void ndis_stop (struct ndis_softc *);
static void ndis_watchdog (struct ifnet *);
static int ndis_ifmedia_upd (struct ifnet *);
static void ndis_ifmedia_sts (struct ifnet *, struct ifmediareq *);
-static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex *);
+static int ndis_get_assoc (struct ndis_softc *, ndis_wlan_bssid_ex **);
static int ndis_probe_offload (struct ndis_softc *);
static int ndis_set_offload (struct ndis_softc *);
static void ndis_getstate_80211 (struct ndis_softc *);
@@ -1713,7 +1713,7 @@ ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
static int
ndis_get_assoc(sc, assoc)
struct ndis_softc *sc;
- ndis_wlan_bssid_ex *assoc;
+ ndis_wlan_bssid_ex **assoc;
{
ndis_80211_bssid_list_ex *bl;
ndis_wlan_bssid_ex *bs;
@@ -1747,7 +1747,12 @@ ndis_get_assoc(sc, assoc)
bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0];
for (i = 0; i < bl->nblx_items; i++) {
if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) {
- bcopy((char *)bs, (char *)assoc, bs->nwbx_len);
+ *assoc = malloc(bs->nwbx_len, M_TEMP, M_NOWAIT);
+ if (*assoc == NULL) {
+ free(bl, M_TEMP);
+ return(ENOMEM);
+ }
+ bcopy((char *)bs, (char *)*assoc, bs->nwbx_len);
free(bl, M_TEMP);
return(0);
}
@@ -1765,7 +1770,7 @@ ndis_getstate_80211(sc)
struct ieee80211com *ic;
ndis_80211_ssid ssid;
ndis_80211_config config;
- ndis_wlan_bssid_ex bs;
+ ndis_wlan_bssid_ex *bs;
int rval, len, i = 0;
uint32_t arg;
struct ifnet *ifp;
@@ -1786,7 +1791,7 @@ ndis_getstate_80211(sc)
* If we're associated, retrieve info on the current bssid.
*/
if ((rval = ndis_get_assoc(sc, &bs)) == 0) {
- switch(bs.nwbx_nettype) {
+ switch(bs->nwbx_nettype) {
case NDIS_80211_NETTYPE_11FH:
case NDIS_80211_NETTYPE_11DS:
ic->ic_curmode = IEEE80211_MODE_11B;
@@ -1802,6 +1807,7 @@ ndis_getstate_80211(sc)
"unknown nettype %d\n", arg);
break;
}
+ free(bs, M_TEMP);
} else
return;