USB: Replace zero-length array with flexible-array member
authorGustavo A. R. Silva <gustavo@embeddedor.com>
Thu, 20 Feb 2020 13:20:17 +0000 (07:20 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 23 Feb 2020 18:24:51 +0000 (19:24 +0100)
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@embeddedor.com>
Link: https://lore.kernel.org/r/20200220132017.GA29262@embeddedor
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
16 files changed:
drivers/usb/atm/usbatm.h
drivers/usb/dwc2/hcd.h
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci.h
drivers/usb/host/fotg210.h
drivers/usb/host/ohci.h
drivers/usb/host/xhci-mtk.h
drivers/usb/host/xhci.h
drivers/usb/serial/io_usbvend.h
drivers/usb/serial/ti_usb_3410_5052.c
include/linux/usb.h
include/linux/usb/audio-v2.h
include/linux/usb/audio-v3.h
include/linux/usb/gadget.h
include/linux/usb/hcd.h
include/linux/usbdevice_fs.h

index d3bdc4c..8725755 100644 (file)
@@ -164,7 +164,7 @@ struct usbatm_data {
        unsigned char *cell_buf;        /* holds partial rx cell */
        unsigned int buf_usage;
 
-       struct urb *urbs[0];
+       struct urb *urbs[];
 };
 
 static inline void *to_usbatm_driver_data(struct usb_interface *intf)
index 8ca6d12..1224fa9 100644 (file)
@@ -199,7 +199,7 @@ struct dwc2_hcd_urb {
        u32 flags;
        u16 interval;
        struct dwc2_hcd_pipe_info pipe_info;
-       struct dwc2_hcd_iso_packet_desc iso_descs[0];
+       struct dwc2_hcd_iso_packet_desc iso_descs[];
 };
 
 /* Phases for control transfers */
index d6433f2..10d51da 100644 (file)
@@ -282,7 +282,7 @@ done:
 struct dma_aligned_buffer {
        void *kmalloc_ptr;
        void *old_xfer_buffer;
-       u8 data[0];
+       u8 data[];
 };
 
 static void free_dma_aligned_buffer(struct urb *urb)
index ac5e967..229b3de 100644 (file)
@@ -255,7 +255,7 @@ struct ehci_hcd {                   /* one per controller */
        struct list_head        tt_list;
 
        /* platform-specific data -- must come last */
-       unsigned long           priv[0] __aligned(sizeof(s64));
+       unsigned long           priv[] __aligned(sizeof(s64));
 };
 
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
@@ -460,7 +460,7 @@ struct ehci_iso_sched {
        struct list_head        td_list;
        unsigned                span;
        unsigned                first_packet;
-       struct ehci_iso_packet  packet[0];
+       struct ehci_iso_packet  packet[];
 };
 
 /*
index 1b4db95..6cee40e 100644 (file)
@@ -490,7 +490,7 @@ struct fotg210_iso_packet {
 struct fotg210_iso_sched {
        struct list_head        td_list;
        unsigned                span;
-       struct fotg210_iso_packet       packet[0];
+       struct fotg210_iso_packet       packet[];
 };
 
 /*
index b015b00..27c26ca 100644 (file)
@@ -337,7 +337,7 @@ typedef struct urb_priv {
        u16                     length;         // # tds in this request
        u16                     td_cnt;         // tds already serviced
        struct list_head        pending;
-       struct td               *td [0];        // all TDs in this request
+       struct td               *td[];          // all TDs in this request
 
 } urb_priv_t;
 
@@ -435,7 +435,7 @@ struct ohci_hcd {
        struct dentry           *debug_dir;
 
        /* platform-specific data -- must come last */
-       unsigned long           priv[0] __aligned(sizeof(s64));
+       unsigned long           priv[] __aligned(sizeof(s64));
 
 };
 
index 5ac458b..acd5651 100644 (file)
@@ -95,7 +95,7 @@ struct mu3h_sch_ep_info {
        u32 pkts;
        u32 cs_count;
        u32 burst_mode;
-       u32 bw_budget_table[0];
+       u32 bw_budget_table[];
 };
 
 #define MU3C_U3_PORT_MAX 4
index 13d8838..5f47b18 100644 (file)
@@ -1642,7 +1642,7 @@ struct xhci_scratchpad {
 struct urb_priv {
        int     num_tds;
        int     num_tds_done;
-       struct  xhci_td td[0];
+       struct  xhci_td td[];
 };
 
 /*
@@ -1893,7 +1893,7 @@ struct xhci_hcd {
 
        void                    *dbc;
        /* platform-specific data -- must come last */
-       unsigned long           priv[0] __aligned(sizeof(s64));
+       unsigned long           priv[] __aligned(sizeof(s64));
 };
 
 /* Platform specific overrides to generic XHCI hc_driver ops */
