| From abfb3cc1d7f5cf8b0cbad4a1d04bdea8dd450ab7 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 8 Jul 2020 14:58:57 +0300 |
| Subject: mwifiex: Prevent memory corruption handling keys |
| |
| From: Dan Carpenter <dan.carpenter@oracle.com> |
| |
| [ Upstream commit e18696786548244914f36ec3c46ac99c53df99c3 ] |
| |
| 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: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") |
| Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Acked-by: Ganapathi Bhat <ganapathi.bhat@nxp.com> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Link: https://lore.kernel.org/r/20200708115857.GA13729@mwanda |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../wireless/marvell/mwifiex/sta_cmdresp.c | 22 +++++++++++++------ |
| 1 file changed, 15 insertions(+), 7 deletions(-) |
| |
| diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |
| index f21660149f584..962d8bfe6f101 100644 |
| --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |
| +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |
| @@ -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; |
| } |
| -- |
| 2.25.1 |
| |