net: wireless: bcmdhd: Fixing memory leak problem in wl_get_ies

Change-Id: I26462c22ba4c3aebc1e157fbf74833c65815647c
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
Greg Goldman 2011-08-09 11:43:28 -07:00 committed by Dmitry Shmidt
parent 3fe24366a4
commit 4113f8d6da
9 changed files with 61 additions and 40 deletions

View File

@ -29,7 +29,7 @@
#include <proto/bcmeth.h>
#include <proto/bcmevent.h>
#if WLC_E_LAST != 84
#if WLC_E_LAST != 85
#error "You need to add an entry to bcmevent_names[] for the new event"
#endif
@ -115,7 +115,10 @@ const bcmevent_name_t bcmevent_names[] = {
{ WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND" },
{ WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" },
{ WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" },
{ WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" }
{ WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" },
#ifdef SOFTAP
{ WLC_E_GTK_PLUMBED, "GTK_PLUMBED" }
#endif
};

View File

@ -971,7 +971,8 @@ dhd_op_if(dhd_if_t *ifp)
memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, dhd_net_attach)) {
if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx,
dhd_net_attach)) {
ifp->state = 0;
return;
}
@ -2357,6 +2358,7 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name,
if (handle == NULL) {
ifp->state = WLC_E_IF_ADD;
ifp->idx = ifidx;
ifp->bssidx = bssidx;
ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
up(&dhd->thr_sysioc_ctl.sema);
} else

View File

@ -1026,7 +1026,9 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt)
htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
#ifdef DHD_DEBUG
tx_packets[PKTPRIO(pkt)]++;
if (PKTPRIO(pkt) < ARRAYSIZE(tx_packets)) {
tx_packets[PKTPRIO(pkt)]++;
}
if (DHD_BYTES_ON() &&
(((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
(DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {

View File

@ -33,17 +33,17 @@
#define EPI_RC_NUMBER 125
#define EPI_INCREMENTAL_NUMBER 52
#define EPI_INCREMENTAL_NUMBER 60
#define EPI_BUILD_NUMBER 0
#define EPI_VERSION 5, 90, 125, 52
#define EPI_VERSION 5, 90, 125, 60
#define EPI_VERSION_NUM 0x055a7d34
#define EPI_VERSION_NUM 0x055a7d3c
#define EPI_VERSION_DEV 5.90.125
#define EPI_VERSION_STR "5.90.125.52"
#define EPI_VERSION_STR "5.90.125.60"
#endif

View File

@ -181,7 +181,8 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_EXCESS_PM_WAKE_EVENT 81
#define WLC_E_PFN_SCAN_NONE 82
#define WLC_E_PFN_SCAN_ALLGONE 83
#define WLC_E_LAST 84
#define WLC_E_GTK_PLUMBED 84
#define WLC_E_LAST 85
typedef struct {

View File

@ -190,6 +190,7 @@ typedef struct wlc_ssid {
#define WL_SCANFLAGS_RESERVED 0x02
#define WL_SCANFLAGS_PROHIBITED 0x04
#define WL_SCAN_PARAMS_SSID_MAX 10
typedef struct wl_scan_params {
wlc_ssid_t ssid;
struct ether_addr bssid;

View File

@ -83,7 +83,7 @@ u32 wl_dbg_level = WL_DBG_ERR;
#define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAX_WAIT_TIME 3000
#define MAX_WAIT_TIME 1500
static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
@ -1118,7 +1118,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
}
s32
wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
{
struct wl_priv *wl = WL_PRIV_GET();
@ -1133,11 +1133,11 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
/* Assign the net device to CONNECT BSSCFG */
strncpy(net->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
P2PAPI_BSSCFG_CONNECTION;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx;
wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
wl_clr_p2p_status(wl, IF_ADD);
net->ifindex = idx;
wl_clr_p2p_status(wl, IF_ADD);
wake_up_interruptible(&wl->dongle_event_wait);
}
return ret;
@ -2153,7 +2153,10 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
memcpy(&join_params.params.bssid, &ether_bcast, ETHER_ADDR_LEN);
if (sme->bssid)
memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
else
memcpy(&join_params.params.bssid, &ether_bcast, ETH_ALEN);
wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
WL_DBG(("join_param_size %d\n", join_params_size));
@ -2976,12 +2979,12 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
* without turning on P2P
*/
p2p_on(wl) = true;
err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
if (unlikely(err)) {
goto exit;
}
p2p_on(wl) = true;
}
if (p2p_on(wl))
wl_cfgp2p_discover_listen(wl, target_channel, duration);
@ -3926,13 +3929,6 @@ static s32 wl_inform_bss(struct wl_priv *wl)
s32 i;
bss_list = wl->bss_list;
#if 0
if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
bss_list->version));
return -EOPNOTSUPP;
}
#endif
WL_DBG(("scanned AP count (%d)\n", bss_list->count));
bi = next_bss(bss_list, bi);
for_each_bss(bss_list, bi, i) {
@ -4279,6 +4275,14 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
assoc_info.req_len = htod32(assoc_info.req_len);
assoc_info.resp_len = htod32(assoc_info.resp_len);
assoc_info.flags = htod32(assoc_info.flags);
if (conn_info->req_ie_len) {
conn_info->req_ie_len = 0;
bzero(conn_info->req_ie, sizeof(conn_info->req_ie));
}
if (conn_info->resp_ie_len) {
conn_info->resp_ie_len = 0;
bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie));
}
if (assoc_info.req_len) {
err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
WL_ASSOC_INFO_MAX);
@ -4290,11 +4294,15 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
conn_info->req_ie_len -= ETHER_ADDR_LEN;
}
conn_info->req_ie =
kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
if (conn_info->req_ie_len <= MAX_REQ_LINE)
memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len);
else {
WL_ERR(("%s IE size %d above max %d size \n",
__FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE));
return err;
}
} else {
conn_info->req_ie_len = 0;
conn_info->req_ie = NULL;
}
if (assoc_info.resp_len) {
err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
@ -4304,11 +4312,15 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
return err;
}
conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
conn_info->resp_ie =
kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
if (conn_info->resp_ie_len <= MAX_REQ_LINE)
memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len);
else {
WL_ERR(("%s IE size %d above max %d size \n",
__FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE));
return err;
}
} else {
conn_info->resp_ie_len = 0;
conn_info->resp_ie = NULL;
}
WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
conn_info->resp_ie_len));
@ -4459,11 +4471,14 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
s32 err = 0;
WL_DBG((" enter\n"));
wl_get_assoc_ies(wl, ndev);
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
wl_update_bss_info(wl, ndev);
if (wl_get_drv_status(wl, CONNECTING)) {
wl_clr_drv_status(wl, CONNECTING);
if (completed) {
wl_get_assoc_ies(wl, ndev);
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
wl_update_bss_info(wl, ndev);
}
cfg80211_connect_result(ndev,
(u8 *)&wl->bssid,
conn_info->req_ie,
@ -6267,11 +6282,7 @@ static void wl_link_down(struct wl_priv *wl)
WL_DBG(("In\n"));
wl->link_up = false;
kfree(conn_info->req_ie);
conn_info->req_ie = NULL;
conn_info->req_ie_len = 0;
kfree(conn_info->resp_ie);
conn_info->resp_ie = NULL;
conn_info->resp_ie_len = 0;
}

View File

@ -274,10 +274,11 @@ struct wl_iscan_ctrl {
};
/* association inform */
#define MAX_REQ_LINE 1024
struct wl_connect_info {
u8 *req_ie;
u8 req_ie[MAX_REQ_LINE];
s32 req_ie_len;
u8 *resp_ie;
u8 resp_ie[MAX_REQ_LINE];
s32 resp_ie_len;
};
@ -498,7 +499,7 @@ extern void wl_cfg80211_set_sdio_func(void *func); /* set sdio function info */
extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
extern s32 wl_cfg80211_up(void); /* dongle up */
extern s32 wl_cfg80211_down(void); /* dongle down */
extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
int (*_net_attach)(dhd_pub_t *dhdp, int ifidx));
extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
extern s32 wl_cfg80211_notify_ifdel(struct net_device *net);

View File

@ -200,7 +200,7 @@ wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
{
wl_p2p_if_t ifreq;
s32 err;
struct net_device *netdev = wl_to_prmry_ndev(wl);
struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
ifreq.type = if_type;
ifreq.chspec = chspec;