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

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
...@@ -580,6 +580,11 @@ static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv, ...@@ -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 = struct host_cmd_ds_802_11_key_material *key =
&resp->params.key_material; &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->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { 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, ...@@ -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, memset(priv->aes_key.key_param_set.key, 0,
sizeof(key->key_param_set.key)); sizeof(key->key_param_set.key));
priv->aes_key.key_param_set.key_len = 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, memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len);
le16_to_cpu(priv->aes_key.key_param_set.key_len));
return 0; return 0;
} }
...@@ -610,9 +614,14 @@ static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv, ...@@ -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_command *resp)
{ {
struct host_cmd_ds_802_11_key_material_v2 *key_v2; struct host_cmd_ds_802_11_key_material_v2 *key_v2;
__le16 len; int len;
key_v2 = &resp->params.key_material_v2; 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->action) == HostCmd_ACT_GEN_SET) {
if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) { if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n"); 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, ...@@ -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, memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
WLAN_KEY_LEN_CCMP); WLAN_KEY_LEN_CCMP);
priv->aes_key_v2.key_param_set.key_params.aes.key_len = priv->aes_key_v2.key_param_set.key_params.aes.key_len =
key_v2->key_param_set.key_params.aes.key_len; cpu_to_le16(len);
len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key, 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; return 0;
} }
......
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