Commit e1869678 authored by Dan Carpenter's avatar Dan Carpenter Committed by Kalle Valo
Browse files

mwifiex: Prevent memory corruption handling keys



The length of the key comes from the network and it's a 16 bit number.  It
needs to be capped to prevent a buffer overflow.

Fixes: 5e6e3a92 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Acked-by: default avatarGanapathi Bhat <ganapathi.bhat@nxp.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200708115857.GA13729@mwanda
parent 9187f4e8
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -580,6 +580,11 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
{
	struct host_cmd_ds_802_11_key_material *key =
						&resp->params.key_material;
	int len;

	len = le16_to_cpu(key->key_param_set.key_len);
	if (len > sizeof(key->key_param_set.key))
		return -EINVAL;

	if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
		if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
@@ -593,9 +598,8 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,

	memset(priv->aes_key.key_param_set.key, 0,
	       sizeof(key->key_param_set.key));
	priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
	memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
	       le16_to_cpu(priv->aes_key.key_param_set.key_len));
	priv->aes_key.key_param_set.key_len = cpu_to_le16(len);
	memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len);

	return 0;
}
@@ -610,9 +614,14 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
					      struct host_cmd_ds_command *resp)
{
	struct host_cmd_ds_802_11_key_material_v2 *key_v2;
	__le16 len;
	int len;

	key_v2 = &resp->params.key_material_v2;

	len = le16_to_cpu(key_v2->key_param_set.key_params.aes.key_len);
	if (len > WLAN_KEY_LEN_CCMP)
		return -EINVAL;

	if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
		if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
			mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n");
@@ -628,10 +637,9 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
	memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
	       WLAN_KEY_LEN_CCMP);
	priv->aes_key_v2.key_param_set.key_params.aes.key_len =
				key_v2->key_param_set.key_params.aes.key_len;
	len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
				cpu_to_le16(len);
	memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
	       key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));
	       key_v2->key_param_set.key_params.aes.key, len);

	return 0;
}