Re: [PATCH] wifi: mwifiex: replace one-element arrays with flexible array members

From: George Valkov

Date: Wed Jul 15 2026 - 19:00:41 EST


Thank you for your help!
Please backport to 6.18 and 6.12, which are used by OpenWrt.

v2:
- restore the unions and use DECLARE_FLEX_ARRAY
for the flexible arrays inside
- restore use of sizeof(*member) instead of sizeof(struct)


From 654af1e2be5e0d2269a108f050dfbcbf1ad79262 Mon Sep 17 00:00:00 2001
From: Georgi Valkov <gvalkov@xxxxxxxxx>
Date: Thu, 16 Jul 2026 12:28:00 +0300
Subject: [PATCH v2] wifi: mwifiex: replace one-element arrays with flexible array
members

Replace deprecated one-element arrays with flexible array members.
CONFIG_FORTIFY_SOURCE reports the following warning when
one-element arrays are used as variable-length buffers:

sta_cmd.c:1033 mwifiex_sta_prepare_cmd
memcpy: detected field-spanning write (size 84) of single field
"domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)

Convert affected structs to use flexible array members.
- Preserve existing wire layouts.
- Use DECLARE_FLEX_ARRAY for structs inside affected unions.

Tested-on: WRT3200ACM, OpenWrt
Signed-off-by: Georgi Valkov <gvalkov@xxxxxxxxx>
---
drivers/net/wireless/marvell/mwifiex/fw.h | 18 +++++++++---------
drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++----
drivers/net/wireless/marvell/mwifiex/sta_cmd.c | 2 +-
3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index e9e896606912..93561116959a 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -823,7 +823,7 @@ struct chan_band_param_set {
struct mwifiex_ie_types_chan_band_list_param_set {
struct mwifiex_ie_types_header header;
- struct chan_band_param_set chan_band_param[1];
+ struct chan_band_param_set chan_band_param[];
} __packed;
struct mwifiex_ie_types_rates_param_set {
@@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
#define TSF_DATA_SIZE 8
struct mwifiex_ie_types_tsf_timestamp {
struct mwifiex_ie_types_header header;
- u8 tsf_data[1];
+ u8 tsf_data[];
} __packed;
struct mwifiex_cf_param_set {
@@ -903,8 +903,8 @@ struct mwifiex_ibss_param_set {
struct mwifiex_ie_types_ss_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_cf_param_set cf_param_set[1];
- struct mwifiex_ibss_param_set ibss_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_cf_param_set, cf_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ibss_param_set, ibss_param_set);
} cf_ibss;
} __packed;
@@ -922,8 +922,8 @@ struct mwifiex_ds_param_set {
struct mwifiex_ie_types_phy_param_set {
struct mwifiex_ie_types_header header;
union {
- struct mwifiex_fh_param_set fh_param_set[1];
- struct mwifiex_ds_param_set ds_param_set[1];
+ DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set);
+ DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set);
} fh_ds;
} __packed;
@@ -1383,7 +1383,7 @@ struct host_cmd_ds_802_11_snmp_mib {
__le16 query_type;
__le16 oid;
__le16 buf_size;
- u8 value[1];
+ u8 value[];
} __packed;
struct mwifiex_rate_scope {
@@ -1551,7 +1551,7 @@ struct mwifiex_scan_cmd_config {
* TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
* WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
*/
- u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
+ u8 tlv_buf[]; /* SSID TLV(s) and ChanList TLVs are stored
here */
} __packed;
@@ -1683,7 +1683,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
struct mwifiex_ietypes_domain_param_set {
struct mwifiex_ie_types_header header;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
- struct ieee80211_country_ie_triplet triplet[1];
+ struct ieee80211_country_ie_triplet triplet[];
} __packed;
struct host_cmd_ds_802_11d_domain_info {
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
index 5a1a0287c1d5..a83f4d081fe2 100644
--- a/drivers/net/wireless/marvell/mwifiex/join.c
+++ b/drivers/net/wireless/marvell/mwifiex/join.c
@@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
- phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
- memcpy(&phy_tlv->fh_ds.ds_param_set,
+ phy_tlv->header.len = cpu_to_le16(sizeof(*phy_tlv->fh_ds.ds_param_set));
+ memcpy(phy_tlv->fh_ds.ds_param_set,
&bss_desc->phy_param_set.ds_param_set.current_chan,
- sizeof(phy_tlv->fh_ds.ds_param_set));
+ sizeof(*phy_tlv->fh_ds.ds_param_set));
pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
- ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+ ss_tlv->header.len = cpu_to_le16(sizeof(*ss_tlv->cf_ibss.cf_param_set));
pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
/* Get the common rates supported between the driver and the BSS Desc */
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
index 623ddde8c8e5..071f7cb305e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
@@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
"cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
- - 1 + S_DS_GEN);
+ + S_DS_GEN);
snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
if (cmd_action == HostCmd_ACT_GEN_GET) {
-- 2.55.0



> On 15 Jul 2026, at 7:35 PM, Kees Cook <kees@xxxxxxxxxx> wrote:
>
> On Mon, Jul 13, 2026 at 01:23:34AM +0300, Georgi Valkov wrote:
>> Replace deprecated one-element arrays with flexible array members.
>> CONFIG_FORTIFY_SOURCE reports the following warning when
>> one-element arrays are used as variable-length buffers:
>>
>> sta_cmd.c:1033 mwifiex_sta_prepare_cmd
>> memcpy: detected field-spanning write (size 84) of single field
>> "domain->triplet" at .../marvell/mwifiex/sta_cmd.c:1033 (size 3)
>>
>> Convert affected structs to use flexible array members.
>> - Preserve existing wire layouts.
>> - Replace affected uses of sizeof(member) with sizeof(type).
>> - Replace unions containing one-element arrays with
>> u8 flexible arrays, and document the stored parameter-set type.
>>
>> Tested-on: WRT3200ACM, OpenWrt
>> Signed-off-by: Georgi Valkov <gvalkov@xxxxxxxxx>
>> ---
>> drivers/net/wireless/marvell/mwifiex/fw.h | 20 +++++++------------
>> drivers/net/wireless/marvell/mwifiex/join.c | 8 ++++----
>> .../net/wireless/marvell/mwifiex/sta_cmd.c | 2 +-
>> 3 files changed, 12 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
>> index e9e896606912..ec3e3f806134 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/fw.h
>> +++ b/drivers/net/wireless/marvell/mwifiex/fw.h
>> @@ -823,7 +823,7 @@ struct chan_band_param_set {
>>
>> struct mwifiex_ie_types_chan_band_list_param_set {
>> struct mwifiex_ie_types_header header;
>> - struct chan_band_param_set chan_band_param[1];
>> + struct chan_band_param_set chan_band_param[];
>> } __packed;
>>
>> struct mwifiex_ie_types_rates_param_set {
>> @@ -886,7 +886,7 @@ struct mwifiex_ie_types_wildcard_ssid_params {
>> #define TSF_DATA_SIZE 8
>> struct mwifiex_ie_types_tsf_timestamp {
>> struct mwifiex_ie_types_header header;
>> - u8 tsf_data[1];
>> + u8 tsf_data[];
>> } __packed;
>>
>> struct mwifiex_cf_param_set {
>> @@ -902,10 +902,7 @@ struct mwifiex_ibss_param_set {
>>
>> struct mwifiex_ie_types_ss_param_set {
>> struct mwifiex_ie_types_header header;
>> - union {
>> - struct mwifiex_cf_param_set cf_param_set[1];
>> - struct mwifiex_ibss_param_set ibss_param_set[1];
>> - } cf_ibss;
>> + u8 cf_ibss[]; /* CF and IBSS param sets are stored here */
>> } __packed;
>>
>> struct mwifiex_fh_param_set {
>> @@ -921,10 +918,7 @@ struct mwifiex_ds_param_set {
>>
>> struct mwifiex_ie_types_phy_param_set {
>> struct mwifiex_ie_types_header header;
>> - union {
>> - struct mwifiex_fh_param_set fh_param_set[1];
>> - struct mwifiex_ds_param_set ds_param_set[1];
>> - } fh_ds;
>> + u8 fh_ds[]; /* FH and DS param sets are stored here */
>> } __packed;
>
> This (and below) can still be a union so you don't lose the type
> information:
>
> union {
> DECLARE_FLEX_ARRAY(struct mwifiex_fh_param_set, fh_param_set);
> DECLARE_FLEX_ARRAY(struct mwifiex_ds_param_set, ds_param_set);
> } fh_ds;
>
>>
>> struct mwifiex_ie_types_auth_type {
>> @@ -1383,7 +1377,7 @@ struct host_cmd_ds_802_11_snmp_mib {
>> __le16 query_type;
>> __le16 oid;
>> __le16 buf_size;
>> - u8 value[1];
>> + u8 value[];
>> } __packed;
>>
>> struct mwifiex_rate_scope {
>> @@ -1551,7 +1545,7 @@ struct mwifiex_scan_cmd_config {
>> * TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
>> * WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
>> */
>> - u8 tlv_buf[1]; /* SSID TLV(s) and ChanList TLVs are stored
>> + u8 tlv_buf[]; /* SSID TLV(s) and ChanList TLVs are stored
>> here */
>> } __packed;
>>
>> @@ -1683,7 +1677,7 @@ struct host_cmd_ds_802_11_bg_scan_query_rsp {
>> struct mwifiex_ietypes_domain_param_set {
>> struct mwifiex_ie_types_header header;
>> u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
>> - struct ieee80211_country_ie_triplet triplet[1];
>> + struct ieee80211_country_ie_triplet triplet[];
>> } __packed;
>>
>> struct host_cmd_ds_802_11d_domain_info {
>> diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
>> index 5a1a0287c1d5..a2c427e6af3f 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/join.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/join.c
>> @@ -421,15 +421,15 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
>>
>> phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
>> phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
>> - phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
>> - memcpy(&phy_tlv->fh_ds.ds_param_set,
>> + phy_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_ds_param_set));
>
> And this would become (the "*" added to get the member size):
>
> phy_tlv->header.len = cpu_to_le16(sizeof(*phy_tlv->fh_ds.ds_param_set));
>
> etc.
>
>> + memcpy(phy_tlv->fh_ds,
>> &bss_desc->phy_param_set.ds_param_set.current_chan,
>> - sizeof(phy_tlv->fh_ds.ds_param_set));
>> + sizeof(struct mwifiex_ds_param_set));
>> pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
>>
>> ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
>> ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
>> - ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
>> + ss_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_cf_param_set));
>> pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
>>
>> /* Get the common rates supported between the driver and the BSS Desc */
>> diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> index 623ddde8c8e5..071f7cb305e1 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
>> @@ -108,7 +108,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
>> "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
>> cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
>> cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
>> - - 1 + S_DS_GEN);
>> + + S_DS_GEN);
>>
>> snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
>> if (cmd_action == HostCmd_ACT_GEN_GET) {
>> --
>> 2.55.0
>>
>
> --
> Kees Cook