Skip to content

Commit

Permalink
USB: Replace zero-length array with flexible-array member
Browse files Browse the repository at this point in the history
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 7649773 ("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>
  • Loading branch information
Gustavo A. R. Silva authored and Greg Kroah-Hartman committed Feb 23, 2020
1 parent 2f41c8a commit 6bc3f39
Show file tree
Hide file tree
Showing 16 changed files with 22 additions and 22 deletions.
2 changes: 1 addition & 1 deletion drivers/usb/atm/usbatm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/dwc2/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/ehci-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ static int tegra_ehci_hub_control(
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)
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/host/ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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[];
};

/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/fotg210.h
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
};

/*
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/host/ohci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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));

};

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/xhci-mtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
};

/*
Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/serial/io_usbvend.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,15 +593,15 @@ 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)
// for 3410 the version is stored in the WATCHPORT_FIRMWARE_VERSION descriptor
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));


Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/serial/ti_usb_3410_5052.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -234,7 +234,7 @@ struct ti_read_data_bytes {
__u8 bCmdCode;
__u8 bModuleId;
__u8 bErrorCode;
__u8 bData[0];
__u8 bData[];
} __packed;

/* Interrupt struct */
Expand Down
4 changes: 2 additions & 2 deletions include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 */
};

Expand Down
2 changes: 1 addition & 1 deletion include/linux/usb/audio-v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion include/linux/usb/audio-v3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
2 changes: 1 addition & 1 deletion include/linux/usb/gadget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand Down
2 changes: 1 addition & 1 deletion include/linux/usb/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))));
};

Expand Down
2 changes: 1 addition & 1 deletion include/linux/usbdevice_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 6bc3f39

Please sign in to comment.