staging: Replace zero-length array with flexible-array member
Subsystems (4)
PATCH 1/1 staging: Replace zero-length array with flexible-array member
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]
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/staging/gdm724x/gdm_mux.h | 2 +- drivers/staging/gdm724x/hci_packet.h | 6 ++-- drivers/staging/greybus/audio_apbridgea.h | 2 +- drivers/staging/ks7010/ks_hostif.h | 4 +-- .../staging/media/allegro-dvt/allegro-core.c | 2 +- drivers/staging/octeon-usb/octeon-hcd.c | 2 +- drivers/staging/rtl8192e/rtllib.h | 30 +++++++++---------- .../staging/rtl8192u/ieee80211/ieee80211.h | 28 ++++++++--------- drivers/staging/rtl8712/ieee80211.h | 4 +-- drivers/staging/rtl8712/rtl871x_mp_ioctl.h | 4 +-- drivers/staging/wilc1000/cfg80211.c | 10 +++---- drivers/staging/wilc1000/spi.c | 2 +- drivers/staging/wlan-ng/hfa384x.h | 4 +-- drivers/staging/wlan-ng/p80211types.h | 4 +-- 14 files changed, 52 insertions(+), 52 deletions(-)
drivers/staging/gdm724x/gdm_mux.h +1 -1
@@ -29,7 +29,7 @@ struct mux_pkt_header {__le32 seq_num;__le32 payload_size;__le16 packet_type; -unsigned char data[0 ]; +unsigned char data[]; };struct mux_tx {
drivers/staging/gdm724x/hci_packet.h +3 -3
@@ -28,7 +28,7 @@struct hci_packet {__dev16 cmd_evt;__dev16 len; -u8 data[0 ]; +u8 data[]; } __packed;struct tlv {
@@ -51,7 +51,7 @@ struct sdu {__dev32 dft_eps_ID;__dev32 bearer_ID;__dev32 nic_type; -u8 data[0 ]; +u8 data[]; } __packed;struct multi_sdu {
@@ -59,7 +59,7 @@ struct multi_sdu {__dev16 len;__dev16 num_packet;__dev16 reserved; -u8 data[0 ]; +u8 data[]; } __packed;struct hci_pdn_table_ind {
drivers/staging/greybus/audio_apbridgea.h +1 -1
@@ -65,7 +65,7 @@struct audio_apbridgea_hdr {__u8 type;__le16 i2s_port; -__u8 data[0 ]; +__u8 data[]; } __packed;struct audio_apbridgea_set_config_request {
drivers/staging/ks7010/ks_hostif.h +2 -2
@@ -70,7 +70,7 @@ struct hostif_data_request {#define TYPE_DATA 0x0000#define TYPE_AUTH 0x0001__le16 reserved; -u8 data[0 ]; +u8 data[]; } __packed;#define TYPE_PMK1 0x0001
@@ -194,7 +194,7 @@ enum mib_data_type {struct hostif_mib_value {__le16 size;__le16 type; -u8 body[0 ]; +u8 body[]; } __packed;struct hostif_mib_get_confirm_t {
drivers/staging/media/allegro-dvt/allegro-core.c +1 -1
@@ -434,7 +434,7 @@ struct mcu_msg_push_buffers_internal_buffer {struct mcu_msg_push_buffers_internal {struct mcu_msg_header header;u32 channel_id; -struct mcu_msg_push_buffers_internal_buffer buffer[0 ]; +struct mcu_msg_push_buffers_internal_buffer buffer[]; } __attribute__ ((__packed__ ));struct mcu_msg_put_stream_buffer {
drivers/staging/octeon-usb/octeon-hcd.c +1 -1
@@ -406,7 +406,7 @@ struct octeon_hcd {*/ struct octeon_temp_buffer {void *orig_buffer; -u8 data[0 ]; +u8 data[]; };static inline struct usb_hcd *octeon_to_hcd (struct octeon_hcd *p)
drivers/staging/rtl8192e/rtllib.h +15 -15
@@ -728,14 +728,14 @@ struct rtllib_pspoll_hdr {struct rtllib_hdr {__le16 frame_ctl;__le16 duration_id; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_1addr {__le16 frame_ctl;__le16 duration_id;u8 addr1[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_2addr {
@@ -743,7 +743,7 @@ struct rtllib_hdr_2addr {__le16 duration_id;u8 addr1[ETH_ALEN ];u8 addr2[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_3addr {
@@ -753,7 +753,7 @@ struct rtllib_hdr_3addr {u8 addr2[ETH_ALEN ];u8 addr3[ETH_ALEN ];__le16 seq_ctl; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_4addr {
@@ -764,7 +764,7 @@ struct rtllib_hdr_4addr {u8 addr3[ETH_ALEN ];__le16 seq_ctl;u8 addr4[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_3addrqos {
@@ -775,7 +775,7 @@ struct rtllib_hdr_3addrqos {u8 addr3[ETH_ALEN ];__le16 seq_ctl;__le16 qos_ctl; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_hdr_4addrqos {
@@ -787,13 +787,13 @@ struct rtllib_hdr_4addrqos {__le16 seq_ctl;u8 addr4[ETH_ALEN ];__le16 qos_ctl; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtllib_info_element {u8 id;u8 len; -u8 data[0 ]; +u8 data[]; } __packed;struct rtllib_authentication {
@@ -802,7 +802,7 @@ struct rtllib_authentication {__le16 transaction;__le16 status;/*challenge*/ -struct rtllib_info_element info_element[0 ]; +struct rtllib_info_element info_element[]; } __packed;struct rtllib_disauth {
@@ -818,7 +818,7 @@ struct rtllib_disassoc {struct rtllib_probe_request {struct rtllib_hdr_3addr header;/* SSID, supported rates */ -struct rtllib_info_element info_element[0 ]; +struct rtllib_info_element info_element[]; } __packed;struct rtllib_probe_response {
@@ -829,7 +829,7 @@ struct rtllib_probe_response {/* SSID, supported rates, FH params, DS params, * CF params, IBSS params, TIM (if beacon), RSN */ -struct rtllib_info_element info_element[0 ]; +struct rtllib_info_element info_element[]; } __packed;/* Alias beacon for probe_response */
@@ -840,7 +840,7 @@ struct rtllib_assoc_request_frame {__le16 capability;__le16 listen_interval;/* SSID, supported rates, RSN */ -struct rtllib_info_element info_element[0 ]; +struct rtllib_info_element info_element[]; } __packed;struct rtllib_assoc_response_frame {
@@ -848,7 +848,7 @@ struct rtllib_assoc_response_frame {__le16 capability;__le16 status;__le16 aid; -struct rtllib_info_element info_element[0 ];/* supported rates */ +struct rtllib_info_element info_element[];/* supported rates */ } __packed;struct rtllib_txb {
@@ -859,7 +859,7 @@ struct rtllib_txb {u16 reserved;__le16 frag_size;__le16 payload_size; -struct sk_buff *fragments[0 ]; +struct sk_buff *fragments[]; };#define MAX_SUBFRAME_COUNT 64
@@ -1792,7 +1792,7 @@ struct rtllib_device {/* This must be the last item so that it points to the data * allocated beyond this structure by alloc_rtllib */ -u8 priv[0 ]; +u8 priv[]; };#define IEEE_A (1<<0)
drivers/staging/rtl8192u/ieee80211/ieee80211.h +14 -14
@@ -886,14 +886,14 @@ enum ieee80211_mfie {struct rtl_80211_hdr {__le16 frame_ctl;__le16 duration_id; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtl_80211_hdr_1addr {__le16 frame_ctl;__le16 duration_id;u8 addr1[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtl_80211_hdr_2addr {
@@ -901,7 +901,7 @@ struct rtl_80211_hdr_2addr {__le16 duration_id;u8 addr1[ETH_ALEN ];u8 addr2[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtl_80211_hdr_3addr {
@@ -911,7 +911,7 @@ struct rtl_80211_hdr_3addr {u8 addr2[ETH_ALEN ];u8 addr3[ETH_ALEN ];__le16 seq_ctl; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtl_80211_hdr_4addr {
@@ -922,7 +922,7 @@ struct rtl_80211_hdr_4addr {u8 addr3[ETH_ALEN ];__le16 seq_ctl;u8 addr4[ETH_ALEN ]; -u8 payload[0 ]; +u8 payload[]; } __packed;struct rtl_80211_hdr_3addrqos {
@@ -951,7 +951,7 @@ struct rtl_80211_hdr_4addrqos {struct ieee80211_info_element {u8 id;u8 len; -u8 data[0 ]; +u8 data[]; } __packed;struct ieee80211_authentication {
@@ -960,7 +960,7 @@ struct ieee80211_authentication {__le16 transaction;__le16 status;/*challenge*/ -struct ieee80211_info_element info_element[0 ]; +struct ieee80211_info_element info_element[]; } __packed;struct ieee80211_disassoc {
@@ -971,7 +971,7 @@ struct ieee80211_disassoc {struct ieee80211_probe_request {struct rtl_80211_hdr_3addr header;/* SSID, supported rates */ -struct ieee80211_info_element info_element[0 ]; +struct ieee80211_info_element info_element[]; } __packed;struct ieee80211_probe_response {
@@ -982,7 +982,7 @@ struct ieee80211_probe_response {/* SSID, supported rates, FH params, DS params, * CF params, IBSS params, TIM (if beacon), RSN */ -struct ieee80211_info_element info_element[0 ]; +struct ieee80211_info_element info_element[]; } __packed;/* Alias beacon for probe_response */
@@ -993,7 +993,7 @@ struct ieee80211_assoc_request_frame {__le16 capability;__le16 listen_interval;/* SSID, supported rates, RSN */ -struct ieee80211_info_element info_element[0 ]; +struct ieee80211_info_element info_element[]; } __packed;struct ieee80211_reassoc_request_frame {
@@ -1002,7 +1002,7 @@ struct ieee80211_reassoc_request_frame {__le16 listen_interval;u8 current_ap[ETH_ALEN ];/* SSID, supported rates, RSN */ -struct ieee80211_info_element info_element[0 ]; +struct ieee80211_info_element info_element[]; } __packed;struct ieee80211_assoc_response_frame {
@@ -1010,7 +1010,7 @@ struct ieee80211_assoc_response_frame {__le16 capability;__le16 status;__le16 aid; -struct ieee80211_info_element info_element[0 ];/* supported rates */ +struct ieee80211_info_element info_element[];/* supported rates */ } __packed;struct ieee80211_txb {
@@ -1021,7 +1021,7 @@ struct ieee80211_txb {u16 reserved;__le16 frag_size;__le16 payload_size; -struct sk_buff *fragments[0 ]; +struct sk_buff *fragments[]; };#define MAX_TX_AGG_COUNT 16
@@ -2007,7 +2007,7 @@ struct ieee80211_device {/* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ -u8 priv[0 ]; +u8 priv[]; };#define IEEE_A (1<<0)
drivers/staging/rtl8712/ieee80211.h +2 -2
@@ -535,7 +535,7 @@ struct ieee80211_info_element_hdr {struct ieee80211_info_element {u8 id;u8 len; -u8 data[0 ]; +u8 data[]; } __packed;/*
@@ -597,7 +597,7 @@ struct ieee80211_txb {u16 reserved;u16 frag_size;u16 payload_size; -struct sk_buff *fragments[0 ]; +struct sk_buff *fragments[]; };/* SWEEP TABLE ENTRIES NUMBER*/
drivers/staging/rtl8712/rtl871x_mp_ioctl.h +2 -2
@@ -48,7 +48,7 @@ struct eeprom_rw_param {struct EFUSE_ACCESS_STRUCT {u16 start_addr;u16 cnts; -u8 data[0 ]; +u8 data[]; };struct burst_rw_reg {
@@ -324,7 +324,7 @@ struct mp_ioctl_handler {struct mp_ioctl_param {unsigned int subcode;unsigned int len; -unsigned char data[0 ]; +unsigned char data[]; };#define GEN_MP_IOCTL_SUBCODE (code) _MP_IOCTL_ ## code ## _CMD_
drivers/staging/wilc1000/cfg80211.c +5 -5
@@ -62,7 +62,7 @@ struct wilc_p2p_pub_act_frame {u8 oui_type;u8 oui_subtype;u8 dialog_token; -u8 elem[0 ]; +u8 elem[]; } __packed;struct wilc_vendor_specific_ie {
@@ -70,13 +70,13 @@ struct wilc_vendor_specific_ie {u8 tag_len;u8 oui[3 ];u8 oui_type; -u8 attr[0 ]; +u8 attr[]; } __packed;struct wilc_attr_entry {u8 attr_type;__le16 attr_len; -u8 val[0 ]; +u8 val[]; } __packed;struct wilc_attr_oper_ch {
@@ -91,13 +91,13 @@ struct wilc_attr_ch_list {u8 attr_type;__le16 attr_len;u8 country_code[IEEE80211_COUNTRY_STRING_LEN ]; -u8 elem[0 ]; +u8 elem[]; } __packed;struct wilc_ch_list_elem {u8 op_class;u8 no_of_channels; -u8 ch_list[0 ]; +u8 ch_list[]; } __packed; static void cfg_scan_result(enum scan_event scan_event,
drivers/staging/wilc1000/spi.c +1 -1
@@ -139,7 +139,7 @@ struct wilc_spi_read_rsp_data {u8 status;u8 resp_header;u8 resp_data[4 ]; -u8 crc[0 ]; +u8 crc[]; } __packed;struct wilc_spi_rsp_data {
drivers/staging/wlan-ng/hfa384x.h +2 -2
@@ -355,7 +355,7 @@/* Commonly used basic types */ struct hfa384x_bytestr {__le16 len; -u8 data[0 ]; +u8 data[]; } __packed;struct hfa384x_bytestr32 {
@@ -421,7 +421,7 @@ struct hfa384x_authenticate_station_data {/*-- Configuration Record: WPAData (data portion only) --*/ struct hfa384x_wpa_data {__le16 datalen; -u8 data[0 ];/* max 80 */ +u8 data[];/* max 80 */ } __packed;/*--------------------------------------------------------------------
drivers/staging/wlan-ng/p80211types.h +2 -2
@@ -204,7 +204,7 @@ struct p80211pstr {struct p80211pstrd {u8 len; -u8 data[0 ]; +u8 data[]; } __packed;/* Maximum pascal string */
@@ -249,7 +249,7 @@ struct p80211itemd {u32 did;u16 status;u16 len; -u8 data[0 ]; +u8 data[]; } __packed;/* message data item for int, BOUNDEDINT, ENUMINT */
Signature · 1 line
2.25.0
Hi Gustavo
Quoted 36 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]
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]>static void cfg_scan_result(enum
scan_eventscan_event,drivers/staging/wilc1000/spi.c +0
-0
drivers/staging/wilc1000/spi.c struct wilc_spi_read_rsp_data { · line 143
Quoted 6 lines
drivers/staging/wilc1000/spi.c +1
-1@@ -139,7 +139,7 @@ struct wilc_spi_read_rsp_data {u8 status;u8 resp_header;u8 resp_data[4 ]; -u8 crc[0 ]; +u8 crc[]; } __packed;
more zero-length arrays in wilc1000, spi.c, struct wilc_spi_cmd, and in fw.h
Hi,
Quoted 33 lines · On 2/20/20 13:04, [email protected] wrote:
Hi Gustavo
Quoted 30 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]
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]>
Quoted 14 lines
drivers/staging/wilc1000/spi.c struct wilc_spi_read_rsp_data { · line 143
Quoted 12 lines
static void cfg_scan_result(enum
scan_eventscan_event,drivers/staging/wilc1000/spi.c +1
-1@@ -139,7 +139,7 @@ struct wilc_spi_read_rsp_data {u8 status;u8 resp_header;u8 resp_data[4 ]; -u8 crc[0 ]; +u8 crc[]; } __packed;more zero-length arrays in wilc1000,
spi.c, structwilc_spi_cmd, and infw.h
Oh wow, I hadn't thought about cases like this:
struct wilc_spi_cmd {
u8 cmd_type;
union {
struct {
u8 addr[3];
u8 crc[0];
} __packed simple_cmd;
struct {
u8 addr[3];
u8 size[2];
u8 crc[0];
} __packed dma_cmd;
struct {
u8 addr[3];
u8 size[3];
u8 crc[0];
} __packed dma_cmd_ext;
struct {
u8 addr[2];
__be32 data;
u8 crc[0];
} __packed internal_w_cmd;
struct {
u8 addr[3];
__be32 data;
u8 crc[0];
} __packed w_cmd;
} u;
} __packed;Thanks for the feedback.
--
Gustavo