Function iwlagn_send_sta_key() was trying to write across multiple structure members in a single memcpy(). Add a struct group "keys" to let the compiler see the intended bounds of the memcpy, which includes the tkip keys as well. Silences false positive memcpy() run-time warning: memcpy: detected field-spanning write (size 32) of single field "sta_cmd.key.key" at drivers/net/wireless/intel/iwlwifi/dvm/sta.c:1103 (size 16) Link: https://www.alionet.org/index.php?topic=1469.0 Cc: Gregory Greenman <gregory.greenman@xxxxxxxxx> Cc: Kalle Valo <kvalo@xxxxxxxxxx> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Eric Dumazet <edumazet@xxxxxxxxxx> Cc: Jakub Kicinski <kuba@xxxxxxxxxx> Cc: Paolo Abeni <pabeni@xxxxxxxxxx> Cc: Johannes Berg <johannes.berg@xxxxxxxxx> Cc: Benjamin Berg <benjamin.berg@xxxxxxxxx> Cc: Sriram R <quic_srirrama@xxxxxxxxxxx> Cc: linux-wireless@xxxxxxxxxxxxxxx Cc: netdev@xxxxxxxxxxxxxxx Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> --- drivers/net/wireless/intel/iwlwifi/dvm/commands.h | 10 ++++++---- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h index 75a4b8e26232..0eceac4b9131 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/intel/iwlwifi/dvm/commands.h @@ -783,10 +783,12 @@ struct iwl_keyinfo { __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ u8 key_offset; u8 reserved2; - u8 key[16]; /* 16-byte unicast decryption key */ - __le64 tx_secur_seq_cnt; - __le64 hw_tkip_mic_rx_key; - __le64 hw_tkip_mic_tx_key; + struct_group(keys, + u8 key[16]; /* 16-byte unicast decryption key */ + __le64 tx_secur_seq_cnt; + __le64 hw_tkip_mic_rx_key; + __le64 hw_tkip_mic_tx_key; + ); } __packed; /** diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c index cef43cf80620..a1c9e201b058 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -1093,14 +1093,14 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_CCMP: key_flags |= STA_KEY_FLG_CCMP; - memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); + memcpy(&sta_cmd.key.keys, keyconf->key, keyconf->keylen); break; case WLAN_CIPHER_SUITE_TKIP: key_flags |= STA_KEY_FLG_TKIP; sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; for (i = 0; i < 5; i++) sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); - memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); + memcpy(&sta_cmd.key.keys, keyconf->key, keyconf->keylen); break; case WLAN_CIPHER_SUITE_WEP104: key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; -- 2.34.1