On 2/24/20 8:14 AM, Gustavo A. R. Silva wrote: > 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") > > Signed-off-by: Gustavo A. R. Silva <gustavo@xxxxxxxxxxxxxx> > --- > ... > diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h > index 92b11c7e0b4f..b0e240b10bf9 100644 > --- a/include/scsi/iscsi_if.h > +++ b/include/scsi/iscsi_if.h > @@ -311,7 +311,7 @@ enum iscsi_param_type { > struct iscsi_param_info { > uint32_t len; /* Actual length of the param value */ > uint16_t param; /* iscsi param */ > - uint8_t value[0]; /* length sized value follows */ > + uint8_t value[]; /* length sized value follows */ > } __packed; > > struct iscsi_iface_param_info { > @@ -320,7 +320,7 @@ struct iscsi_iface_param_info { > uint16_t param; /* iscsi param value */ > uint8_t iface_type; /* IPv4 or IPv6 */ > uint8_t param_type; /* iscsi_param_type */ > - uint8_t value[0]; /* length sized value follows */ > + uint8_t value[]; /* length sized value follows */ > } __packed; > > /* > @@ -697,7 +697,7 @@ enum iscsi_flashnode_param { > struct iscsi_flashnode_param_info { > uint32_t len; /* Actual length of the param */ > uint16_t param; /* iscsi param value */ > - uint8_t value[0]; /* length sized value follows */ > + uint8_t value[]; /* length sized value follows */ > } __packed; > > enum iscsi_discovery_parent_type { > @@ -815,7 +815,7 @@ struct iscsi_stats { > * up to ISCSI_STATS_CUSTOM_MAX > */ > uint32_t custom_length; > - struct iscsi_stats_custom custom[0] > + struct iscsi_stats_custom custom[] > __attribute__ ((aligned (sizeof(uint64_t)))); > }; > > @@ -946,7 +946,7 @@ struct iscsi_offload_host_stats { > * up to ISCSI_HOST_STATS_CUSTOM_MAX > */ > uint32_t custom_length; > - struct iscsi_host_stats_custom custom[0] > + struct iscsi_host_stats_custom custom[] > __aligned(sizeof(uint64_t)); > }; > > diff --git a/include/scsi/scsi_bsg_iscsi.h b/include/scsi/scsi_bsg_iscsi.h > index fa0c820a1663..6b8128005af8 100644 > --- a/include/scsi/scsi_bsg_iscsi.h > +++ b/include/scsi/scsi_bsg_iscsi.h > @@ -52,7 +52,7 @@ struct iscsi_bsg_host_vendor { > uint64_t vendor_id; > > /* start of vendor command area */ > - uint32_t vendor_cmd[0]; > + uint32_t vendor_cmd[]; > }; > > /* Response: > diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h > index f8312a3e5b42..4dc158cf09b8 100644 > --- a/include/scsi/scsi_device.h > +++ b/include/scsi/scsi_device.h > @@ -231,7 +231,7 @@ struct scsi_device { > struct mutex state_mutex; > enum scsi_device_state sdev_state; > struct task_struct *quiesced_by; > - unsigned long sdev_data[0]; > + unsigned long sdev_data[]; > } __attribute__((aligned(sizeof(unsigned long)))); > > #define to_scsi_device(d) \ > @@ -315,7 +315,7 @@ struct scsi_target { > char scsi_level; > enum scsi_target_state state; > void *hostdata; /* available to low-level driver */ > - unsigned long starget_data[0]; /* for the transport */ > + unsigned long starget_data[]; /* for the transport */ > /* starget_data must be the last element!!!! */ > } __attribute__((aligned(sizeof(unsigned long)))); > > diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h > index 7a97fb8104cf..e6811ea8f984 100644 > --- a/include/scsi/scsi_host.h > +++ b/include/scsi/scsi_host.h > @@ -682,7 +682,7 @@ struct Scsi_Host { > * and also because some compilers (m68k) don't automatically force > * alignment to a long boundary. > */ > - unsigned long hostdata[0] /* Used for storage of host specific stuff */ > + unsigned long hostdata[] /* Used for storage of host specific stuff */ > __attribute__ ((aligned (sizeof(unsigned long)))); > }; > > diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h > index 4fe69d863b5d..b465799f4d2d 100644 > --- a/include/scsi/scsi_ioctl.h > +++ b/include/scsi/scsi_ioctl.h > @@ -27,7 +27,7 @@ struct scsi_device; > typedef struct scsi_ioctl_command { > unsigned int inlen; > unsigned int outlen; > - unsigned char data[0]; > + unsigned char data[]; > } Scsi_Ioctl_Command; > > typedef struct scsi_idlun { > diff --git a/include/scsi/srp.h b/include/scsi/srp.h > index 9220758d5087..177d8026e96f 100644 > --- a/include/scsi/srp.h > +++ b/include/scsi/srp.h > @@ -109,7 +109,7 @@ struct srp_direct_buf { > struct srp_indirect_buf { > struct srp_direct_buf table_desc; > __be32 len; > - struct srp_direct_buf desc_list[0]; > + struct srp_direct_buf desc_list[]; > } __attribute__((packed)); > > /* Immediate data buffer descriptor as defined in SRP2. */ > @@ -244,7 +244,7 @@ struct srp_cmd { > u8 reserved4; > u8 add_cdb_len; > u8 cdb[16]; > - u8 add_data[0]; > + u8 add_data[]; > }; > > enum { > @@ -274,7 +274,7 @@ struct srp_rsp { > __be32 data_in_res_cnt; > __be32 sense_data_len; > __be32 resp_data_len; > - u8 data[0]; > + u8 data[]; > } __attribute__((packed)); > > struct srp_cred_req { > @@ -306,7 +306,7 @@ struct srp_aer_req { > struct scsi_lun lun; > __be32 sense_data_len; > u32 reserved3; > - u8 sense_data[0]; > + u8 sense_data[]; > } __attribute__((packed)); > > struct srp_aer_rsp { > diff --git a/include/uapi/scsi/scsi_bsg_fc.h b/include/uapi/scsi/scsi_bsg_fc.h > index 3ae65e93235c..7f5930801f72 100644 > --- a/include/uapi/scsi/scsi_bsg_fc.h > +++ b/include/uapi/scsi/scsi_bsg_fc.h > @@ -209,7 +209,7 @@ struct fc_bsg_host_vendor { > __u64 vendor_id; > > /* start of vendor command area */ > - __u32 vendor_cmd[0]; > + __u32 vendor_cmd[]; > }; > > /* Response: > Reviewed-by: Lee Duncan <lduncan@xxxxxxxx>