ipw2x00: Replace zero-length array with flexible-array
PATCH 1/1 ipw2x00: Replace zero-length array with flexible-array
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo {
int stuff;
struct boo array[];
};By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
--- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 2 - drivers/net/wireless/intel/ipw2x00/ipw2200.h | 10 ++++----- drivers/net/wireless/intel/ipw2x00/libipw.h | 28 +++++++++++++-------------- 3 files changed, 20 insertions(+), 20 deletions(-)
drivers/net/wireless/intel/ipw2x00/ipw2200.c +1 -1
@@ -3386,7 +3386,7 @@ struct ipw_fw {__le32 boot_size;__le32 ucode_size;__le32 fw_size; -u8 data[0 ]; +u8 data[]; }; static int ipw_get_fw(struct ipw_priv *priv,
drivers/net/wireless/intel/ipw2x00/ipw2200.h +5 -5
@@ -448,7 +448,7 @@ struct tfd_command {u8 index;u8 length;__le16 reserved; -u8 payload[0 ]; +u8 payload[]; } __packed;struct tfd_data {
@@ -675,7 +675,7 @@ struct ipw_rx_frame {// is identical) u8 rtscts_seen;// 0x1 RTS seen ; 0x2 CTS seen __le16 length; -u8 data[0 ]; +u8 data[]; } __packed;struct ipw_rx_header {
@@ -1002,7 +1002,7 @@ struct ipw_cmd { /* XXX */* Incoming parameters listed 1-st, followed by outcoming params. * nParams=(len+3)/4+status_len */ -u32 param[0 ]; +u32 param[]; } __packed;#define STATUS_HCMD_ACTIVE (1<<0)/**< host command in progress */
@@ -1108,7 +1108,7 @@ struct ipw_fw_error { /* XXX */u32 log_len;struct ipw_error_elem *elem;struct ipw_event *log; -u8 payload[0 ]; +u8 payload[]; } __packed;#ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -1153,7 +1153,7 @@ struct ipw_rt_hdr {s8 rt_dbmsignal;/* signal in dbM, kluged to signed */ s8 rt_dbmnoise;u8 rt_antenna;/* antenna number */ - u8 payload[0]; /* payload... */ + u8 payload[]; /* payload... */ } __packed;#endif
drivers/net/wireless/intel/ipw2x00/libipw.h +14 -14
@@ -334,7 +334,7 @@ struct libipw_hdr_1addr {__le16 frame_ctl;__le16 duration_id;u8 addr1[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct libipw_hdr_2addr {
@@ -342,7 +342,7 @@ struct libipw_hdr_2addr {__le16 duration_id;u8 addr1[ETH_ALEN ];u8 addr2[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct libipw_hdr_3addr {
@@ -352,7 +352,7 @@ struct libipw_hdr_3addr {u8 addr2[ETH_ALEN ];u8 addr3[ETH_ALEN ];__le16 seq_ctl; -u8 payload[0 ]; +u8 payload[]; } __packed;struct libipw_hdr_4addr {
@@ -363,7 +363,7 @@ struct libipw_hdr_4addr {u8 addr3[ETH_ALEN ];__le16 seq_ctl;u8 addr4[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct libipw_hdr_3addrqos {
@@ -380,7 +380,7 @@ struct libipw_hdr_3addrqos {struct libipw_info_element {u8 id;u8 len; -u8 data[0 ]; +u8 data[]; } __packed;/*
@@ -406,7 +406,7 @@ struct libipw_auth {__le16 transaction;__le16 status;/* challenge */ -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;struct libipw_channel_switch {
@@ -442,7 +442,7 @@ struct libipw_disassoc {struct libipw_probe_request {struct libipw_hdr_3addr header;/* SSID, supported rates */ -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;struct libipw_probe_response {
@@ -452,7 +452,7 @@ struct libipw_probe_response {__le16 capability;/* SSID, supported rates, FH params, DS params, * CF params, IBSS params, TIM (if beacon), RSN */ -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;/* Alias beacon for probe_response */
@@ -463,7 +463,7 @@ struct libipw_assoc_request {__le16 capability;__le16 listen_interval;/* SSID, supported rates, RSN */ -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;struct libipw_reassoc_request {
@@ -471,7 +471,7 @@ struct libipw_reassoc_request {__le16 capability;__le16 listen_interval;u8 current_ap[ETH_ALEN ]; -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;struct libipw_assoc_response {
@@ -480,7 +480,7 @@ struct libipw_assoc_response {__le16 status;__le16 aid;/* supported rates */ -struct libipw_info_element info_element[0 ]; +struct libipw_info_element info_element[]; } __packed;struct libipw_txb {
@@ -490,7 +490,7 @@ struct libipw_txb {u8 reserved;u16 frag_size;u16 payload_size; -struct sk_buff *fragments[0 ]; +struct sk_buff *fragments[]; };/* SWEEP TABLE ENTRIES NUMBER */
@@ -594,7 +594,7 @@ struct libipw_ibss_dfs {struct libipw_info_element ie;u8 owner[ETH_ALEN ];u8 recovery_interval; -struct libipw_channel_map channel_map[0 ]; +struct libipw_channel_map channel_map[]; };struct libipw_csa {
@@ -830,7 +830,7 @@ struct libipw_device {/* This must be the last item so that it points to the data * allocated beyond this structure by alloc_libipw */ -u8 priv[0 ]; +u8 priv[]; };#define IEEE_A (1<<0)
Quoted 29 lines · Gustavo A. R. Silva
The current codebase makes use of the zero-length array language extension to the C90 standard, but the preferred mechanism to declare variable-length types such as these ones is a flexible array member[1][2], introduced in C99:
struct foo { int stuff; struct boo array[]; };By making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by this change:
"Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array members have incomplete type[1]. There are some instances of code in which the sizeof operator is being incorrectly/erroneously applied to zero-length arrays and the result is zero. Such instances may be hiding some bugs. So, this work (flexible-array member conversions) will also help to get completely rid of those sorts of issues.
Quoted 7 lines
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit76497732932f("cxgb3/l2t: Fix undefined behaviour")Signed-off-by Gustavo A. R. Silva <[email protected]>
Patch applied to wireless-drivers-next.git, thanks.
e0e05f20c200 ipw2x00: Replace zero-length array with flexible-array
Signature · 3 lines
https://patchwork.kernel.org/patch/11534703/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches