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 d3bdc4cc47aa8d7519a2b7c43acd07eb297fc079..8725755bd53deb020c1afefadd1bdd12da65a1b6 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 8ca6d12a6f5701318d9665ad950d3be82f657e6e..1224fa9df604b4760077b2d063f057d9bbe7b425 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 d6433f206c17063f6e170a3bdd89f2d5dee7af51..10d51daa6a1bb9bc97d257cace287fdd40bf16f9 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 ac5e967907d1412fc403256d22a5369807275eca..229b3de319e64eda9df96265f4ddea95752fafcb 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 1b4db95e5c43aef564e6f47fb5fd441d1b954634..6cee40ec65b4140b0a1352b7b7a8405e8c6889db 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 b015b00774b217c2e42b27920e34c25485615ddc..27c26ca10bfd89aca6fa798383938630c474559a 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 5ac458b7d2e0efa406e5db2ca57dfe3dde59e550..acd56517215aeefe27abd5d27fa695d477bb95ec 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 13d8838cd552be01b145e0d2f78dc815c3ffad0b..5f47b18609ee44f3e24adfa9630482841e443ee2 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 c38e87ac5ea9ea9665115cb74167b311a59c9c7c..0d1a5bb4636ef169ec1c4632992f3fc32b945b92 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 ef23acc9b9ce4bc8fe8ccb8197b42f69928a87b3..73075b9351c58694e4239fe6b18eec4da2fddc42 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 ca1a5f1e1c5eec435c07456682163c64d3ae486b..9f3c721c70dc16be937a039256d38438a14516e8 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 ba4b3e3327ff30a394d82b65f0499dd2b974853f..5e31740c7e40caf67a655d284f874ff48f27a3e8 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 6b708434b7f94edaec21f06336744899895be537..c69a6f2e6837762cee78476356f3ec18214dbf03 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 124462d65eac43e62b03a4236b4c0ab7da4ef8b6..9411c08a5c7e150af4693ec7158071f0df992e0b 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 712b2a603645f5532897f457e6fe7fb3d2ed5a61..e12105ed38341c28f62a531139c4a148838e7d54 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 79aab0065ec80ae183fccfdd67f2ce2eb776eaa2..14ea197ce37f24c4e0e7bbb1d6a858fbbc0d26de 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 {