mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 22:52:35 +02:00
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:
parent
3fe24366a4
commit
4113f8d6da
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))))) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, ðer_bcast, ETHER_ADDR_LEN);
|
||||
if (sme->bssid)
|
||||
memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
|
||||
else
|
||||
memcpy(&join_params.params.bssid, ðer_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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user