scsi: Replace zero-length array with flexible-array member
authorGustavo A. R. Silva <gustavo@embeddedor.com>
Mon, 24 Feb 2020 16:14:06 +0000 (10:14 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 12 Mar 2020 03:07:56 +0000 (23:07 -0400)
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")

Link: https://lore.kernel.org/r/20200224161406.GA21454@embeddedor
Reviewed-by: Lee Duncan <lduncan@suse.com>
Reviewed-by: Satish Kharat <satishkh@cisco.com>
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
16 files changed:
drivers/scsi/fnic/vnic_devcmd.h
drivers/scsi/ipr.h
drivers/scsi/isci/sas.h
drivers/scsi/mpt3sas/mpt3sas_scsih.c
drivers/scsi/mvsas/mv_sas.h
drivers/scsi/mvumi.h
drivers/scsi/pmcraid.h
drivers/scsi/snic/vnic_devcmd.h
drivers/scsi/stex.c
include/scsi/iscsi_if.h
include/scsi/scsi_bsg_iscsi.h
include/scsi/scsi_device.h
include/scsi/scsi_host.h
include/scsi/scsi_ioctl.h
include/scsi/srp.h
include/uapi/scsi/scsi_bsg_fc.h

index c5dde556dc7c548491ca7353f0e884c319692cd2..c20d30e36dfc065b856c1e46bf37c7606617d813 100644 (file)
@@ -442,7 +442,7 @@ struct vnic_devcmd_notify {
 struct vnic_devcmd_provinfo {
        u8 oui[3];
        u8 type;
-       u8 data[0];
+       u8 data[];
 };
 
 /*
index a67baeb36d1f7e942149427b349f5d8cd456e843..fd3929a19ab5d64b7bd54cd5c5bed69ae19d6af4 100644 (file)
@@ -451,12 +451,12 @@ struct ipr_config_table_hdr64 {
 
 struct ipr_config_table {
        struct ipr_config_table_hdr hdr;
-       struct ipr_config_table_entry dev[0];
+       struct ipr_config_table_entry dev[];
 }__attribute__((packed, aligned (4)));
 
 struct ipr_config_table64 {
        struct ipr_config_table_hdr64 hdr64;
-       struct ipr_config_table_entry64 dev[0];
+       struct ipr_config_table_entry64 dev[];
 }__attribute__((packed, aligned (8)));
 
 struct ipr_config_table_entry_wrapper {
@@ -792,7 +792,7 @@ struct ipr_mode_page28 {
        struct ipr_mode_page_hdr hdr;
        u8 num_entries;
        u8 entry_length;
-       struct ipr_dev_bus_entry bus[0];
+       struct ipr_dev_bus_entry bus[];
 }__attribute__((packed));
 
 struct ipr_mode_page24 {
index dc26b4aea99e6fb636d3868071768cbf897ccc5b..15d8f3631ab74be8e476b3544b145798d573ae84 100644 (file)
@@ -201,7 +201,7 @@ struct smp_req {
        u8 func;                /* byte 1 */
        u8 alloc_resp_len;      /* byte 2 */
        u8 req_len;             /* byte 3 */
-       u8 req_data[0];
+       u8 req_data[];
 }  __packed;
 
 /*
index c597d544eb3927da2a0679ef9143fbd6e74922c8..778d5e6ce38505192ff4a0b89418650069449c18 100644 (file)
@@ -207,7 +207,7 @@ struct fw_event_work {
        u8                      ignore;
        u16                     event;
        struct kref             refcount;
-       char                    event_data[0] __aligned(4);
+       char                    event_data[] __aligned(4);
 };
 
 static void fw_event_work_free(struct kref *r)
index 519edc796691a627518977164dda1d20e15a464c..327fdd5ee962f2708b6ea38e26f42c7425e1d611 100644 (file)
@@ -394,7 +394,7 @@ struct mvs_info {
        dma_addr_t bulk_buffer_dma1;
 #define TRASH_BUCKET_SIZE      0x20000
        void *dma_pool;
-       struct mvs_slot_info slot_info[0];
+       struct mvs_slot_info slot_info[];
 };
 
 struct mvs_prv_info{
index ec8cc2207536108dd215cc06e1bf93e15ada0dec..60d5691fc4ab28a3e753101cf991c3e3a9fb8298 100644 (file)
@@ -130,7 +130,7 @@ enum {
 struct mvumi_hotplug_event {
        u16 size;
        u8 dummy[2];
-       u8 bitmap[0];
+       u8 bitmap[];
 };
 
 struct mvumi_driver_event {
@@ -290,7 +290,7 @@ struct mvumi_rsp_frame {
 
 struct mvumi_ob_data {
        struct list_head list;
-       unsigned char data[0];
+       unsigned char data[];
 };
 
 struct version_info {
index a4f7eb8f50a3352e4d579edf36b04f6361654087..15c962108075f803892a4abfbe1489a7e53ac729 100644 (file)
@@ -623,7 +623,7 @@ struct pmcraid_aen_msg {
        u32 hostno;
        u32 length;
        u8  reserved[8];
-       u8  data[0];
+       u8  data[];
 };
 
 /* Controller state event message type */
index d81b4f0ceaaa3842eaf6d254fbe54b6af3cee6bf..0e0fa38f8d901e70fb4dcdfbec83a1706d274e93 100644 (file)
@@ -208,7 +208,7 @@ struct vnic_devcmd_notify {
 struct vnic_devcmd_provinfo {
        u8 oui[3];
        u8 type;
-       u8 data[0];
+       u8 data[];
 };
 
 /*
index 33287b6bdf0ef9c1788d89d269c680de0610ebec..d4f10c0d813cf49b3309f1f13d832b4e4b6028a0 100644 (file)
@@ -236,7 +236,7 @@ struct req_msg {
        u8 data_dir;
        u8 payload_sz;          /* payload size in 4-byte, not used */
        u8 cdb[STEX_CDB_LENGTH];
-       u32 variable[0];
+       u32 variable[];
 };
 
 struct status_msg {
index 92b11c7e0b4f22ecdaad25bf5d66e2ae7fc61a22..b0e240b10bf97381b574117ab41e55a0de714364 100644 (file)
@@ -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));
 };
 
index fa0c820a1663904886f9610c43d8bbe43e6e3f36..6b8128005af8f40aee50b057799265c032e1387c 100644 (file)
@@ -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:
index f146a45577874db349d31e0304fabf8595317e45..579e24c92f2f7c0d47ea8beac074141a61fa9a1d 100644 (file)
@@ -230,7 +230,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)       \
@@ -314,7 +314,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))));
 
index 7464394e7d01d8fe780fc859e51935a0ea55119f..822e8cda8d9b5ac1b9b9bff4b20e26ea13cc2093 100644 (file)
@@ -683,7 +683,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))));
 };
 
index 4fe69d863b5d7ee819b47e0671d74e2d41a947a3..b465799f4d2d682f8d7819b9cde07fd64849d2ce 100644 (file)
@@ -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 {
index 9220758d5087ef25bb769245ed24564179402f7a..177d8026e96f5fba4192695c692cb7b1c4338461 100644 (file)
@@ -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 {
index 3ae65e93235cf77ffbae4a37fff9bbe35e600933..7f5930801f722164013fc143dff0fcb3568dfbdd 100644 (file)
@@ -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: