diff options
author | Daniel Drake <dsd@laptop.org> | 2013-06-14 21:24:24 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-17 20:38:51 +0200 |
commit | 6390d88529835a8ad3563fe01a5da89fa52d6db2 (patch) | |
tree | 0761f683f4a31ff7cdba5c1e1ed9cfd9d1422e4e /drivers/net/wireless | |
parent | mwifiex: Add module parameter for regdomain (diff) | |
download | linux-6390d88529835a8ad3563fe01a5da89fa52d6db2.tar.xz linux-6390d88529835a8ad3563fe01a5da89fa52d6db2.zip |
mwifiex: fix memory corruption when unsetting multicast list
When trying to unset a previously-set multicast list (i.e. the new list
has 0 entries), mwifiex_set_multicast_list() was calling down to
mwifiex_request_set_multicast_list() while leaving
mcast_list.num_multicast_addr as an uninitialized value.
We were arriving at mwifiex_cmd_mac_multicast_adr() which would then
proceed to do an often huge memcpy of
mcast_list.num_multicast_addr*ETH_ALEN bytes, causing memory corruption
and hard to debug crashes.
Fix this by setting mcast_list.num_multicast_addr to 0 when no multicast
list is provided. Similarly, fix up the logic in
mwifiex_request_set_multicast_list() to unset the multicast list that
was previously sent to the hardware in such cases.
Signed-off-by: Daniel Drake <dsd@laptop.org>
Acked-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/mwifiex/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/mwifiex/sta_ioctl.c | 18 |
2 files changed, 10 insertions, 13 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 485871940d3c..e15ab72fb03d 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -669,9 +669,8 @@ static void mwifiex_set_multicast_list(struct net_device *dev) mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; } else { mcast_list.mode = MWIFIEX_MULTICAST_MODE; - if (netdev_mc_count(dev)) - mcast_list.num_multicast_addr = - mwifiex_copy_mcast_addr(&mcast_list, dev); + mcast_list.num_multicast_addr = + mwifiex_copy_mcast_addr(&mcast_list, dev); } mwifiex_request_set_multicast_list(priv, &mcast_list); } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 1a8a19dbd635..23aa910bc5d0 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -104,16 +104,14 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, } else { priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; - if (mcast_list->num_multicast_addr) { - dev_dbg(priv->adapter->dev, - "info: Set multicast list=%d\n", - mcast_list->num_multicast_addr); - /* Send multicast addresses to firmware */ - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_MAC_MULTICAST_ADR, - HostCmd_ACT_GEN_SET, 0, - mcast_list); - } + dev_dbg(priv->adapter->dev, + "info: Set multicast list=%d\n", + mcast_list->num_multicast_addr); + /* Send multicast addresses to firmware */ + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + HostCmd_ACT_GEN_SET, 0, + mcast_list); } } dev_dbg(priv->adapter->dev, |