Skip to contentSkip to conversation

wifi: ath6kl: wmi: Avoid -Wflex-array-member-not-at-end warning

PATCH Superseded Gustavo A. R. Silva 3 participants 5 messages Feb 17 – Feb 21 Atheros ATH6KL wireless driver

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 wifi: ath6kl: wmi: Avoid -Wflex-array-member-not-at-end warning

-Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally.

struct bss_bias_info is a flexible structure, this is a structure that contains a flexible-array member (struct bss_bias bss_bias[]).

Since struct roam_ctrl_cmd is defined by hardware, we create the new struct bss_bias_info_hdr type, and use it to replace the object type causing trouble in struct roam_ctrl_cmd, namely struct bss_bias_info.

Also, once -fms-extensions is enabled, we can use transparent struct members in struct bss_bias_info.

Notice that the newly created type does not contain the flex-array member bss_bias, which is the object causing the -Wfamnae warning.

After these changes, the size of struct roam_ctrl_cmd, along with its member's offsets remain the same, hence the memory layout doesn't change:

Before changes:
struct roam_ctrl_cmd {
union {
u8 bssid[6]; /* 0 6 */
u8 roam_mode; /* 0 1 */
struct bss_bias_info bss; /* 0 1 */
struct low_rssi_scan_params params; /* 0 8 */
} info; /* 0 8 */
u8 roam_ctrl; /* 8 1 */

/* size: 9, cachelines: 1, members: 2 */
/* last cacheline: 9 bytes */
} __attribute__((__packed__));

After changes:
struct roam_ctrl_cmd {
union {
u8 bssid[6]; /* 0 6 */
u8 roam_mode; /* 0 1 */
struct bss_bias_info_hdr bss; /* 0 1 */
struct low_rssi_scan_params params; /* 0 8 */
} info; /* 0 8 */
u8 roam_ctrl; /* 8 1 */

/* size: 9, cachelines: 1, members: 2 */
/* last cacheline: 9 bytes */
} __attribute__((__packed__));

With these changes fix the following warning:

drivers/net/wireless/ath/ath6kl/wmi.h:1658:20: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

---
Changes in v2:
- Create new separate struct bss_bias_info_hdr, and use transparent struct members (in struct bss_bias_info) instead of rearranging members in struct roam_ctrl_cmd.
- Update subject line - Add 'wifi:' prefix.

v1:
- Link: https://lore.kernel.org/linux-hardening/aR153k4ExCD-QTMq@kspp/

 drivers/net/wireless/ath/ath6kl/wmi.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath6kl/wmi.h +6 -2
index 3080d82e25cc..d2a5c96fc878 100644
@@ -1635,8 +1635,12 @@ struct bss_bias {
 	s8 bias;
 } __packed;
 