index c38e87a..0d1a5bb 100644 (file)
@@ -593,7 +593,7 @@ struct ti_i2c_desc {
        __u8    Type;                   // Type of descriptor
        __le16  Size;                   // Size of data only not including header
        __u8    CheckSum;               // Checksum (8 bit sum of data only)
-       __u8    Data[0];                // Data starts here
+       __u8    Data[];         // Data starts here
 } __attribute__((packed));
 
 // for 5152 devices only (type 2 record)
@@ -601,7 +601,7 @@ struct ti_i2c_desc {
 struct ti_i2c_firmware_rec {
        __u8    Ver_Major;              // Firmware Major version number
        __u8    Ver_Minor;              // Firmware Minor version number
-       __u8    Data[0];                // Download starts here
+       __u8    Data[];         // Download starts here
 } __attribute__((packed));
 
 
index ef23acc..73075b9 100644 (file)
@@ -219,7 +219,7 @@ struct ti_write_data_bytes {
        u8      bDataCounter;
        __be16  wBaseAddrHi;
        __be16  wBaseAddrLo;
-       u8      bData[0];
+       u8      bData[];
 } __packed;
 
 struct ti_read_data_request {
@@ -234,7 +234,7 @@ struct ti_read_data_bytes {
        __u8    bCmdCode;
        __u8    bModuleId;
        __u8    bErrorCode;
-       __u8    bData[0];
+       __u8    bData[];
 } __packed;
 
 /* Interrupt struct */
index ca1a5f1..9f3c721 100644 (file)
@@ -325,7 +325,7 @@ struct usb_interface_cache {
 
        /* variable-length array of alternate settings for this interface,
         * stored in no particular order */
-       struct usb_host_interface altsetting[0];
+       struct usb_host_interface altsetting[];
 };
 #define        ref_to_usb_interface_cache(r) \
                container_of(r, struct usb_interface_cache, ref)
@@ -1589,7 +1589,7 @@ struct urb {
        int error_count;                /* (return) number of ISO errors */
        void *context;                  /* (in) context for completion */
        usb_complete_t complete;        /* (in) completion routine */
-       struct usb_iso_packet_descriptor iso_frame_desc[0];
+       struct usb_iso_packet_descriptor iso_frame_desc[];
                                        /* (in) ISO ONLY */
 };
 
index ba4b3e3..5e31740 100644 (file)
@@ -153,7 +153,7 @@ struct uac2_feature_unit_descriptor {
        __u8 bSourceID;
        /* bmaControls is actually u32,
         * but u8 is needed for the hybrid parser */
-       __u8 bmaControls[0]; /* variable length */
+       __u8 bmaControls[]; /* variable length */
 } __attribute__((packed));
 
 /* 4.9.2 Class-Specific AS Interface Descriptor */
index 6b70843..c69a6f2 100644 (file)
@@ -109,7 +109,7 @@ struct uac3_feature_unit_descriptor {
        __u8 bSourceID;
        /* bmaControls is actually u32,
         * but u8 is needed for the hybrid parser */
-       __u8 bmaControls[0]; /* variable length */
+       __u8 bmaControls[]; /* variable length */
        /* wFeatureDescrStr omitted */
 } __attribute__((packed));
 
index 124462d..9411c08 100644 (file)
@@ -767,7 +767,7 @@ struct usb_gadget_strings {
 
 struct usb_gadget_string_container {
        struct list_head        list;
-       u8                      *stash[0];
+       u8                      *stash[];
 };
 
 /* put descriptor for string with that id into buf (buflen >= 256) */
index 712b2a6..e12105e 100644 (file)
@@ -228,7 +228,7 @@ struct usb_hcd {
        /* The HC driver's private data is stored at the end of
         * this structure.
         */
-       unsigned long hcd_priv[0]
+       unsigned long hcd_priv[]
                        __attribute__ ((aligned(sizeof(s64))));
 };
 
index 79aab00..14ea197 100644 (file)
@@ -69,7 +69,7 @@ struct usbdevfs_urb32 {
        compat_int_t error_count;
        compat_uint_t signr;
        compat_caddr_t usercontext; /* unused */
-       struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+       struct usbdevfs_iso_packet_desc iso_frame_desc[];
 };
 
 struct usbdevfs_ioctl32 {