Commit 6390d885 authored by Daniel Drake's avatar Daniel Drake Committed by John W. Linville

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: default avatarDaniel Drake <dsd@laptop.org>
Acked-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3c68ef5b
...@@ -669,9 +669,8 @@ static void mwifiex_set_multicast_list(struct net_device *dev) ...@@ -669,9 +669,8 @@ static void mwifiex_set_multicast_list(struct net_device *dev)
mcast_list.mode = MWIFIEX_ALL_MULTI_MODE; mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
} else { } else {
mcast_list.mode = MWIFIEX_MULTICAST_MODE; mcast_list.mode = MWIFIEX_MULTICAST_MODE;
if (netdev_mc_count(dev)) mcast_list.num_multicast_addr =
mcast_list.num_multicast_addr = mwifiex_copy_mcast_addr(&mcast_list, dev);
mwifiex_copy_mcast_addr(&mcast_list, dev);
} }
mwifiex_request_set_multicast_list(priv, &mcast_list); mwifiex_request_set_multicast_list(priv, &mcast_list);
} }
......
...@@ -104,16 +104,14 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, ...@@ -104,16 +104,14 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
} else { } else {
priv->curr_pkt_filter &= priv->curr_pkt_filter &=
~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE; ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
if (mcast_list->num_multicast_addr) { dev_dbg(priv->adapter->dev,
dev_dbg(priv->adapter->dev, "info: Set multicast list=%d\n",
"info: Set multicast list=%d\n", mcast_list->num_multicast_addr);
mcast_list->num_multicast_addr); /* Send multicast addresses to firmware */
/* Send multicast addresses to firmware */ ret = mwifiex_send_cmd_async(priv,
ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_CMD_MAC_MULTICAST_ADR, HostCmd_ACT_GEN_SET, 0,
HostCmd_ACT_GEN_SET, 0, mcast_list);
mcast_list);
}
} }
} }
dev_dbg(priv->adapter->dev, dev_dbg(priv->adapter->dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment