Commit d3ed0cf0 authored by Gustavo A. R. Silva's avatar Gustavo A. R. Silva Committed by Kalle Valo
Browse files

ath10k: 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 76497732 ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: default avatarGustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200507041127.GA31587@embeddedor
parent 27143fa9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ struct ath10k_ce_ring {
	struct ce_desc_64 *shadow_base;

	/* keep last */
	void *per_transfer_context[0];
	void *per_transfer_context[];
};

struct ath10k_ce_pipe {
+1 −1
Original line number Diff line number Diff line
@@ -1262,7 +1262,7 @@ struct ath10k {
	int coex_gpio_pin;

	/* must be last */
	u8 drv_priv[0] __aligned(sizeof(void *));
	u8 drv_priv[] __aligned(sizeof(void *));
};

static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
+2 −2
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ struct ath10k_dump_file_data {
	u8 unused[128];

	/* struct ath10k_tlv_dump_data + more */
	u8 data[0];
	u8 data[];
} __packed;

struct ath10k_dump_ram_data_hdr {
@@ -100,7 +100,7 @@ struct ath10k_dump_ram_data_hdr {
	/* length of payload data, not including this header */
	__le32 length;

	u8 data[0];
	u8 data[];
};

/* magic number to fill the holes not copied due to sections in regions */
+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ struct ath10k_pktlog_hdr {
	__le16 log_type; /* Type of log information foll this header */
	__le16 size; /* Size of variable length log information in bytes */
	__le32 timestamp;
	u8 payload[0];
	u8 payload[];
} __packed;

/* FIXME: How to calculate the buffer size sanely? */
+21 −21
Original line number Diff line number Diff line
@@ -289,12 +289,12 @@ struct htt_rx_ring_setup_hdr {

struct htt_rx_ring_setup_32 {
	struct htt_rx_ring_setup_hdr hdr;
	struct htt_rx_ring_setup_ring32 rings[0];
	struct htt_rx_ring_setup_ring32 rings[];
} __packed;

struct htt_rx_ring_setup_64 {
	struct htt_rx_ring_setup_hdr hdr;
	struct htt_rx_ring_setup_ring64 rings[0];
	struct htt_rx_ring_setup_ring64 rings[];
} __packed;

/*
@@ -732,7 +732,7 @@ struct htt_rx_indication {
	 * %mpdu_ranges starts after &%prefix + roundup(%fw_rx_desc_bytes, 4)
	 * and has %num_mpdu_ranges elements.
	 */
	struct htt_rx_indication_mpdu_range mpdu_ranges[0];
	struct htt_rx_indication_mpdu_range mpdu_ranges[];
} __packed;

/* High latency version of the RX indication */
@@ -741,7 +741,7 @@ struct htt_rx_indication_hl {
	struct htt_rx_indication_ppdu ppdu;
	struct htt_rx_indication_prefix prefix;
	struct fw_rx_desc_hl fw_desc;
	struct htt_rx_indication_mpdu_range mpdu_ranges[0];
	struct htt_rx_indication_mpdu_range mpdu_ranges[];
} __packed;

struct htt_hl_rx_desc {
@@ -908,7 +908,7 @@ struct htt_append_retries {
struct htt_data_tx_completion_ext {
	struct htt_append_retries a_retries;
	__le32 t_stamp;
	__le16 msdus_rssi[0];
	__le16 msdus_rssi[];
} __packed;

/**
@@ -992,7 +992,7 @@ struct htt_data_tx_completion {
	} __packed;
	u8 num_msdus;
	u8 flags2; /* HTT_TX_CMPL_FLAG_DATA_RSSI */
	__le16 msdus[0]; /* variable length based on %num_msdus */
	__le16 msdus[]; /* variable length based on %num_msdus */
} __packed;

#define HTT_TX_PPDU_DUR_INFO0_PEER_ID_MASK	GENMASK(15, 0)
@@ -1007,7 +1007,7 @@ struct htt_data_tx_ppdu_dur {

struct htt_data_tx_compl_ppdu_dur {
	__le32 info0; /* HTT_TX_COMPL_PPDU_DUR_INFO0_ */
	struct htt_data_tx_ppdu_dur ppdu_dur[0];
	struct htt_data_tx_ppdu_dur ppdu_dur[];
} __packed;

struct htt_tx_compl_ind_base {
@@ -1033,7 +1033,7 @@ struct htt_rc_update {
	u8 addr[6];
	u8 num_elems;
	u8 rsvd0;
	struct htt_rc_tx_done_params params[0]; /* variable length %num_elems */
	struct htt_rc_tx_done_params params[]; /* variable length %num_elems */
} __packed;

/* see htt_rx_indication for similar fields and descriptions */
@@ -1050,7 +1050,7 @@ struct htt_rx_fragment_indication {
	__le16 fw_rx_desc_bytes;
	__le16 rsvd0;

	u8 fw_msdu_rx_desc[0];
	u8 fw_msdu_rx_desc[];
} __packed;

#define ATH10K_IEEE80211_EXTIV               BIT(5)
@@ -1075,7 +1075,7 @@ struct htt_rx_pn_ind {
	u8 seqno_end;
	u8 pn_ie_count;
	u8 reserved;
	u8 pn_ies[0];
	u8 pn_ies[];
} __packed;

struct htt_rx_offload_msdu {
@@ -1084,7 +1084,7 @@ struct htt_rx_offload_msdu {
	u8 vdev_id;
	u8 tid;
	u8 fw_desc;
	u8 payload[0];
	u8 payload[];
} __packed;

struct htt_rx_offload_ind {
@@ -1167,7 +1167,7 @@ struct htt_rx_test {
	 *  a) num_ints * sizeof(__le32)
	 *  b) num_chars * sizeof(u8) aligned to 4bytes
	 */
	u8 payload[0];
	u8 payload[];
} __packed;

static inline __le32 *htt_rx_test_get_ints(struct htt_rx_test *rx_test)
@@ -1201,7 +1201,7 @@ static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test)
 */
struct htt_pktlog_msg {
	u8 pad[3];
	u8 payload[0];
	u8 payload[];
} __packed;

struct htt_dbg_stats_rx_reorder_stats {
@@ -1490,7 +1490,7 @@ struct htt_stats_conf_item {
	} __packed;
	u8 pad;
	__le16 length;
	u8 payload[0]; /* roundup(length, 4) long */
	u8 payload[]; /* roundup(length, 4) long */
} __packed;

struct htt_stats_conf {
@@ -1499,7 +1499,7 @@ struct htt_stats_conf {
	__le32 cookie_msb;

	/* each item has variable length! */
	struct htt_stats_conf_item items[0];
	struct htt_stats_conf_item items[];
} __packed;

static inline struct htt_stats_conf_item *htt_stats_conf_next_item(
@@ -1674,7 +1674,7 @@ struct htt_tx_fetch_ind {
	__le16 num_resp_ids;
	__le16 num_records;
	struct htt_tx_fetch_record records[0];
	__le32 resp_ids[0]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */
	__le32 resp_ids[]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */
} __packed;

static inline void *
@@ -1689,13 +1689,13 @@ struct htt_tx_fetch_resp {
	__le16 fetch_seq_num;
	__le16 num_records;
	__le32 token;
	struct htt_tx_fetch_record records[0];
	struct htt_tx_fetch_record records[];
} __packed;

struct htt_tx_fetch_confirm {
	u8 pad0;
	__le16 num_resp_ids;
	__le32 resp_ids[0];
	__le32 resp_ids[];
} __packed;

enum htt_tx_mode_switch_mode {
@@ -1727,7 +1727,7 @@ struct htt_tx_mode_switch_ind {
	__le16 info0; /* HTT_TX_MODE_SWITCH_IND_INFO0_ */
	__le16 info1; /* HTT_TX_MODE_SWITCH_IND_INFO1_ */
	u8 pad1[2];
	struct htt_tx_mode_switch_record records[0];
	struct htt_tx_mode_switch_record records[];
} __packed;

struct htt_channel_change {
@@ -1757,7 +1757,7 @@ struct htt_peer_tx_stats {
	u8 num_ppdu;
	u8 ppdu_len;
	u8 version;
	u8 payload[0];
	u8 payload[];
} __packed;

#define ATH10K_10_2_TX_STATS_OFFSET	136
@@ -2206,7 +2206,7 @@ struct htt_rx_desc {
		struct rx_ppdu_end ppdu_end;
	} __packed;
	u8 rx_hdr_status[RX_HTT_HDR_STATUS_LEN];
	u8 msdu_payload[0];
	u8 msdu_payload[];
};

#define HTT_RX_DESC_HL_INFO_SEQ_NUM_MASK           0x00000fff
Loading