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")
Showing the changes to include/linux (6 of 16 files). Show all
Unified · Split
| @@ -325,7 +325,7 @@ struct usb_interface_cache { · 324 unmodified lines | |||
| 325 | 325 | ||
| 326 | /* variable-length array of alternate settings for this interface, | 326 | /* variable-length array of alternate settings for this interface, |
| 327 | * stored in no particular order */ | 327 | * stored in no particular order */ |
| 328 | struct usb_host_interface altsetting[0]; | 328 | struct usb_host_interface altsetting[]; |
| 329 | }; | 329 | }; |
| 330 | #define ref_to_usb_interface_cache(r) \ | 330 | #define ref_to_usb_interface_cache(r) \ |
| 331 | container_of(r, struct usb_interface_cache, ref) | 331 | container_of(r, struct usb_interface_cache, ref) |
| @@ -1589,7 +1589,7 @@ struct urb { · 1257 unmodified lines | |||
| 1589 | int error_count; /* (return) number of ISO errors */ | 1589 | int error_count; /* (return) number of ISO errors */ |
| 1590 | void *context; /* (in) context for completion */ | 1590 | void *context; /* (in) context for completion */ |
| 1591 | usb_complete_t complete; /* (in) completion routine */ | 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 | /* (in) ISO ONLY */ | 1593 | /* (in) ISO ONLY */ |
| 1594 | }; | 1594 | }; |
| 1595 | 1595 | ||
| @@ -153,7 +153,7 @@ struct uac2_feature_unit_descriptor { · 152 unmodified lines | |||
| 153 | __u8 bSourceID; | 153 | __u8 bSourceID; |
| 154 | /* bmaControls is actually u32, | 154 | /* bmaControls is actually u32, |
| 155 | * but u8 is needed for the hybrid parser */ | 155 | * but u8 is needed for the hybrid parser */ |
| 156 | __u8 bmaControls[0]; /* variable length */ | 156 | __u8 bmaControls[]; /* variable length */ |
| 157 | } __attribute__((packed)); | 157 | } __attribute__((packed)); |
| 158 | 158 | ||
| 159 | /* 4.9.2 Class-Specific AS Interface Descriptor */ | 159 | /* 4.9.2 Class-Specific AS Interface Descriptor */ |
| @@ -109,7 +109,7 @@ struct uac3_feature_unit_descriptor { · 108 unmodified lines | |||
| 109 | __u8 bSourceID; | 109 | __u8 bSourceID; |
| 110 | /* bmaControls is actually u32, | 110 | /* bmaControls is actually u32, |
| 111 | * but u8 is needed for the hybrid parser */ | 111 | * but u8 is needed for the hybrid parser */ |
| 112 | __u8 bmaControls[0]; /* variable length */ | 112 | __u8 bmaControls[]; /* variable length */ |
| 113 | /* wFeatureDescrStr omitted */ | 113 | /* wFeatureDescrStr omitted */ |
| 114 | } __attribute__((packed)); | 114 | } __attribute__((packed)); |
| 115 | 115 | ||
| @@ -767,7 +767,7 @@ struct usb_gadget_strings { · 766 unmodified lines | |||
| 767 | 767 | ||
| 768 | struct usb_gadget_string_container { | 768 | struct usb_gadget_string_container { |
| 769 | struct list_head list; | 769 | struct list_head list; |
| 770 | u8 *stash[0]; | 770 | u8 *stash[]; |
| 771 | }; | 771 | }; |
| 772 | 772 | ||
| 773 | /* put descriptor for string with that id into buf (buflen >= 256) */ | 773 | /* put descriptor for string with that id into buf (buflen >= 256) */ |
| @@ -228,7 +228,7 @@ struct usb_hcd { · 227 unmodified lines | |||
| 228 | /* The HC driver's private data is stored at the end of | 228 | /* The HC driver's private data is stored at the end of |
| 229 | * this structure. | 229 | * this structure. |
| 230 | */ | 230 | */ |
| 231 | unsigned long hcd_priv[0] | 231 | unsigned long hcd_priv[] |
| 232 | __attribute__ ((aligned(sizeof(s64)))); | 232 | __attribute__ ((aligned(sizeof(s64)))); |
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| @@ -69,7 +69,7 @@ struct usbdevfs_urb32 { · 68 unmodified lines | |||
| 69 | compat_int_t error_count; | 69 | compat_int_t error_count; |
| 70 | compat_uint_t signr; | 70 | compat_uint_t signr; |
| 71 | compat_caddr_t usercontext; /* unused */ | 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 | struct usbdevfs_ioctl32 { | 75 | struct usbdevfs_ioctl32 { |