Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: 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 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>

authored by

Gustavo A. R. Silva and committed by
Greg Kroah-Hartman
6bc3f397 2f41c8a2

+22 -22
+1 -1
drivers/usb/atm/usbatm.h
··· 164 164 unsigned char *cell_buf; /* holds partial rx cell */ 165 165 unsigned int buf_usage; 166 166 167 - struct urb *urbs[0]; 167 + struct urb *urbs[]; 168 168 }; 169 169 170 170 static inline void *to_usbatm_driver_data(struct usb_interface *intf)
+1 -1
drivers/usb/dwc2/hcd.h
··· 199 199 u32 flags; 200 200 u16 interval; 201 201 struct dwc2_hcd_pipe_info pipe_info; 202 - struct dwc2_hcd_iso_packet_desc iso_descs[0]; 202 + struct dwc2_hcd_iso_packet_desc iso_descs[]; 203 203 }; 204 204 205 205 /* Phases for control transfers */
+1 -1
drivers/usb/host/ehci-tegra.c
··· 282 282 struct dma_aligned_buffer { 283 283 void *kmalloc_ptr; 284 284 void *old_xfer_buffer; 285 - u8 data[0]; 285 + u8 data[]; 286 286 }; 287 287 288 288 static void free_dma_aligned_buffer(struct urb *urb)
+2 -2
drivers/usb/host/ehci.h
··· 255 255 struct list_head tt_list; 256 256 257 257 /* platform-specific data -- must come last */ 258 - unsigned long priv[0] __aligned(sizeof(s64)); 258 + unsigned long priv[] __aligned(sizeof(s64)); 259 259 }; 260 260 261 261 /* convert between an HCD pointer and the corresponding EHCI_HCD */ ··· 460 460 struct list_head td_list; 461 461 unsigned span; 462 462 unsigned first_packet; 463 - struct ehci_iso_packet packet[0]; 463 + struct ehci_iso_packet packet[]; 464 464 }; 465 465 466 466 /*
+1 -1
drivers/usb/host/fotg210.h
··· 490 490 struct fotg210_iso_sched { 491 491 struct list_head td_list; 492 492 unsigned span; 493 - struct fotg210_iso_packet packet[0]; 493 + struct fotg210_iso_packet packet[]; 494 494 }; 495 495 496 496 /*
+2 -2
drivers/usb/host/ohci.h
··· 337 337 u16 length; // # tds in this request 338 338 u16 td_cnt; // tds already serviced 339 339 struct list_head pending; 340 - struct td *td [0]; // all TDs in this request 340 + struct td *td[]; // all TDs in this request 341 341 342 342 } urb_priv_t; 343 343 ··· 435 435 struct dentry *debug_dir; 436 436 437 437 /* platform-specific data -- must come last */ 438 - unsigned long priv[0] __aligned(sizeof(s64)); 438 + unsigned long priv[] __aligned(sizeof(s64)); 439 439 440 440 }; 441 441
+1 -1
drivers/usb/host/xhci-mtk.h
··· 95 95 u32 pkts; 96 96 u32 cs_count; 97 97 u32 burst_mode; 98 - u32 bw_budget_table[0]; 98 + u32 bw_budget_table[]; 99 99 }; 100 100 101 101 #define MU3C_U3_PORT_MAX 4
+2 -2
drivers/usb/host/xhci.h
··· 1642 1642 struct urb_priv { 1643 1643 int num_tds; 1644 1644 int num_tds_done; 1645 - struct xhci_td td[0]; 1645 + struct xhci_td td[]; 1646 1646 }; 1647 1647 1648 1648 /* ··· 1893 1893 1894 1894 void *dbc; 1895 1895 /* platform-specific data -- must come last */ 1896 - unsigned long priv[0] __aligned(sizeof(s64)); 1896 + unsigned long priv[] __aligned(sizeof(s64)); 1897 1897 }; 1898 1898 1899 1899 /* Platform specific overrides to generic XHCI hc_driver ops */
+2 -2
drivers/usb/serial/io_usbvend.h
··· 593 593 __u8 Type; // Type of descriptor 594 594 __le16 Size; // Size of data only not including header 595 595 __u8 CheckSum; // Checksum (8 bit sum of data only) 596 - __u8 Data[0]; // Data starts here 596 + __u8 Data[]; // Data starts here 597 597 } __attribute__((packed)); 598 598 599 599 // for 5152 devices only (type 2 record) ··· 601 601 struct ti_i2c_firmware_rec { 602 602 __u8 Ver_Major; // Firmware Major version number 603 603 __u8 Ver_Minor; // Firmware Minor version number 604 - __u8 Data[0]; // Download starts here 604 + __u8 Data[]; // Download starts here 605 605 } __attribute__((packed)); 606 606 607 607
+2 -2
drivers/usb/serial/ti_usb_3410_5052.c
··· 219 219 u8 bDataCounter; 220 220 __be16 wBaseAddrHi; 221 221 __be16 wBaseAddrLo; 222 - u8 bData[0]; 222 + u8 bData[]; 223 223 } __packed; 224 224 225 225 struct ti_read_data_request { ··· 234 234 __u8 bCmdCode; 235 235 __u8 bModuleId; 236 236 __u8 bErrorCode; 237 - __u8 bData[0]; 237 + __u8 bData[]; 238 238 } __packed; 239 239 240 240 /* Interrupt struct */
+2 -2
include/linux/usb.h
··· 325 325 326 326 /* variable-length array of alternate settings for this interface, 327 327 * stored in no particular order */ 328 - struct usb_host_interface altsetting[0]; 328 + struct usb_host_interface altsetting[]; 329 329 }; 330 330 #define ref_to_usb_interface_cache(r) \ 331 331 container_of(r, struct usb_interface_cache, ref) ··· 1589 1589 int error_count; /* (return) number of ISO errors */ 1590 1590 void *context; /* (in) context for completion */ 1591 1591 usb_complete_t complete; /* (in) completion routine */ 1592 - struct usb_iso_packet_descriptor iso_frame_desc[0]; 1592 + struct usb_iso_packet_descriptor iso_frame_desc[]; 1593 1593 /* (in) ISO ONLY */ 1594 1594 }; 1595 1595
+1 -1
include/linux/usb/audio-v2.h
··· 153 153 __u8 bSourceID; 154 154 /* bmaControls is actually u32, 155 155 * but u8 is needed for the hybrid parser */ 156 - __u8 bmaControls[0]; /* variable length */ 156 + __u8 bmaControls[]; /* variable length */ 157 157 } __attribute__((packed)); 158 158 159 159 /* 4.9.2 Class-Specific AS Interface Descriptor */
+1 -1
include/linux/usb/audio-v3.h
··· 109 109 __u8 bSourceID; 110 110 /* bmaControls is actually u32, 111 111 * but u8 is needed for the hybrid parser */ 112 - __u8 bmaControls[0]; /* variable length */ 112 + __u8 bmaControls[]; /* variable length */ 113 113 /* wFeatureDescrStr omitted */ 114 114 } __attribute__((packed)); 115 115
+1 -1
include/linux/usb/gadget.h
··· 767 767 768 768 struct usb_gadget_string_container { 769 769 struct list_head list; 770 - u8 *stash[0]; 770 + u8 *stash[]; 771 771 }; 772 772 773 773 /* put descriptor for string with that id into buf (buflen >= 256) */
+1 -1
include/linux/usb/hcd.h
··· 228 228 /* The HC driver's private data is stored at the end of 229 229 * this structure. 230 230 */ 231 - unsigned long hcd_priv[0] 231 + unsigned long hcd_priv[] 232 232 __attribute__ ((aligned(sizeof(s64)))); 233 233 }; 234 234
+1 -1
include/linux/usbdevice_fs.h
··· 69 69 compat_int_t error_count; 70 70 compat_uint_t signr; 71 71 compat_caddr_t usercontext; /* unused */ 72 - struct usbdevfs_iso_packet_desc iso_frame_desc[0]; 72 + struct usbdevfs_iso_packet_desc iso_frame_desc[]; 73 73 }; 74 74 75 75 struct usbdevfs_ioctl32 {