diff mbox series

[next] wifi: iwlwifi: mvm: Use __counted_by() and avoid -Wfamnae warnings

Message ID ZrZrNfUZtUIqvbUI@cute (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [next] wifi: iwlwifi: mvm: Use __counted_by() and avoid -Wfamnae warnings | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 29 this patch: 18
netdev/build_tools success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 3 maintainers not CCed: kees@kernel.org shaul.triebitz@intel.com gregory.greenman@intel.com
netdev/build_clang fail Errors and warnings before: 29 this patch: 19
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 38 this patch: 27
netdev/checkpatch warning WARNING: Comparisons should place the constant on the right side of the test WARNING: line length of 83 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 4 this patch: 4
netdev/source_inline success Was 0 now: 0

Commit Message

Gustavo A. R. Silva Aug. 9, 2024, 7:17 p.m. UTC
-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 <gustavoars@kernel.org>
---
 .../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(-)

Comments

Ard Biesheuvel Sept. 16, 2024, 10:40 a.m. UTC | #1
On Fri, 9 Aug 2024 at 21:17, Gustavo A. R. Silva <gustavoars@kernel.org> wrote:
>
> -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 <gustavoars@kernel.org>
> ---
>  .../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(-)
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
> index d7f8a276b683..fe6bd34fefa3 100644
> --- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
> +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
> @@ -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 */
>
>  /**
> diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
> index b4d650583ac2..b19579dd8de3 100644
> --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
> +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
> @@ -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;
> +
>         BUILD_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.
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
index d7f8a276b683..fe6bd34fefa3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
@@ -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 */
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index b4d650583ac2..b19579dd8de3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -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;
+
 	BUILD_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));
 
 	switch (gtk_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_TKIP:
-		conf.conf.keylen = WLAN_KEY_LEN_TKIP;
+		conf->keylen = WLAN_KEY_LEN_TKIP;
 		break;
 	default:
 		WARN_ON(1);
@@ -2177,14 +2169,14 @@  static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status,
 		if (!status->gtk[i].len)
 			continue;
 
-		conf.conf.keyidx = status->gtk[i].id;
+		conf->keyidx = status->gtk[i].id;
 		IWL_DEBUG_WOWLAN(mvm,
 				 "Received from FW GTK cipher %d, key index %d\n",
-				 conf.conf.cipher, conf.conf.keyidx);
-		memcpy(conf.conf.key, status->gtk[i].key,
+				 conf->cipher, conf->keyidx);
+		memcpy(conf->key, status->gtk[i].key,
 		       sizeof(status->gtk[i].key));
 
-		key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id);
+		key = ieee80211_gtk_rekey_add(vif, conf, link_id);
 		if (IS_ERR(key))
 			return false;
 
@@ -2207,41 +2199,39 @@  iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status,
 				struct iwl_multicast_key_data *key_data)
 {
 	struct ieee80211_key_conf *key_config;
-	struct {
-		struct ieee80211_key_conf conf;
-		u8 key[WOWLAN_KEY_MAX_SIZE];
-	} conf = {
-		.conf.cipher = cipher,
-		.conf.keyidx = key_data->id,
-	};
+	DEFINE_FLEX(struct ieee80211_key_conf, conf, key, keylen,
+		    WOWLAN_KEY_MAX_SIZE);
 	struct ieee80211_key_seq seq;
 	int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
 
+	conf->cipher = cipher;
+	conf->keyidx = key_data->id;
+
 	if (!key_data->len)
 		return true;
 
-	iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, conf.conf.cipher);
+	iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, conf->cipher);
 
 	switch (cipher) {
 	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;
 	default:
 		WARN_ON(1);
 	}
-	BUILD_BUG_ON(sizeof(conf.key) < sizeof(key_data->key));
-	memcpy(conf.conf.key, key_data->key, conf.conf.keylen);
+	BUILD_BUG_ON(WOWLAN_KEY_MAX_SIZE < sizeof(key_data->key));
+	memcpy(conf->key, key_data->key, conf->keylen);
 
-	key_config = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id);
+	key_config = ieee80211_gtk_rekey_add(vif, conf, link_id);
 	if (IS_ERR(key_config))
 		return false;
 	ieee80211_set_key_rx_seq(key_config, 0, &seq);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 15e64d94d6ea..7e550d880584 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -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) {
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 0a04eaf5343c..d3f6056daf8a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -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