wireless: intel: Replace zero-length array with flexible-array member
Subsystems (5)
PATCH 1/1 wireless: intel: 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 detected 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 +++++++++---------- .../wireless/intel/iwlegacy/iwl-spectrum.h | 4 +-- .../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 2 +- .../net/wireless/intel/iwlwifi/fw/api/debug.h | 4 +-- .../wireless/intel/iwlwifi/fw/api/filter.h | 2 +- .../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 4 +-- .../net/wireless/intel/iwlwifi/fw/api/sta.h | 2 +- .../net/wireless/intel/iwlwifi/fw/api/tdls.h | 2 +- .../net/wireless/intel/iwlwifi/fw/debugfs.c | 2 +- .../wireless/intel/iwlwifi/fw/error-dump.h | 2 +- drivers/net/wireless/intel/iwlwifi/fw/file.h | 12 ++++---- .../net/wireless/intel/iwlwifi/iwl-op-mode.h | 2 +- .../net/wireless/intel/iwlwifi/iwl-trans.h | 2 +- 15 files changed, 40 insertions(+), 40 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)
drivers/net/wireless/intel/iwlegacy/iwl-spectrum.h +2 -2
@@ -53,7 +53,7 @@ struct ieee80211_measurement_params {struct ieee80211_info_element {u8 id;u8 len; -u8 data[0 ]; +u8 data[]; } __packed;struct ieee80211_measurement_request {
@@ -61,7 +61,7 @@ struct ieee80211_measurement_request {u8 token;u8 mode;u8 type; -struct ieee80211_measurement_params params[0 ]; +struct ieee80211_measurement_params params[]; } __packed;struct ieee80211_measurement_report {
drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h +1 -1
@@ -77,7 +77,7 @@ struct iwl_fw_ini_hcmd {u8 id;u8 group;__le16 reserved; -u8 data[0 ]; +u8 data[]; } __packed;/* FW_DEBUG_TLV_HCMD_DATA_API_S_VER_1 */ /**
drivers/net/wireless/intel/iwlwifi/fw/api/debug.h +2 -2
@@ -266,7 +266,7 @@ struct iwl_mfu_assert_dump_notif {__le16 index_num;__le16 parts_num;__le32 data_size; -__le32 data[0 ]; +__le32 data[]; } __packed;/* MFU_DUMP_ASSERT_API_S_VER_1 */ /**
@@ -302,7 +302,7 @@ struct iwl_mvm_marker {u8 marker_id;__le16 reserved;__le64 timestamp; -__le32 metadata[0 ]; +__le32 metadata[]; } __packed;/* MARKER_API_S_VER_1 */ /**
drivers/net/wireless/intel/iwlwifi/fw/api/filter.h +1 -1
@@ -89,7 +89,7 @@ struct iwl_mcast_filter_cmd {u8 pass_all;u8 bssid[6 ];u8 reserved[2 ]; -u8 addr_list[0 ]; +u8 addr_list[]; } __packed;/* MCAST_FILTERING_CMD_API_S_VER_1 */ #define MAX_BCAST_FILTERS 8
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h +2 -2
@@ -351,7 +351,7 @@ struct iwl_mcc_update_resp_v3 {__le16 time;__le16 geo_info;__le32 n_channels; -__le32 channels[0 ]; +__le32 channels[]; } __packed;/* LAR_UPDATE_MCC_CMD_RESP_S_VER_3 */ /**
@@ -380,7 +380,7 @@ struct iwl_mcc_update_resp {u8 source_id;u8 reserved[3 ];__le32 n_channels; -__le32 channels[0 ]; +__le32 channels[]; } __packed;/* LAR_UPDATE_MCC_CMD_RESP_S_VER_4 */ /**
drivers/net/wireless/intel/iwlwifi/fw/api/sta.h +1 -1
@@ -552,7 +552,7 @@ struct iwl_mvm_wep_key_cmd {u8 decryption_type;u8 flags;u8 reserved; -struct iwl_mvm_wep_key wep_key[0 ]; +struct iwl_mvm_wep_key wep_key[]; } __packed;/* SEC_CURR_WEP_KEY_CMD_API_S_VER_2 */ /**
drivers/net/wireless/intel/iwlwifi/fw/api/tdls.h +1 -1
@@ -190,7 +190,7 @@ struct iwl_tdls_config_cmd {__le32 pti_req_data_offset;struct iwl_tx_cmd pti_req_tx_cmd; -u8 pti_req_template[0 ]; +u8 pti_req_template[]; } __packed;/* TDLS_CONFIG_CMD_API_S_VER_1 */ /**
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +1 -1
@@ -261,7 +261,7 @@ struct hcmd_write_data {__be32 cmd_id;__be32 flags;__be16 length; -u8 data[0 ]; +u8 data[]; } __packed; static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf,
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +1 -1
@@ -141,7 +141,7 @@ struct iwl_fw_error_dump_data {struct iwl_fw_error_dump_file {__le32 barker;__le32 file_len; -u8 data[0 ]; +u8 data[]; } __packed;/**
drivers/net/wireless/intel/iwlwifi/fw/file.h +6 -6
@@ -165,7 +165,7 @@ enum iwl_ucode_tlv_type {struct iwl_ucode_tlv {__le32 type;/* see above */ __le32 length;/* not including type/length fields */ -u8 data[0 ]; +u8 data[]; };#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
@@ -191,7 +191,7 @@ struct iwl_tlv_ucode_header {* Note that each TLV is padded to a length * that is a multiple of 4 for alignment. */ -u8 data[0 ]; +u8 data[]; };/*
@@ -652,7 +652,7 @@ struct iwl_fw_dbg_dest_tlv_v1 {__le32 wrap_count;u8 base_shift;u8 end_shift; -struct iwl_fw_dbg_reg_op reg_ops[0 ]; +struct iwl_fw_dbg_reg_op reg_ops[]; } __packed;/* Mask of the register for defining the LDBG MAC2SMEM buffer SMEM size */
@@ -672,14 +672,14 @@ struct iwl_fw_dbg_dest_tlv {__le32 wrap_count;u8 base_shift;u8 size_shift; -struct iwl_fw_dbg_reg_op reg_ops[0 ]; +struct iwl_fw_dbg_reg_op reg_ops[]; } __packed;struct iwl_fw_dbg_conf_hcmd {u8 id;u8 reserved;__le16 len; -u8 data[0 ]; +u8 data[]; } __packed;/**
@@ -754,7 +754,7 @@ struct iwl_fw_dbg_trigger_tlv {u8 flags;u8 reserved[5 ]; -u8 data[0 ]; +u8 data[]; } __packed;#define FW_DBG_START_FROM_ALIVE 0
drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h +1 -1
@@ -175,7 +175,7 @@ void iwl_opmode_deregister(const char *name);struct iwl_op_mode {const struct iwl_op_mode_ops *ops; -char op_mode_specific[0 ]__aligned(sizeof(void *)) ; +char op_mode_specific[]__aligned(sizeof(void *)) ; };static inline void iwl_op_mode_stop (struct iwl_op_mode *op_mode)
drivers/net/wireless/intel/iwlwifi/iwl-trans.h +1 -1
@@ -875,7 +875,7 @@ struct iwl_trans {/* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ -char trans_specific[0 ]__aligned(sizeof(void *)) ; +char trans_specific[]__aligned(sizeof(void *)) ; };const char *iwl_get_cmd_string (struct iwl_trans *trans,u32 id);
Signature · 1 line
2.25.0
Quoted 22 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]
Quoted 7 lines
This issue was detected 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]>
Please split iwlwifi changes to a separate patch so that Luca can apply to his tree.
Patch set to Changes Requested.
Signature · 3 lines
https://patchwork.kernel.org/patch/11401145/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches