wifi: iwlwifi: mvm: Use __counted_by() and avoid -Wfamnae warnings
Subsystems (4)
PATCH 1/1 wifi: iwlwifi: mvm: Use __counted_by() and avoid -Wfamnae warnings
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.
So, use the DEFINE_FLEX() helper for multiple on-stack definitions of flexible structures where the size of their flexible-array members are known at compile-time, and refactor the rest of the code, accordingly.
In order to allow for the use of DEFINE_FLEX(), a couple of structures were annotated with the __counted_by() attribute.
With these changes, fix the following warnings:drivers/net/wireless/intel/iwlwifi/mvm/d3.c:124:52: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2053:51: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2148:43: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2211:43: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
--- .../net/wireless/intel/iwlwifi/fw/api/sta.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 126 ++++++++---------- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- include/net/mac80211.h | 2 +- 4 files changed, 61 insertions(+), 71 deletions(-)
drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +1 -1
@@ -479,7 +479,7 @@ struct iwl_mvm_wep_key_cmd {u8 decryption_type;u8 flags;u8 reserved; -struct iwl_mvm_wep_key wep_key[]; + struct iwl_mvm_wep_key wep_key[] __counted_by(num_keys); } __packed;/* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */ /**
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +58 -68
237 lines not on this page · raw message
drivers/net/wireless/intel/iwlwifi/mvm/sta.c +1 -1
@@ -4350,8 +4350,8 @@ int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, goto out; keyconf->cipher = cipher; -memcpy (keyconf->key, key, key_len); keyconf->keylen = key_len; +memcpy (keyconf->key, key, keyconf->key_len); keyconf->flags =IEEE80211_KEY_FLAG_PAIRWISE ;if (mld) {
include/net/mac80211.h +1 -1
@@ -2222,7 +2222,7 @@ struct ieee80211_key_conf {u16 flags;s8 link_id;u8 keylen; -u8 key[]; + u8 key[] __counted_by(keylen); };#define IEEE80211_MAX_PN_LEN 16
Signature · 1 line
2.34.1
Quoted 188 lines · Gustavo A. R. Silva
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.
So, use the
DEFINE_FLEX()helper for multiple on-stack definitions of flexible structures where the size of their flexible-array members are known at compile-time, and refactor the rest of the code, accordingly.In order to allow for the use of
DEFINE_FLEX(), a couple of structures were annotated with the__counted_by()attribute.With these changes, fix the following warnings:
drivers/net/wireless/intel/iwlwifi/mvm/d3.c:124:52: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2053:51: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2148:43: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]drivers/net/wireless/intel/iwlwifi/mvm/d3.c:2211:43: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]Signed-off-by Gustavo A. R. Silva <[email protected]>--- .../net/wireless/intel/iwlwifi/fw/api/sta.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 126 ++++++++---------- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 +- include/net/mac80211.h | 2 +- 4 files changed, 61 insertions(+), 71 deletions(-)drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +1
-1@@ -479,7 +479,7 @@ struct iwl_mvm_wep_key_cmd {u8 decryption_type;u8 flags;u8 reserved; -struct iwl_mvm_wep_key wep_key[]; + struct iwl_mvm_wep_key wep_key[] __counted_by(num_keys); } __packed;/* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */ /** drivers/net/wireless/intel/iwlwifi/mvm/d3.c +34
-42@@ -120,19 +120,15 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,switch (key->cipher) {case WLAN_CIPHER_SUITE_WEP40 :case WLAN_CIPHER_SUITE_WEP104 : {/* hack it for now */ -struct { -struct iwl_mvm_wep_key_cmd wep_key_cmd; -struct iwl_mvm_wep_key wep_key; - } __packed wkc = { - .wep_key_cmd.mac_id_n_color = -cpu_to_le32 (FW_CMD_ID_AND_COLOR (mvmvif->id, - mvmvif->color)), - .wep_key_cmd.num_keys =1 , -/* firmware sets STA_KEY_FLG_WEP_13BYTES */ - .wep_key_cmd.decryption_type =STA_KEY_FLG_WEP , - .wep_key.key_index = key->keyidx, - .wep_key.key_size = key->keylen, - }; + DEFINE_FLEX(struct iwl_mvm_wep_key_cmd, wkc, wep_key, num_keys, 1); + + wkc->mac_id_n_color = +cpu_to_le32 (FW_CMD_ID_AND_COLOR (mvmvif->id, + mvmvif->color)); +/* firmware sets STA_KEY_FLG_WEP_13BYTES */ + wkc->decryption_type =STA_KEY_FLG_WEP ; + wkc->wep_key[0 ].key_index = key->keyidx; + wkc->wep_key[0 ].key_size = key->keylen;/* * This will fail -- the key functions don't set support @@ -142,18 +138,18 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,if (key->flags &IEEE80211_KEY_FLAG_PAIRWISE )break ; -memcpy (&wkc.wep_key.key[3 ], key->key, key->keylen); +memcpy (&wkc->wep_key[0 ].key[3 ], key->key, key->keylen);if (key->keyidx == mvmvif->tx_key_idx) {/* TX key must be at offset 0 */ - wkc.wep_key.key_offset =0 ; + wkc->wep_key[0 ].key_offset =0 ; }else {/* others start at 1 */ data->wep_key_idx++; - wkc.wep_key.key_offset = data->wep_key_idx; + wkc->wep_key[0 ].key_offset = data->wep_key_idx; }mutex_lock (&mvm->mutex); - ret =iwl_mvm_send_cmd_pdu (mvm,WEP_KEY ,0 ,sizeof (wkc), &wkc); + ret =iwl_mvm_send_cmd_pdu (mvm,WEP_KEY ,0 ,__struct_size (wkc), wkc); data->error = ret !=0 ; mvm->ptk_ivlen = key->iv_len;@@ -2049,10 +2045,8 @@ static bool iwl_mvm_mlo_gtk_rekey(struct iwl_wowlan_status_data *status,struct iwl_wowlan_mlo_gtk *mlo_key = &status->mlo_keys[i];struct ieee80211_key_conf *key, *old_key;struct ieee80211_key_seq seq; -struct { -struct ieee80211_key_conf conf; -u8 key[32 ]; - } conf = {}; + DEFINE_FLEX(struct ieee80211_key_conf, conf, key, keylen, + WOWLAN_KEY_MAX_SIZE);u16 flags =le16_to_cpu (mlo_key->flags);int j, link_id, key_id, key_type;@@ -2069,40 +2063,40 @@ static bool iwl_mvm_mlo_gtk_rekey(struct iwl_wowlan_status_data *status, key_type >= WOWLAN_MLO_GTK_KEY_NUM_TYPES))continue ; - conf.conf.cipher = old_keys->cipher[link_id][key_type]; + conf->cipher = old_keys->cipher[link_id][key_type];/* WARN_ON? */ -if (!conf.conf.cipher) +if (!conf->cipher)continue ; - conf.conf.keylen =0 ; -switch (conf.conf.cipher) { + conf->keylen =0 ; +switch (conf->cipher) {case WLAN_CIPHER_SUITE_CCMP :case WLAN_CIPHER_SUITE_GCMP : - conf.conf.keylen =WLAN_KEY_LEN_CCMP ; + conf->keylen =WLAN_KEY_LEN_CCMP ;break ;case WLAN_CIPHER_SUITE_GCMP_256 : - conf.conf.keylen =WLAN_KEY_LEN_GCMP_256 ; + conf->keylen =WLAN_KEY_LEN_GCMP_256 ;break ;case WLAN_CIPHER_SUITE_BIP_GMAC_128 : - conf.conf.keylen =WLAN_KEY_LEN_BIP_GMAC_128 ; + conf->keylen =WLAN_KEY_LEN_BIP_GMAC_128 ;break ;case WLAN_CIPHER_SUITE_BIP_GMAC_256 : - conf.conf.keylen =WLAN_KEY_LEN_BIP_GMAC_256 ; + conf->keylen =WLAN_KEY_LEN_BIP_GMAC_256 ;break ;case WLAN_CIPHER_SUITE_AES_CMAC : - conf.conf.keylen =WLAN_KEY_LEN_AES_CMAC ; + conf->keylen =WLAN_KEY_LEN_AES_CMAC ;break ;case WLAN_CIPHER_SUITE_BIP_CMAC_256 : - conf.conf.keylen =WLAN_KEY_LEN_BIP_CMAC_256 ; + conf->keylen =WLAN_KEY_LEN_BIP_CMAC_256 ;break ; } -if (WARN_ON (!conf.conf.keylen || - conf.conf.keylen >sizeof (conf.key))) +if (WARN_ON (!conf->keylen || + conf->keylen >WOWLAN_KEY_MAX_SIZE ))continue ; -memcpy (conf.conf.key, mlo_key->key, conf.conf.keylen); - conf.conf.keyidx = key_id; +memcpy (conf->key, mlo_key->key, conf->keylen); + conf->keyidx = key_id; old_key = old_keys->key[link_id][key_id];if (old_key) {@@ -2114,7 +2108,7 @@ static bool iwl_mvm_mlo_gtk_rekey(struct iwl_wowlan_status_data *status,IWL_DEBUG_WOWLAN (mvm,"Add MLO key id %d, link id %d\n" , key_id, link_id); - key =ieee80211_gtk_rekey_add (vif, &conf.conf, link_id); + key =ieee80211_gtk_rekey_add (vif, conf, link_id);if (WARN_ON (IS_ERR (key))) { ret = false; goto out;@@ -2144,30 +2138,28 @@ static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status, {int i, j;struct ieee80211_key_conf *key; -struct { -struct ieee80211_key_conf conf; -u8 key[32 ]; - } conf = { - .conf.cipher = gtk_cipher, - }; + DEFINE_FLEX(struct ieee80211_key_conf, conf, key, keylen, + WOWLAN_KEY_MAX_SIZE);int link_id = vif->active_links ?__ffs (vif->active_links) :-1 ; + conf->cipher = gtk_cipher; +
drivers/net/wireless/intel/iwlwifi/mvm/d3.c static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status, · line 2152
Quoted 10 lines
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +4
-4BUILD_BUG_ON (WLAN_KEY_LEN_CCMP !=WLAN_KEY_LEN_GCMP ); -BUILD_BUG_ON (sizeof (conf.key) <WLAN_KEY_LEN_CCMP ); -BUILD_BUG_ON (sizeof (conf.key) <WLAN_KEY_LEN_GCMP_256 ); -BUILD_BUG_ON (sizeof (conf.key) <WLAN_KEY_LEN_TKIP ); -BUILD_BUG_ON (sizeof (conf.key) <sizeof (status->gtk[0 ].key)); +BUILD_BUG_ON (conf->keylen <WLAN_KEY_LEN_CCMP ); +BUILD_BUG_ON (conf->keylen <WLAN_KEY_LEN_GCMP_256 ); +BUILD_BUG_ON (conf->keylen <WLAN_KEY_LEN_TKIP ); +BUILD_BUG_ON (conf->keylen <sizeof (status->gtk[0 ].key));
Even though the mystery re __ffs() has been solved, I wonder if these BUILD_BUG()s still make sense: their purpose appears to have been to ensure that the key[] member is of sufficient size, and this is now guaranteed. So I think we should just drop them.
In the general case, using BUILD_BUG() on a value of a local variable like this is always going to be fragile. Compilers are free to reorder code, and some function calls are implicit, or have global side effects that may prevent the compiler from making any assumptions about these values at the point of the BUILD_BUG() invocation.