aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2013-06-14 15:24:24 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-13 19:08:28 -0400
commit9e65b308202a4e6536c5b453d6b37fd0467dd5d2 (patch)
treeea0855b1c39122eb6dc06ae502cda31e982366d9 /drivers/net/wireless/mwifiex
parentcac65253a9c5a30d4c8d7bc4c60197935f9e2e70 (diff)
mwifiex: fix memory corruption when unsetting multicast list
commit 6390d88529835a8ad3563fe01a5da89fa52d6db2 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/main.c5
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c18
2 files changed, 10 insertions, 13 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index c4a2e775fe1a..8fc44992b5c3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -559,9 +559,8 @@ static void mwifiex_set_multicast_list(struct net_device *dev)
559 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; 559 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
560 } else { 560 } else {
561 mcast_list.mode = MWIFIEX_MULTICAST_MODE; 561 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
562 if (netdev_mc_count(dev)) 562 mcast_list.num_multicast_addr =
563 mcast_list.num_multicast_addr = 563 mwifiex_copy_mcast_addr(&mcast_list, dev);
564 mwifiex_copy_mcast_addr(&mcast_list, dev);
565 } 564 }
566 mwifiex_request_set_multicast_list(priv, &mcast_list); 565 mwifiex_request_set_multicast_list(priv, &mcast_list);
567} 566}
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,
104 } else { 104 } else {
105 priv->curr_pkt_filter &= 105 priv->curr_pkt_filter &=
106 ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; 106 ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
107 if (mcast_list->num_multicast_addr) { 107 dev_dbg(priv->adapter->dev,
108 dev_dbg(priv->adapter->dev, 108 "info: Set multicast list=%d\n",
109 "info: Set multicast list=%d\n", 109 mcast_list->num_multicast_addr);
110 mcast_list->num_multicast_addr); 110 /* Send multicast addresses to firmware */
111 /* Send multicast addresses to firmware */ 111 ret = mwifiex_send_cmd_async(priv,
112 ret = mwifiex_send_cmd_async(priv, 112 HostCmd_CMD_MAC_MULTICAST_ADR,
113 HostCmd_CMD_MAC_MULTICAST_ADR, 113 HostCmd_ACT_GEN_SET, 0,
114 HostCmd_ACT_GEN_SET, 0, 114 mcast_list);
115 mcast_list);
116 }
117 } 115 }
118 } 116 }
119 dev_dbg(priv->adapter->dev, 117 dev_dbg(priv->adapter->dev,