-struct bss_bias_info {
+struct bss_bias_info_hdr {
 	u8 num_bss;
+} __packed;
+
+struct bss_bias_info {
+	struct bss_bias_info_hdr;
 	struct bss_bias bss_bias[];
 } __packed;
 
@@ -1652,7 +1656,7 @@ struct roam_ctrl_cmd {
 	union {
 		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
 		u8 roam_mode; /* WMI_SET_ROAM_MODE */
-		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct bss_bias_info_hdr bss; /* WMI_SET_HOST_BIAS */
 		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
 						     */
 	} __packed info;
Signature · 1 line
2.43.0
#1 lore raw
Quoted 85 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.

struct bss_bias_info is a flexible structure, this is a structure that contains a flexible-array member (struct bss_bias bss_bias[]).

Since struct roam_ctrl_cmd is defined by hardware, we create the new struct bss_bias_info_hdr type, and use it to replace the object type causing trouble in struct roam_ctrl_cmd, namely struct bss_bias_info.

Also, once -fms-extensions is enabled, we can use transparent struct members in struct bss_bias_info.

Notice that the newly created type does not contain the flex-array member bss_bias, which is the object causing the -Wfamnae warning.

After these changes, the size of struct roam_ctrl_cmd, along with its member's offsets remain the same, hence the memory layout doesn't change:

Before changes:
struct roam_ctrl_cmd {
union {
u8 bssid[6]; /* 0 6 */
u8 roam_mode; /* 0 1 */
struct bss_bias_info bss; /* 0 1 */
struct low_rssi_scan_params params; /* 0 8 */
} info; /* 0 8 */
u8 roam_ctrl; /* 8 1 */

/* size: 9, cachelines: 1, members: 2 */
/* last cacheline: 9 bytes */
} __attribute__((__packed__));

After changes:
struct roam_ctrl_cmd {
union {
u8 bssid[6]; /* 0 6 */
u8 roam_mode; /* 0 1 */
struct bss_bias_info_hdr bss; /* 0 1 */
struct low_rssi_scan_params params; /* 0 8 */
} info; /* 0 8 */
u8 roam_ctrl; /* 8 1 */

/* size: 9, cachelines: 1, members: 2 */
/* last cacheline: 9 bytes */
} __attribute__((__packed__));

With these changes fix the following warning:

drivers/net/wireless/ath/ath6kl/wmi.h:1658:20: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

---
Changes in v2:
- Create new separate struct bss_bias_info_hdr, and use transparent struct members (in struct bss_bias_info) instead of rearranging members in struct roam_ctrl_cmd.
- Update subject line - Add 'wifi:' prefix.

v1:
- Link: https://lore.kernel.org/linux-hardening/aR153k4ExCD-QTMq@kspp/

 drivers/net/wireless/ath/ath6kl/wmi.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath6kl/wmi.h +5 -1
index 3080d82e25cc..d2a5c96fc878 100644
@@ -1635,8 +1635,12 @@ struct bss_bias {
 	s8 bias;
 } __packed;
 
-struct bss_bias_info {
+struct bss_bias_info_hdr {
 	u8 num_bss;
+} __packed;
+
+struct bss_bias_info {
+	struct bss_bias_info_hdr;
 	struct bss_bias bss_bias[];
 } __packed;
 

drivers/net/wireless/ath/ath6kl/wmi.h struct roam_ctrl_cmd { · line 1662

Quoted 8 lines
drivers/net/wireless/ath/ath6kl/wmi.h +1 -1
@@ -1652,7 +1656,7 @@ struct roam_ctrl_cmd {
 	union {
 		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
 		u8 roam_mode; /* WMI_SET_ROAM_MODE */
-		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct bss_bias_info_hdr bss; /* WMI_SET_HOST_BIAS */
 		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
 						     */
 	} __packed info;

That bss member appears to be completely unused
(bssid, roam_mode, and params are used)

So IMO the better solution is to remove bss from the union. And I think struct bss_bias and struct bss_bias_info can also be removed.

/jeff

#2 lore raw
Quoted 14 lines

drivers/net/wireless/ath/ath6kl/wmi.h struct roam_ctrl_cmd { · line 1662

Quoted 10 lines
drivers/net/wireless/ath/ath6kl/wmi.h +1 -1
@@ -1652,7 +1656,7 @@ struct roam_ctrl_cmd {
  	union {
  		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
  		u8 roam_mode; /* WMI_SET_ROAM_MODE */
-		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct bss_bias_info_hdr bss; /* WMI_SET_HOST_BIAS */
  		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
  						     */
  	} __packed info;

That bss member appears to be completely unused
(bssid, roam_mode, and params are used)

Quoted 2 lines

So IMO the better solution is to remove bss from the union. And I think struct bss_bias and struct bss_bias_info can also be removed.

Even if they're not used, are you sure they aren't there simply to define the memory layout of struct roam_ctrl_cmd?

As Kees commented[1], struct roam_ctrl_cmd appears to be a hardware interface... See below:

drivers/net/wireless/ath/ath6kl/wmi.c:
755 /*

 756  * Mechanism to modify the roaming behavior in the firmware. The lower rssi
 757  * at which the station has to roam can be passed with
 758  * WMI_SET_LRSSI_SCAN_PARAMS. Subtract 96 from RSSI to get the signal level
 759  * in dBm.
 760  */

761 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi) 762 {
763 struct sk_buff *skb;
764 struct roam_ctrl_cmd *cmd;
765
766 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
767 if (!skb)
768 return -ENOMEM;
769
770 cmd = (struct roam_ctrl_cmd *) skb->data;
...
}

Thanks
-Gustavo

[1] https://lore.kernel.org/linux-hardening/202601151627.99DFE54@keescook/

#3 lore raw
Quoted 30 lines · Gustavo A. R. Silva
Quoted 14 lines

drivers/net/wireless/ath/ath6kl/wmi.h struct roam_ctrl_cmd { · line 1662

Quoted 10 lines
drivers/net/wireless/ath/ath6kl/wmi.h +1 -1
@@ -1652,7 +1656,7 @@ struct roam_ctrl_cmd {
  	union {
  		u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
  		u8 roam_mode; /* WMI_SET_ROAM_MODE */
-		struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
+		struct bss_bias_info_hdr bss; /* WMI_SET_HOST_BIAS */
  		struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
  						     */
  	} __packed info;

That bss member appears to be completely unused
(bssid, roam_mode, and params are used)

Quoted 2 lines

So IMO the better solution is to remove bss from the union. And I think struct bss_bias and struct bss_bias_info can also be removed.

Even if they're not used, are you sure they aren't there simply to define the memory layout of struct roam_ctrl_cmd?

As Kees commented[1], struct roam_ctrl_cmd appears to be a hardware interface... See below:

drivers/net/wireless/ath/ath6kl/wmi.c:
755 /*

  756  * Mechanism to modify the roaming behavior in the firmware. The lower rssi
  757  * at which the station has to roam can be passed with
  758  * WMI_SET_LRSSI_SCAN_PARAMS. Subtract 96 from RSSI to get the signal level
  759  * in dBm.
  760  */
Quoted 12 lines

761 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi) 762 {
763 struct sk_buff *skb;
764 struct roam_ctrl_cmd *cmd;
765
766 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
767 if (!skb)
768 return -ENOMEM;
769
770 cmd = (struct roam_ctrl_cmd *) skb->data;
...
}

yes, it defines a hardware interface. But note the 'info' is a union, and each member of the union is there to support a specific value of roam_ctrl. And since the WMI_SET_HOST_BIAS roam_ctrl is not used, the only important thing to consider with your patch is that the location of the roam_ctrl field must not change, and hence the size of union info must not change.

pahole of the original:
struct roam_ctrl_cmd {
union {
u8 bssid[6]; /* 0 6 */
u8 roam_mode; /* 0 1 */
struct bss_bias_info bss; /* 0 1 */
struct low_rssi_scan_params params; /* 0 8 */
} info; /* 0 8 */
u8 roam_ctrl; /* 8 1 */

/* size: 9, cachelines: 1, members: 2 */
/* last cacheline: 9 bytes */
} __attribute__((__packed__));

pahole with struct bss removed:

struct roam_ctrl_cmd {
	union {
		u8                 bssid[6];             /*     0     6 */
		u8                 roam_mode;            /*     0     1 */
		struct low_rssi_scan_params params;      /*     0     8 */
	} info;                                          /*     0     8 */
	u8                         roam_ctrl;            /*     8     1 */

	/* size: 9, cachelines: 1, members: 2 */
	/* last cacheline: 9 bytes */
} __attribute__((__packed__));

So the size of the message and the location of roam_ctrl is unchanged.

/jeff

#4 lore raw

[..]

Quoted 6 lines

yes, it defines a hardware interface. But note the 'info' is a union, and each member of the union is there to support a specific value of roam_ctrl. And since the WMI_SET_HOST_BIAS roam_ctrl is not used, the only important thing to consider with your patch is that the location of the roam_ctrl field must not change, and hence the size of union info must not change.

[..]

Quoted 1 line

So the size of the message and the location of roam_ctrl is unchanged.

Perfect! With that confirmation, I can proceed with v3. :)

Thanks!
-Gustavo