Commit 5b361328 authored by Gustavo A. R. Silva's avatar Gustavo A. R. Silva Committed by Jason Gunthorpe

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

Link: https://lore.kernel.org/r/20200213010425.GA13068@embeddedor.comSigned-off-by: default avatarGustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> # added a few more
parent 52c5e9e7
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
struct ib_pkey_cache { struct ib_pkey_cache {
int table_len; int table_len;
u16 table[0]; u16 table[];
}; };
struct ib_update_work { struct ib_update_work {
......
...@@ -197,7 +197,7 @@ struct cm_device { ...@@ -197,7 +197,7 @@ struct cm_device {
struct ib_device *ib_device; struct ib_device *ib_device;
u8 ack_delay; u8 ack_delay;
int going_down; int going_down;
struct cm_port *port[0]; struct cm_port *port[];
}; };
struct cm_av { struct cm_av {
...@@ -216,7 +216,7 @@ struct cm_work { ...@@ -216,7 +216,7 @@ struct cm_work {
__be32 local_id; /* Established / timewait */ __be32 local_id; /* Established / timewait */
__be32 remote_id; __be32 remote_id;
struct ib_cm_event cm_event; struct ib_cm_event cm_event;
struct sa_path_rec path[0]; struct sa_path_rec path[];
}; };
struct cm_timewait_info { struct cm_timewait_info {
......
...@@ -79,13 +79,13 @@ struct ib_mad_private { ...@@ -79,13 +79,13 @@ struct ib_mad_private {
struct ib_mad_private_header header; struct ib_mad_private_header header;
size_t mad_size; size_t mad_size;
struct ib_grh grh; struct ib_grh grh;
u8 mad[0]; u8 mad[];
} __packed; } __packed;
struct ib_rmpp_segment { struct ib_rmpp_segment {
struct list_head list; struct list_head list;
u32 num; u32 num;
u8 data[0]; u8 data[];
}; };
struct ib_mad_agent_private { struct ib_mad_agent_private {
......
...@@ -71,7 +71,7 @@ struct mcast_device { ...@@ -71,7 +71,7 @@ struct mcast_device {
struct ib_event_handler event_handler; struct ib_event_handler event_handler;
int start_port; int start_port;
int end_port; int end_port;
struct mcast_port port[0]; struct mcast_port port[];
}; };
enum mcast_state { enum mcast_state {
......
...@@ -101,7 +101,7 @@ struct ib_sa_port { ...@@ -101,7 +101,7 @@ struct ib_sa_port {
struct ib_sa_device { struct ib_sa_device {
int start_port, end_port; int start_port, end_port;
struct ib_event_handler event_handler; struct ib_event_handler event_handler;
struct ib_sa_port port[0]; struct ib_sa_port port[];
}; };
struct ib_sa_query { struct ib_sa_query {
......
...@@ -707,7 +707,7 @@ struct mpa_message { ...@@ -707,7 +707,7 @@ struct mpa_message {
u8 flags; u8 flags;
u8 revision; u8 revision;
__be16 private_data_size; __be16 private_data_size;
u8 private_data[0]; u8 private_data[];
}; };
struct mpa_v2_conn_params { struct mpa_v2_conn_params {
...@@ -719,7 +719,7 @@ struct terminate_message { ...@@ -719,7 +719,7 @@ struct terminate_message {
u8 layer_etype; u8 layer_etype;
u8 ecode; u8 ecode;
__be16 hdrct_rsvd; __be16 hdrct_rsvd;
u8 len_hdrs[0]; u8 len_hdrs[];
}; };
#define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28) #define TERM_MAX_LENGTH (sizeof(struct terminate_message) + 2 + 18 + 28)
......
...@@ -123,7 +123,7 @@ struct fw_ri_dsgl { ...@@ -123,7 +123,7 @@ struct fw_ri_dsgl {
__be32 len0; __be32 len0;
__be64 addr0; __be64 addr0;
#ifndef C99_NOT_SUPPORTED #ifndef C99_NOT_SUPPORTED
struct fw_ri_dsge_pair sge[0]; struct fw_ri_dsge_pair sge[];
#endif #endif
}; };
...@@ -139,7 +139,7 @@ struct fw_ri_isgl { ...@@ -139,7 +139,7 @@ struct fw_ri_isgl {
__be16 nsge; __be16 nsge;
__be32 r2; __be32 r2;
#ifndef C99_NOT_SUPPORTED #ifndef C99_NOT_SUPPORTED
struct fw_ri_sge sge[0]; struct fw_ri_sge sge[];
#endif #endif
}; };
...@@ -149,7 +149,7 @@ struct fw_ri_immd { ...@@ -149,7 +149,7 @@ struct fw_ri_immd {
__be16 r2; __be16 r2;
__be32 immdlen; __be32 immdlen;
#ifndef C99_NOT_SUPPORTED #ifndef C99_NOT_SUPPORTED
__u8 data[0]; __u8 data[];
#endif #endif
}; };
...@@ -321,7 +321,7 @@ struct fw_ri_res_wr { ...@@ -321,7 +321,7 @@ struct fw_ri_res_wr {
__be32 len16_pkd; __be32 len16_pkd;
__u64 cookie; __u64 cookie;
#ifndef C99_NOT_SUPPORTED #ifndef C99_NOT_SUPPORTED
struct fw_ri_res res[0]; struct fw_ri_res res[];
#endif #endif
}; };
......
...@@ -2381,7 +2381,7 @@ struct opa_port_status_rsp { ...@@ -2381,7 +2381,7 @@ struct opa_port_status_rsp {
__be64 port_vl_rcv_bubble; __be64 port_vl_rcv_bubble;
__be64 port_vl_mark_fecn; __be64 port_vl_mark_fecn;
__be64 port_vl_xmit_discards; __be64 port_vl_xmit_discards;
} vls[0]; /* real array size defined by # bits set in vl_select_mask */ } vls[]; /* real array size defined by # bits set in vl_select_mask */
}; };
enum counter_selects { enum counter_selects {
...@@ -2423,7 +2423,7 @@ struct opa_aggregate { ...@@ -2423,7 +2423,7 @@ struct opa_aggregate {
__be16 attr_id; __be16 attr_id;
__be16 err_reqlength; /* 1 bit, 8 res, 7 bit */ __be16 err_reqlength; /* 1 bit, 8 res, 7 bit */
__be32 attr_mod; __be32 attr_mod;
u8 data[0]; u8 data[];
}; };
#define MSK_LLI 0x000000f0 #define MSK_LLI 0x000000f0
......
...@@ -165,7 +165,7 @@ struct opa_mad_notice_attr { ...@@ -165,7 +165,7 @@ struct opa_mad_notice_attr {
} __packed ntc_2048; } __packed ntc_2048;
}; };
u8 class_data[0]; u8 class_data[];
}; };
#define IB_VLARB_LOWPRI_0_31 1 #define IB_VLARB_LOWPRI_0_31 1
......
...@@ -243,7 +243,7 @@ struct sc_config_sizes { ...@@ -243,7 +243,7 @@ struct sc_config_sizes {
*/ */
struct pio_map_elem { struct pio_map_elem {
u32 mask; u32 mask;
struct send_context *ksc[0]; struct send_context *ksc[];
}; };
/* /*
...@@ -263,7 +263,7 @@ struct pio_vl_map { ...@@ -263,7 +263,7 @@ struct pio_vl_map {
u32 mask; u32 mask;
u8 actual_vls; u8 actual_vls;
u8 vls; u8 vls;
struct pio_map_elem *map[0]; struct pio_map_elem *map[];
}; };
int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls,
......
...@@ -833,7 +833,7 @@ struct sdma_engine *sdma_select_engine_sc( ...@@ -833,7 +833,7 @@ struct sdma_engine *sdma_select_engine_sc(
struct sdma_rht_map_elem { struct sdma_rht_map_elem {
u32 mask; u32 mask;
u8 ctr; u8 ctr;
struct sdma_engine *sde[0]; struct sdma_engine *sde[];
}; };
struct sdma_rht_node { struct sdma_rht_node {
......
...@@ -1002,7 +1002,7 @@ void sdma_engine_interrupt(struct sdma_engine *sde, u64 status); ...@@ -1002,7 +1002,7 @@ void sdma_engine_interrupt(struct sdma_engine *sde, u64 status);
*/ */
struct sdma_map_elem { struct sdma_map_elem {
u32 mask; u32 mask;
struct sdma_engine *sde[0]; struct sdma_engine *sde[];
}; };
/** /**
...@@ -1024,7 +1024,7 @@ struct sdma_vl_map { ...@@ -1024,7 +1024,7 @@ struct sdma_vl_map {
u32 mask; u32 mask;
u8 actual_vls; u8 actual_vls;
u8 vls; u8 vls;
struct sdma_map_elem *map[0]; struct sdma_map_elem *map[];
}; };
int sdma_map_init( int sdma_map_init(
......
...@@ -73,7 +73,7 @@ struct tid_rb_node { ...@@ -73,7 +73,7 @@ struct tid_rb_node {
dma_addr_t dma_addr; dma_addr_t dma_addr;
bool freed; bool freed;
unsigned int npages; unsigned int npages;
struct page *pages[0]; struct page *pages[];
}; };
static inline int num_user_pages(unsigned long addr, static inline int num_user_pages(unsigned long addr,
......
...@@ -85,7 +85,7 @@ struct ietf_mpa_v1 { ...@@ -85,7 +85,7 @@ struct ietf_mpa_v1 {
u8 flags; u8 flags;
u8 rev; u8 rev;
__be16 priv_data_len; __be16 priv_data_len;
u8 priv_data[0]; u8 priv_data[];
}; };
#define ietf_mpa_req_resp_frame ietf_mpa_frame #define ietf_mpa_req_resp_frame ietf_mpa_frame
...@@ -101,7 +101,7 @@ struct ietf_mpa_v2 { ...@@ -101,7 +101,7 @@ struct ietf_mpa_v2 {
u8 rev; u8 rev;
__be16 priv_data_len; __be16 priv_data_len;
struct ietf_rtr_msg rtr_msg; struct ietf_rtr_msg rtr_msg;
u8 priv_data[0]; u8 priv_data[];
}; };
struct i40iw_cm_node; struct i40iw_cm_node;
......
...@@ -58,7 +58,7 @@ struct mthca_user_db_table { ...@@ -58,7 +58,7 @@ struct mthca_user_db_table {
u64 uvirt; u64 uvirt;
struct scatterlist mem; struct scatterlist mem;
int refcount; int refcount;
} page[0]; } page[];
}; };
static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *chunk) static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *chunk)
......
...@@ -68,7 +68,7 @@ struct mthca_icm_table { ...@@ -68,7 +68,7 @@ struct mthca_icm_table {
int lowmem; int lowmem;
int coherent; int coherent;
struct mutex mutex; struct mutex mutex;
struct mthca_icm *icm[0]; struct mthca_icm *icm[];
}; };
struct mthca_icm_iter { struct mthca_icm_iter {
......
...@@ -77,7 +77,7 @@ struct usnic_uiom_reg { ...@@ -77,7 +77,7 @@ struct usnic_uiom_reg {
struct usnic_uiom_chunk { struct usnic_uiom_chunk {
struct list_head list; struct list_head list;
int nents; int nents;
struct scatterlist page_list[0]; struct scatterlist page_list[];
}; };
struct usnic_uiom_pd *usnic_uiom_alloc_pd(void); struct usnic_uiom_pd *usnic_uiom_alloc_pd(void);
......
...@@ -63,7 +63,7 @@ struct rxe_queue_buf { ...@@ -63,7 +63,7 @@ struct rxe_queue_buf {
__u32 pad_2[31]; __u32 pad_2[31];
__u32 consumer_index; __u32 consumer_index;
__u32 pad_3[31]; __u32 pad_3[31];
__u8 data[0]; __u8 data[];
}; };
struct rxe_queue { struct rxe_queue {
......
...@@ -258,7 +258,7 @@ struct opa_veswport_mactable { ...@@ -258,7 +258,7 @@ struct opa_veswport_mactable {
__be16 offset; __be16 offset;
__be16 num_entries; __be16 num_entries;
__be32 mac_tbl_digest; __be32 mac_tbl_digest;
struct opa_veswport_mactable_entry tbl_entries[0]; struct opa_veswport_mactable_entry tbl_entries[];
} __packed; } __packed;
/** /**
...@@ -440,7 +440,7 @@ struct opa_veswport_iface_macs { ...@@ -440,7 +440,7 @@ struct opa_veswport_iface_macs {
__be16 num_macs_in_msg; __be16 num_macs_in_msg;
__be16 tot_macs_in_lst; __be16 tot_macs_in_lst;
__be16 gen_count; __be16 gen_count;
struct opa_vnic_iface_mac_entry entry[0]; struct opa_vnic_iface_mac_entry entry[];
} __packed; } __packed;
/** /**
......
...@@ -309,7 +309,7 @@ struct srp_fr_pool { ...@@ -309,7 +309,7 @@ struct srp_fr_pool {
int max_page_list_len; int max_page_list_len;
spinlock_t lock; spinlock_t lock;
struct list_head free_list; struct list_head free_list;
struct srp_fr_desc desc[0]; struct srp_fr_desc desc[];
}; };
/** /**
......
...@@ -73,7 +73,7 @@ struct ib_pool_fmr { ...@@ -73,7 +73,7 @@ struct ib_pool_fmr {
int remap_count; int remap_count;
u64 io_virtual_address; u64 io_virtual_address;
int page_list_len; int page_list_len;
u64 page_list[0]; u64 page_list[];
}; };
struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
......
...@@ -1876,7 +1876,7 @@ struct ib_flow_eth_filter { ...@@ -1876,7 +1876,7 @@ struct ib_flow_eth_filter {
__be16 ether_type; __be16 ether_type;
__be16 vlan_tag; __be16 vlan_tag;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_eth { struct ib_flow_spec_eth {
...@@ -1890,7 +1890,7 @@ struct ib_flow_ib_filter { ...@@ -1890,7 +1890,7 @@ struct ib_flow_ib_filter {
__be16 dlid; __be16 dlid;
__u8 sl; __u8 sl;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_ib { struct ib_flow_spec_ib {
...@@ -1915,7 +1915,7 @@ struct ib_flow_ipv4_filter { ...@@ -1915,7 +1915,7 @@ struct ib_flow_ipv4_filter {
u8 ttl; u8 ttl;
u8 flags; u8 flags;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_ipv4 { struct ib_flow_spec_ipv4 {
...@@ -1933,7 +1933,7 @@ struct ib_flow_ipv6_filter { ...@@ -1933,7 +1933,7 @@ struct ib_flow_ipv6_filter {
u8 traffic_class; u8 traffic_class;
u8 hop_limit; u8 hop_limit;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_ipv6 { struct ib_flow_spec_ipv6 {
...@@ -1947,7 +1947,7 @@ struct ib_flow_tcp_udp_filter { ...@@ -1947,7 +1947,7 @@ struct ib_flow_tcp_udp_filter {
__be16 dst_port; __be16 dst_port;
__be16 src_port; __be16 src_port;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_tcp_udp { struct ib_flow_spec_tcp_udp {
...@@ -1959,7 +1959,7 @@ struct ib_flow_spec_tcp_udp { ...@@ -1959,7 +1959,7 @@ struct ib_flow_spec_tcp_udp {
struct ib_flow_tunnel_filter { struct ib_flow_tunnel_filter {
__be32 tunnel_id; __be32 tunnel_id;
u8 real_sz[0]; u8 real_sz[];
}; };
/* ib_flow_spec_tunnel describes the Vxlan tunnel /* ib_flow_spec_tunnel describes the Vxlan tunnel
...@@ -1976,7 +1976,7 @@ struct ib_flow_esp_filter { ...@@ -1976,7 +1976,7 @@ struct ib_flow_esp_filter {
__be32 spi; __be32 spi;
__be32 seq; __be32 seq;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_esp { struct ib_flow_spec_esp {
...@@ -1991,7 +1991,7 @@ struct ib_flow_gre_filter { ...@@ -1991,7 +1991,7 @@ struct ib_flow_gre_filter {
__be16 protocol; __be16 protocol;
__be32 key; __be32 key;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_gre { struct ib_flow_spec_gre {
...@@ -2004,7 +2004,7 @@ struct ib_flow_spec_gre { ...@@ -2004,7 +2004,7 @@ struct ib_flow_spec_gre {
struct ib_flow_mpls_filter { struct ib_flow_mpls_filter {
__be32 tag; __be32 tag;
/* Must be last */ /* Must be last */
u8 real_sz[0]; u8 real_sz[];
}; };
struct ib_flow_spec_mpls { struct ib_flow_spec_mpls {
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
struct opa_vnic_rdma_netdev { struct opa_vnic_rdma_netdev {
struct rdma_netdev rn; /* keep this first */ struct rdma_netdev rn; /* keep this first */
/* followed by device private data */ /* followed by device private data */
char *dev_priv[0]; char *dev_priv[];
}; };
static inline void *opa_vnic_priv(const struct net_device *dev) static inline void *opa_vnic_priv(const struct net_device *dev)
......
...@@ -85,7 +85,7 @@ struct rvt_mregion { ...@@ -85,7 +85,7 @@ struct rvt_mregion {
u8 lkey_published; /* in global table */ u8 lkey_published; /* in global table */
struct percpu_ref refcount; struct percpu_ref refcount;
struct completion comp; /* complete when refcount goes to zero */ struct completion comp; /* complete when refcount goes to zero */
struct rvt_segarray *map[0]; /* the segments */ struct rvt_segarray *map[]; /* the segments */
}; };
#define RVT_MAX_LKEY_TABLE_BITS 23 #define RVT_MAX_LKEY_TABLE_BITS 23
......
...@@ -191,7 +191,7 @@ struct rvt_swqe { ...@@ -191,7 +191,7 @@ struct rvt_swqe {
u32 ssn; /* send sequence number */ u32 ssn; /* send sequence number */
u32 length; /* total length of data in sg_list */ u32 length; /* total length of data in sg_list */
void *priv; /* driver dependent field */ void *priv; /* driver dependent field */
struct rvt_sge sg_list[0]; struct rvt_sge sg_list[];
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment