treewide: uapi: Replace zero-length arrays with flexible-array members
Subsystems (55)
PATCH 1/1 treewide: uapi: Replace zero-length arrays with flexible-array members
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf _NPROCESSORS_ONLN) --sp-file script.cocci --include-headers --dir . > output.patch)
@@
identifier S, member, array;
type T1, T2;
@@
struct S {
...
T1 member;
T2 array[
- 0
];
};
-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]
strcpy(de3->name, "."); ^
Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays
---
Hi all!
JFYI: I'm adding this to my -next tree. :)
arch/m68k/include/uapi/asm/bootinfo.h | 4 +- arch/mips/include/uapi/asm/ucontext.h | 2 +- arch/s390/include/uapi/asm/hwctrset.h | 6 +- arch/x86/include/uapi/asm/bootparam.h | 2 +- arch/x86/include/uapi/asm/kvm.h | 12 ++-- include/uapi/drm/i915_drm.h | 6 +- include/uapi/linux/blkzoned.h | 2 +- include/uapi/linux/bpf.h | 2 +- include/uapi/linux/btrfs.h | 10 +-- include/uapi/linux/btrfs_tree.h | 2 +- include/uapi/linux/can/bcm.h | 2 +- include/uapi/linux/connector.h | 2 +- include/uapi/linux/cycx_cfm.h | 2 +- include/uapi/linux/dm-ioctl.h | 8 +-- include/uapi/linux/dm-log-userspace.h | 2 +- include/uapi/linux/ethtool.h | 28 ++++---- include/uapi/linux/fanotify.h | 2 +- include/uapi/linux/fiemap.h | 2 +- include/uapi/linux/firewire-cdev.h | 12 ++-- include/uapi/linux/fs.h | 2 +- include/uapi/linux/if_alg.h | 2 +- include/uapi/linux/if_arcnet.h | 6 +- include/uapi/linux/if_pppox.h | 4 +- include/uapi/linux/if_tun.h | 2 +- include/uapi/linux/igmp.h | 6 +- include/uapi/linux/inet_diag.h | 2 +- include/uapi/linux/inotify.h | 2 +- include/uapi/linux/io_uring.h | 2 +- include/uapi/linux/ip.h | 4 +- include/uapi/linux/ip_vs.h | 4 +- include/uapi/linux/iso_fs.h | 4 +- include/uapi/linux/jffs2.h | 8 +-- include/uapi/linux/kcov.h | 2 +- include/uapi/linux/kvm.h | 8 +-- include/uapi/linux/minix_fs.h | 4 +- include/uapi/linux/mmc/ioctl.h | 2 +- include/uapi/linux/ndctl.h | 10 +-- include/uapi/linux/net_dropmon.h | 4 +- include/uapi/linux/netfilter/x_tables.h | 4 +- include/uapi/linux/netfilter_arp/arp_tables.h | 6 +- .../uapi/linux/netfilter_bridge/ebt_among.h | 2 +- include/uapi/linux/netfilter_ipv4/ip_tables.h | 6 +- .../uapi/linux/netfilter_ipv6/ip6_tables.h | 4 +- include/uapi/linux/perf_event.h | 2 +- include/uapi/linux/pkt_cls.h | 4 +- include/uapi/linux/raid/md_p.h | 2 +- include/uapi/linux/random.h | 2 +- include/uapi/linux/romfs_fs.h | 4 +- include/uapi/linux/rtnetlink.h | 2 +- include/uapi/linux/sctp.h | 10 +-- include/uapi/linux/seg6.h | 2 +- include/uapi/linux/seg6_iptunnel.h | 2 +- include/uapi/linux/stm.h | 2 +- include/uapi/linux/target_core_user.h | 2 +- include/uapi/linux/usb/audio.h | 2 +- include/uapi/linux/usb/cdc.h | 6 +- include/uapi/linux/usb/ch9.h | 2 +- include/uapi/linux/usb/raw_gadget.h | 4 +- include/uapi/linux/usbdevice_fs.h | 4 +- include/uapi/linux/vhost_types.h | 4 +- include/uapi/linux/virtio_9p.h | 2 +- include/uapi/linux/xfrm.h | 10 +-- include/uapi/rdma/hfi/hfi1_user.h | 2 +- include/uapi/rdma/ib_user_verbs.h | 72 +++++++++---------- include/uapi/rdma/rdma_user_cm.h | 2 +- include/uapi/rdma/rdma_user_ioctl_cmds.h | 2 +- include/uapi/scsi/fc/fc_els.h | 18 ++--- include/uapi/scsi/scsi_bsg_fc.h | 2 +- include/uapi/sound/asound.h | 2 +- include/uapi/sound/firewire.h | 6 +- include/uapi/sound/skl-tplg-interface.h | 2 +- include/uapi/sound/sof/header.h | 2 +- include/uapi/sound/usb_stream.h | 2 +- tools/arch/x86/include/uapi/asm/kvm.h | 12 ++-- tools/include/uapi/drm/i915_drm.h | 6 +- tools/include/uapi/linux/bpf.h | 2 +- tools/include/uapi/linux/fs.h | 2 +- tools/include/uapi/linux/if_tun.h | 2 +- tools/include/uapi/linux/kvm.h | 8 +-- tools/include/uapi/linux/perf_event.h | 2 +- tools/include/uapi/linux/pkt_cls.h | 4 +- tools/include/uapi/linux/seg6.h | 4 +- tools/include/uapi/linux/usbdevice_fs.h | 4 +- tools/include/uapi/sound/asound.h | 2 +- 84 files changed, 218 insertions(+), 218 deletions(-)
arch/m68k/include/uapi/asm/bootinfo.h +2 -2
@@ -34,7 +34,7 @@struct bi_record {__be16 tag;/* tag ID */ __be16 size;/* size of record (in bytes) */ -__be32 data[0 ];/* data */ +__be32 data[];/* data */ };
@@ -168,7 +168,7 @@ struct bootversion {struct {__be32 machtype;__be32 version; - } machversions[0]; + } machversions[]; } __packed;#endif /* __ASSEMBLY__ */
arch/mips/include/uapi/asm/ucontext.h +1 -1
@@ -60,7 +60,7 @@ struct ucontext {sigset_t uc_sigmask;/* Extended context structures may follow ucontext */ - unsigned long long uc_extcontext[0]; + unsigned long long uc_extcontext[]; };#endif /* __MIPS_UAPI_ASM_UCONTEXT_H */
arch/s390/include/uapi/asm/hwctrset.h +3 -3
@@ -30,18 +30,18 @@ struct s390_ctrset_start { /* Set CPUs to operate on */struct s390_ctrset_setdata {/* Counter set data */ __u32 set;/* Counter set number */ __u32 no_cnts;/* # of counters stored in cv[] */ -__u64 cv[0 ];/* Counter values (variable length) */ +__u64 cv[];/* Counter values (variable length) */ };struct s390_ctrset_cpudata {/* Counter set data per CPU */ __u32 cpu_nr;/* CPU number */ __u32 no_sets;/* # of counters sets in data[] */ -struct s390_ctrset_setdata data[0 ]; +struct s390_ctrset_setdata data[]; };struct s390_ctrset_read {/* Structure to get all ctr sets */ __u64 no_cpus;/* Total # of CPUs data taken from */ -struct s390_ctrset_cpudata data[0 ]; +struct s390_ctrset_cpudata data[]; };#define S390_HWCTR_MAGIC 'C'/* Random magic # for ioctls */
arch/x86/include/uapi/asm/bootparam.h +1 -1
@@ -52,7 +52,7 @@ struct setup_data {__u64 next;__u32 type;__u32 len; -__u8 data[0 ]; +__u8 data[]; };/* extensible setup indirect data node */
arch/x86/include/uapi/asm/kvm.h +6 -6
@@ -198,13 +198,13 @@ struct kvm_msrs {__u32 nmsrs;/* number of msrs in entries */ __u32 pad; -struct kvm_msr_entry entries[0 ]; +struct kvm_msr_entry entries[]; };/* for KVM_GET_MSR_INDEX_LIST */ struct kvm_msr_list {__u32 nmsrs;/* number of msrs in entries */ -__u32 indices[0 ]; +__u32 indices[]; };/* Maximum size of any access bitmap in bytes */
@@ -241,7 +241,7 @@ struct kvm_cpuid_entry {struct kvm_cpuid {__u32 nent;__u32 padding; -struct kvm_cpuid_entry entries[0 ]; +struct kvm_cpuid_entry entries[]; };struct kvm_cpuid_entry2 {
@@ -263,7 +263,7 @@ struct kvm_cpuid_entry2 {struct kvm_cpuid2 {__u32 nent;__u32 padding; -struct kvm_cpuid_entry2 entries[0 ]; +struct kvm_cpuid_entry2 entries[]; };/* for KVM_GET_PIT and KVM_SET_PIT */
@@ -389,7 +389,7 @@ struct kvm_xsave {* the contents of CPUID leaf 0xD on the host. */ __u32 region[1024 ]; -__u32 extra[0 ]; +__u32 extra[]; };#define KVM_MAX_XCRS 16
@@ -516,7 +516,7 @@ struct kvm_pmu_event_filter {__u32 fixed_counter_bitmap;__u32 flags;__u32 pad[4 ]; -__u64 events[0 ]; +__u64 events[]; };#define KVM_PMU_EVENT_ALLOW 0
include/uapi/drm/i915_drm.h +3 -3
@@ -2123,7 +2123,7 @@ struct i915_context_engines_load_balance {__u64 mbz64;/* reserved for future use; must be zero */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __attribute__((packed));#define I915_DEFINE_CONTEXT_ENGINES_LOAD_BALANCE (name__,N__ ) struct { \
@@ -2161,7 +2161,7 @@ struct i915_context_engines_bond {__u64 flags;/* all undefined flags must be zero */ __u64 mbz64[4 ];/* reserved for future use; must be zero */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __attribute__((packed));#define I915_DEFINE_CONTEXT_ENGINES_BOND (name__,N__ ) struct { \
@@ -2288,7 +2288,7 @@ struct i915_context_engines_parallel_submit {* length = width (i) * num_siblings (j) * index = j + i * num_siblings */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __packed;
include/uapi/linux/blkzoned.h +1 -1
@@ -130,7 +130,7 @@ struct blk_zone_report {__u64 sector;__u32 nr_zones;__u32 flags; -struct blk_zone zones[0 ]; +struct blk_zone zones[]; };/**
include/uapi/linux/bpf.h +1 -1
@@ -79,7 +79,7 @@ struct bpf_insn {/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ struct bpf_lpm_trie_key {__u32 prefixlen;/* up to 32 for AF_INET, 128 for AF_INET6 */ -__u8 data[0 ];/* Arbitrary size */ +__u8 data[];/* Arbitrary size */ };struct bpf_cgroup_storage_key {
include/uapi/linux/btrfs.h +5 -5
@@ -93,7 +93,7 @@ struct btrfs_qgroup_inherit {__u64 num_ref_copies;__u64 num_excl_copies;struct btrfs_qgroup_limit lim; -__u64 qgroups[0 ]; +__u64 qgroups[]; };struct btrfs_ioctl_qgroup_limit_args {
@@ -561,7 +561,7 @@ struct btrfs_ioctl_search_args_v2 {__u64 buf_size;/* in - size of buffer * out - on EOVERFLOW: needed size * to store item */ -__u64 buf[0 ];/* out - found items */ +__u64 buf[];/* out - found items */ };struct btrfs_ioctl_clone_range_args {
@@ -632,7 +632,7 @@ struct btrfs_ioctl_same_args {__u16 dest_count;/* in - total elements in info array */ __u16 reserved1;__u32 reserved2; -struct btrfs_ioctl_same_extent_info info[0 ]; +struct btrfs_ioctl_same_extent_info info[]; };struct btrfs_ioctl_space_info {
@@ -644,7 +644,7 @@ struct btrfs_ioctl_space_info {struct btrfs_ioctl_space_args {__u64 space_slots;__u64 total_spaces; -struct btrfs_ioctl_space_info spaces[0 ]; +struct btrfs_ioctl_space_info spaces[]; };struct btrfs_data_container {
@@ -652,7 +652,7 @@ struct btrfs_data_container {__u32 bytes_missing;/* out -- additional bytes needed for result */ __u32 elem_cnt;/* out */ __u32 elem_missed;/* out */ -__u64 val[0 ];/* out */ +__u64 val[];/* out */ };struct btrfs_ioctl_ino_path_args {
include/uapi/linux/btrfs_tree.h +1 -1
@@ -575,7 +575,7 @@ struct btrfs_inode_extref {__le64 parent_objectid;__le64 index;__le16 name_len; -__u8 name[0 ]; +__u8 name[];/* name goes here */ } __attribute__ ((__packed__));
include/uapi/linux/can/bcm.h +1 -1
@@ -71,7 +71,7 @@ struct bcm_msg_head {struct bcm_timeval ival1, ival2;canid_t can_id;__u32 nframes; -struct can_frame frames[0 ]; +struct can_frame frames[]; };enum {
include/uapi/linux/connector.h +1 -1
@@ -75,7 +75,7 @@ struct cn_msg {__u16 len;/* Length of the following data */ __u16 flags; - __u8 data[0]; + __u8 data[]; };#endif /* _UAPI__CONNECTOR_H */
include/uapi/linux/cycx_cfm.h +1 -1
@@ -91,7 +91,7 @@ struct cycx_firmware {unsigned short reserved[6 ];char descr[CFM_DESCR_LEN ];struct cycx_fw_info info; -unsigned char image[0 ]; +unsigned char image[]; };struct cycx_fw_header {
include/uapi/linux/dm-ioctl.h +4 -4
@@ -182,7 +182,7 @@ struct dm_target_spec {struct dm_target_deps {__u32 count;/* Array size */ __u32 padding;/* unused */ -__u64 dev[0 ];/* out */ +__u64 dev[];/* out */ };/*
@@ -192,7 +192,7 @@ struct dm_name_list {__u64 dev;__u32 next;/* offset to the next record from the _start_ of this */ -char name[0 ]; +char name[];/* * The following members can be accessed by taking a pointer that
@@ -216,7 +216,7 @@ struct dm_target_versions {__u32 next;__u32 version[3 ]; -char name[0 ]; +char name[]; };/*
@@ -225,7 +225,7 @@ struct dm_target_versions {struct dm_target_msg {__u64 sector;/* Device sector */ -char message[0 ]; +char message[]; };/*
include/uapi/linux/dm-log-userspace.h +1 -1
@@ -426,7 +426,7 @@ struct dm_ulog_request {__u32 request_type;/* DM_ULOG_* defined above */ __u32 data_size;/* How much data (not including this struct) */ - char data[0]; + char data[]; };#endif /* __DM_LOG_USERSPACE_H__ */
include/uapi/linux/ethtool.h +14 -14
@@ -257,7 +257,7 @@ struct ethtool_tunable {__u32 id;__u32 type_id;__u32 len; -void *data[0 ]; +void *data[]; };#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
@@ -322,7 +322,7 @@ struct ethtool_regs {__u32 cmd;__u32 version;__u32 len; -__u8 data[0 ]; +__u8 data[]; };/**
@@ -348,7 +348,7 @@ struct ethtool_eeprom {__u32 magic;__u32 offset;__u32 len; -__u8 data[0 ]; +__u8 data[]; };/**
@@ -752,7 +752,7 @@ struct ethtool_gstrings {__u32 cmd;__u32 string_set;__u32 len; -__u8 data[0 ]; +__u8 data[]; };/**
@@ -777,7 +777,7 @@ struct ethtool_sset_info {__u32 cmd;__u32 reserved;__u64 sset_mask; -__u32 data[0 ]; +__u32 data[]; };/**
@@ -817,7 +817,7 @@ struct ethtool_test {__u32 flags;__u32 reserved;__u32 len; -__u64 data[0 ]; +__u64 data[]; };/**
@@ -834,7 +834,7 @@ struct ethtool_test {struct ethtool_stats {__u32 cmd;__u32 n_stats; -__u64 data[0 ]; +__u64 data[]; };/**
@@ -851,7 +851,7 @@ struct ethtool_stats {struct ethtool_perm_addr {__u32 cmd;__u32 size; -__u8 data[0 ]; +__u8 data[]; };/* boolean flags controlling per-interface behavior characteristics.
@@ -1160,7 +1160,7 @@ struct ethtool_rxnfc {struct ethtool_rxfh_indir {__u32 cmd;__u32 size; -__u32 ring_index[0 ]; +__u32 ring_index[]; };/**
@@ -1201,7 +1201,7 @@ struct ethtool_rxfh {__u8 hfunc;__u8 rsvd8[3 ];__u32 rsvd32; -__u32 rss_config[0 ]; +__u32 rss_config[]; };#define ETH_RXFH_CONTEXT_ALLOC 0xffffffff#define ETH_RXFH_INDIR_NO_CHANGE 0xffffffff
@@ -1286,7 +1286,7 @@ struct ethtool_dump {__u32 version;__u32 flag;__u32 len; -__u8 data[0 ]; +__u8 data[]; };#define ETH_FW_DUMP_DISABLE 0
@@ -1318,7 +1318,7 @@ struct ethtool_get_features_block {struct ethtool_gfeatures {__u32 cmd;__u32 size; -struct ethtool_get_features_block features[0 ]; +struct ethtool_get_features_block features[]; };/**
@@ -1340,7 +1340,7 @@ struct ethtool_set_features_block {struct ethtool_sfeatures {__u32 cmd;__u32 size; -struct ethtool_set_features_block features[0 ]; +struct ethtool_set_features_block features[]; };/**
@@ -2087,7 +2087,7 @@ struct ethtool_link_settings {__u8 master_slave_state;__u8 reserved1[1 ];__u32 reserved[7 ]; -__u32 link_mode_masks[0 ]; +__u32 link_mode_masks[];/* layout of link_mode_masks fields: * __u32 map_supported[link_mode_masks_nwords]; * __u32 map_advertising[link_mode_masks_nwords];
include/uapi/linux/fanotify.h +1 -1
@@ -162,7 +162,7 @@ struct fanotify_event_info_fid {* Following is an opaque struct file_handle that can be passed as * an argument to open_by_handle_at(2). */ -unsigned char handle[0 ]; +unsigned char handle[]; };/*
include/uapi/linux/fiemap.h +1 -1
@@ -34,7 +34,7 @@ struct fiemap {__u32 fm_mapped_extents;/* number of extents that were mapped (out) */ __u32 fm_extent_count;/* size of fm_extents array (in) */ __u32 fm_reserved; -struct fiemap_extent fm_extents[0 ];/* array of mapped extents (out) */ +struct fiemap_extent fm_extents[];/* array of mapped extents (out) */ };#define FIEMAP_MAX_OFFSET (~0ULL)
include/uapi/linux/firewire-cdev.h +6 -6
@@ -118,7 +118,7 @@ struct fw_cdev_event_response {__u32 type;__u32 rcode;__u32 length; -__u32 data[0 ]; +__u32 data[]; };/**
@@ -142,7 +142,7 @@ struct fw_cdev_event_request {__u64 offset;__u32 handle;__u32 length; -__u32 data[0 ]; +__u32 data[]; };/**
@@ -205,7 +205,7 @@ struct fw_cdev_event_request2 {__u32 generation;__u32 handle;__u32 length; -__u32 data[0 ]; +__u32 data[]; };/**
@@ -265,7 +265,7 @@ struct fw_cdev_event_iso_interrupt {__u32 type;__u32 cycle;__u32 header_length; -__u32 header[0 ]; +__u32 header[]; };/**
@@ -355,7 +355,7 @@ struct fw_cdev_event_phy_packet {__u32 type;__u32 rcode;__u32 length; -__u32 data[0 ]; +__u32 data[]; };/**
@@ -803,7 +803,7 @@ struct fw_cdev_set_iso_channels {*/ struct fw_cdev_iso_packet {__u32 control; -__u32 header[0 ]; +__u32 header[]; };/**
include/uapi/linux/fs.h +1 -1
@@ -90,7 +90,7 @@ struct file_dedupe_range {__u16 dest_count;/* in - total elements in info array */ __u16 reserved1;/* must be zero */ __u32 reserved2;/* must be zero */ -struct file_dedupe_range_info info[0 ]; +struct file_dedupe_range_info info[]; };/* And dynamically-tunable limits and defaults: */
include/uapi/linux/if_alg.h +1 -1
@@ -42,7 +42,7 @@ struct sockaddr_alg_new {struct af_alg_iv {__u32 ivlen; -__u8 iv[0 ]; +__u8 iv[]; };/* Socket options */
include/uapi/linux/if_arcnet.h +3 -3
@@ -60,7 +60,7 @@ struct arc_rfc1201 {__u8 proto;/* protocol ID field - varies */ __u8 split_flag;/* for use with split packets */ __be16 sequence;/* sequence number */ -__u8 payload[0 ];/* space remaining in packet (504 bytes)*/ +__u8 payload[];/* space remaining in packet (504 bytes)*/ };#define RFC1201_HDR_SIZE 4
@@ -69,7 +69,7 @@ struct arc_rfc1201 {*/ struct arc_rfc1051 {__u8 proto;/* ARC_P_RFC1051_ARP/RFC1051_IP */ -__u8 payload[0 ];/* 507 bytes */ +__u8 payload[];/* 507 bytes */ };#define RFC1051_HDR_SIZE 1
@@ -80,7 +80,7 @@ struct arc_rfc1051 {struct arc_eth_encap {__u8 proto;/* Always ARC_P_ETHER */ struct ethhdr eth;/* standard ethernet header (yuck!) */ -__u8 payload[0 ];/* 493 bytes */ +__u8 payload[];/* 493 bytes */ };#define ETH_ENCAP_HDR_SIZE 14
include/uapi/linux/if_pppox.h +2 -2
@@ -122,7 +122,7 @@ struct sockaddr_pppol2tpv3in6 {struct pppoe_tag {__be16 tag_type;__be16 tag_len; -char tag_data[0 ]; +char tag_data[]; } __attribute__ ((packed));/* Tag identifiers */
@@ -150,7 +150,7 @@ struct pppoe_hdr {__u8 code;__be16 sid;__be16 length; -struct pppoe_tag tag[0 ]; +struct pppoe_tag tag[]; } __packed;/* Length of entire PPPoE + PPP header */
include/uapi/linux/if_tun.h +1 -1
@@ -108,7 +108,7 @@ struct tun_pi {struct tun_filter {__u16 flags;/* TUN_FLT_ flags see above */ __u16 count;/* Number of addresses */ -__u8 addr[0 ][ETH_ALEN ]; +__u8 addr[][ETH_ALEN ]; };#endif /* _UAPI__IF_TUN_H */
include/uapi/linux/igmp.h +3 -3
@@ -48,7 +48,7 @@ struct igmpv3_grec {__u8 grec_auxwords;__be16 grec_nsrcs;__be32 grec_mca; -__be32 grec_src[0 ]; +__be32 grec_src[]; };struct igmpv3_report {
@@ -57,7 +57,7 @@ struct igmpv3_report {__sum16 csum;__be16 resv2;__be16 ngrec; -struct igmpv3_grec grec[0 ]; +struct igmpv3_grec grec[]; };struct igmpv3_query {
@@ -78,7 +78,7 @@ struct igmpv3_query {#endif __u8 qqic;__be16 nsrcs; -__be32 srcs[0 ]; +__be32 srcs[]; };#define IGMP_HOST_MEMBERSHIP_QUERY 0x11/* From RFC1112 */
include/uapi/linux/inet_diag.h +1 -1
@@ -104,7 +104,7 @@ struct inet_diag_hostcond {__u8 family;__u8 prefix_len;int port; -__be32 addr[0 ]; +__be32 addr[]; };struct inet_diag_markcond {
include/uapi/linux/inotify.h +1 -1
@@ -23,7 +23,7 @@ struct inotify_event {__u32 mask;/* watch mask */ __u32 cookie;/* cookie to synchronize two events */ __u32 len;/* length (including nulls) of name */ -char name[0 ];/* stub for possible name */ +char name[];/* stub for possible name */ };/* the following are legal, implemented events that user-space can watch for */
include/uapi/linux/io_uring.h +1 -1
@@ -486,7 +486,7 @@ struct io_uring_probe {__u8 ops_len;/* length of ops[] array below */ __u16 resv;__u32 resv2[3 ]; -struct io_uring_probe_op ops[0 ]; +struct io_uring_probe_op ops[]; };struct io_uring_restriction {
include/uapi/linux/ip.h +2 -2
@@ -112,13 +112,13 @@ struct ip_auth_hdr {__be16 reserved;__be32 spi;__be32 seq_no;/* Sequence number */ -__u8 auth_data[0 ];/* Variable len but >=4. Mind the 64 bit alignment! */ +__u8 auth_data[];/* Variable len but >=4. Mind the 64 bit alignment! */ };struct ip_esp_hdr {__be32 spi;__be32 seq_no;/* Sequence number */ -__u8 enc_data[0 ];/* Variable len but >=8. Mind the 64 bit alignment! */ +__u8 enc_data[];/* Variable len but >=8. Mind the 64 bit alignment! */ };struct ip_comp_hdr {
include/uapi/linux/ip_vs.h +2 -2
@@ -254,7 +254,7 @@ struct ip_vs_get_dests {unsigned int num_dests;/* the real servers */ -struct ip_vs_dest_entry entrytable[0 ]; +struct ip_vs_dest_entry entrytable[]; };
@@ -264,7 +264,7 @@ struct ip_vs_get_services {unsigned int num_services;/* service table */ -struct ip_vs_service_entry entrytable[0 ]; +struct ip_vs_service_entry entrytable[]; };
include/uapi/linux/iso_fs.h +2 -2
@@ -137,7 +137,7 @@ struct iso_path_table{__u8 name_len[2 ];/* 721 */ __u8 extent[4 ];/* 731 */ __u8 parent[2 ];/* 721 */ -char name[0 ]; +char name[]; } __attribute__((packed));/* high sierra is identical to iso, except that the date is only 6 bytes, and
@@ -154,7 +154,7 @@ struct iso_directory_record {__u8 interleave [ISODCL (28 ,28 )];/* 711 */ __u8 volume_sequence_number [ISODCL (29 ,32 )];/* 723 */ __u8 name_len [ISODCL (33 ,33 )];/* 711 */ -char name [0 ]; +char name []; } __attribute__((packed));#define ISOFS_BLOCK_BITS 11
include/uapi/linux/jffs2.h +4 -4
@@ -123,7 +123,7 @@ struct jffs2_raw_dirent__u8 unused[2 ];jint32_t node_crc;jint32_t name_crc; -__u8 name[0 ]; +__u8 name[]; };/* The JFFS2 raw inode structure: Used for storage on physical media. */
@@ -155,7 +155,7 @@ struct jffs2_raw_inodejint16_t flags;/* See JFFS2_INO_FLAG_* */ jint32_t data_crc;/* CRC for the (compressed) data. */ jint32_t node_crc;/* CRC for the raw inode (excluding data) */ -__u8 data[0 ]; +__u8 data[]; };struct jffs2_raw_xattr {
@@ -170,7 +170,7 @@ struct jffs2_raw_xattr {jint16_t value_len;jint32_t data_crc;jint32_t node_crc; -__u8 data[0 ]; +__u8 data[]; } __attribute__((packed));struct jffs2_raw_xref
@@ -196,7 +196,7 @@ struct jffs2_raw_summaryjint32_t padded;/* sum of the size of padding nodes */ jint32_t sum_crc;/* summary information crc */ jint32_t node_crc;/* node crc */ -jint32_t sum[0 ];/* inode summary info */ +jint32_t sum[];/* inode summary info */ };union jffs2_node_union
include/uapi/linux/kcov.h +1 -1
@@ -13,7 +13,7 @@ struct kcov_remote_arg {__u32 area_size;/* Length of coverage buffer in words */ __u32 num_handles;/* Size of handles array */ __aligned_u64 common_handle; -__aligned_u64 handles[0 ]; +__aligned_u64 handles[]; };#define KCOV_REMOTE_MAX_HANDLES 0x100
include/uapi/linux/kvm.h +4 -4
@@ -542,7 +542,7 @@ struct kvm_coalesced_mmio {struct kvm_coalesced_mmio_ring {__u32 first, last; -struct kvm_coalesced_mmio coalesced_mmio[0 ]; +struct kvm_coalesced_mmio coalesced_mmio[]; };#define KVM_COALESCED_MMIO_MAX \
@@ -621,7 +621,7 @@ struct kvm_clear_dirty_log {/* for KVM_SET_SIGNAL_MASK */ struct kvm_signal_mask {__u32 len; -__u8 sigset[0 ]; +__u8 sigset[]; };/* for KVM_TPR_ACCESS_REPORTING */
@@ -1221,7 +1221,7 @@ struct kvm_irq_routing_entry {struct kvm_irq_routing {__u32 nr;__u32 flags; -struct kvm_irq_routing_entry entries[0 ]; +struct kvm_irq_routing_entry entries[]; };#endif
@@ -1341,7 +1341,7 @@ struct kvm_dirty_tlb {struct kvm_reg_list {__u64 n;/* number of regs */ -__u64 reg[0 ]; +__u64 reg[]; };struct kvm_one_reg {
include/uapi/linux/minix_fs.h +2 -2
@@ -97,11 +97,11 @@ struct minix3_super_block {struct minix_dir_entry {__u16 inode; -char name[0 ]; +char name[]; };struct minix3_dir_entry {__u32 inode; -char name[0 ]; +char name[]; };#endif
include/uapi/linux/mmc/ioctl.h +1 -1
@@ -58,7 +58,7 @@ struct mmc_ioc_cmd {*/ struct mmc_ioc_multi_cmd {__u64 num_of_cmds; -struct mmc_ioc_cmd cmds[0 ]; +struct mmc_ioc_cmd cmds[]; };#define MMC_IOC_CMD _IOWR(MMC_BLOCK_MAJOR, 0, struct mmc_ioc_cmd)
include/uapi/linux/ndctl.h +5 -5
@@ -30,25 +30,25 @@ struct nd_cmd_get_config_data_hdr {__u32 in_offset;__u32 in_length;__u32 status; -__u8 out_buf[0 ]; +__u8 out_buf[]; } __packed;struct nd_cmd_set_config_hdr {__u32 in_offset;__u32 in_length; -__u8 in_buf[0 ]; +__u8 in_buf[]; } __packed;struct nd_cmd_vendor_hdr {__u32 opcode;__u32 in_length; -__u8 in_buf[0 ]; +__u8 in_buf[]; } __packed;struct nd_cmd_vendor_tail {__u32 status;__u32 out_length; -__u8 out_buf[0 ]; +__u8 out_buf[]; } __packed;struct nd_cmd_ars_cap {
@@ -86,7 +86,7 @@ struct nd_cmd_ars_status {__u32 reserved;__u64 err_address;__u64 length; - }__packed records[0 ]; + }__packed records[]; } __packed;struct nd_cmd_clear_error {
include/uapi/linux/net_dropmon.h +2 -2
@@ -29,12 +29,12 @@ struct net_dm_config_entry {struct net_dm_config_msg {__u32 entries; -struct net_dm_config_entry options[0 ]; +struct net_dm_config_entry options[]; };struct net_dm_alert_msg {__u32 entries; -struct net_dm_drop_point points[0 ]; +struct net_dm_drop_point points[]; };struct net_dm_user_msg {
include/uapi/linux/netfilter/x_tables.h +2 -2
@@ -28,7 +28,7 @@ struct xt_entry_match {__u16 match_size; } u; -unsigned char data[0 ]; +unsigned char data[]; };struct xt_entry_target {
@@ -119,7 +119,7 @@ struct xt_counters_info {unsigned int num_counters;/* The counters (actually `number' of these). */ -struct xt_counters counters[0 ]; +struct xt_counters counters[]; };#define XT_INV_PROTO 0x40/* Invert the sense of PROTO. */
include/uapi/linux/netfilter_arp/arp_tables.h +3 -3
@@ -109,7 +109,7 @@ struct arpt_entrystruct xt_counters counters;/* The matches (if any), then the target. */ -unsigned char elems[0 ]; +unsigned char elems[]; };/*
@@ -181,7 +181,7 @@ struct arpt_replace {struct xt_counters __user *counters;/* The entries (hang off end: not really an array). */ -struct arpt_entry entries[0 ]; +struct arpt_entry entries[]; };/* The argument to ARPT_SO_GET_ENTRIES. */
@@ -193,7 +193,7 @@ struct arpt_get_entries {unsigned int size;/* The entries. */ -struct arpt_entry entrytable[0 ]; +struct arpt_entry entrytable[]; };/* Helper functions */
include/uapi/linux/netfilter_bridge/ebt_among.h +1 -1
@@ -40,7 +40,7 @@ struct ebt_mac_wormhash_tuple {struct ebt_mac_wormhash {int table[257 ];int poolsize; -struct ebt_mac_wormhash_tuple pool[0 ]; +struct ebt_mac_wormhash_tuple pool[]; };#define ebt_mac_wormhash_size (x) ((x) ? sizeof(struct ebt_mac_wormhash) \
include/uapi/linux/netfilter_ipv4/ip_tables.h +3 -3
@@ -121,7 +121,7 @@ struct ipt_entry {struct xt_counters counters;/* The matches (if any), then the target. */ -unsigned char elems[0 ]; +unsigned char elems[]; };/*
@@ -203,7 +203,7 @@ struct ipt_replace {struct xt_counters __user *counters;/* The entries (hang off end: not really an array). */ -struct ipt_entry entries[0 ]; +struct ipt_entry entries[]; };/* The argument to IPT_SO_GET_ENTRIES. */
@@ -215,7 +215,7 @@ struct ipt_get_entries {unsigned int size;/* The entries. */ -struct ipt_entry entrytable[0 ]; +struct ipt_entry entrytable[]; };/* Helper functions */
include/uapi/linux/netfilter_ipv6/ip6_tables.h +2 -2
@@ -243,7 +243,7 @@ struct ip6t_replace {struct xt_counters __user *counters;/* The entries (hang off end: not really an array). */ -struct ip6t_entry entries[0 ]; +struct ip6t_entry entries[]; };/* The argument to IP6T_SO_GET_ENTRIES. */
@@ -255,7 +255,7 @@ struct ip6t_get_entries {unsigned int size;/* The entries. */ -struct ip6t_entry entrytable[0 ]; +struct ip6t_entry entrytable[]; };/* Helper functions */
include/uapi/linux/perf_event.h +1 -1
@@ -491,7 +491,7 @@ struct perf_event_query_bpf {/* * User provided buffer to store program ids */ -__u32 ids[0 ]; +__u32 ids[]; };/*
include/uapi/linux/pkt_cls.h +2 -2
@@ -256,7 +256,7 @@ struct tc_u32_sel {short hoff;__be32 hmask; -struct tc_u32_key keys[0 ]; +struct tc_u32_key keys[]; };struct tc_u32_mark {
@@ -268,7 +268,7 @@ struct tc_u32_mark {struct tc_u32_pcnt {__u64 rcnt;__u64 rhit; -__u64 kcnts[0 ]; +__u64 kcnts[]; };/* Flags */
include/uapi/linux/raid/md_p.h +1 -1
@@ -303,7 +303,7 @@ struct mdp_superblock_1 {* into the 'roles' value. If a device is spare or faulty, then it doesn't * have a meaningful role. */ -__le16 dev_roles[0 ];/* role in array, or 0xffff for a spare, or 0xfffe for faulty */ +__le16 dev_roles[];/* role in array, or 0xffff for a spare, or 0xfffe for faulty */ };/* feature_map bits */
include/uapi/linux/random.h +1 -1
@@ -41,7 +41,7 @@struct rand_pool_info {int entropy_count;int buf_size; -__u32 buf[0 ]; +__u32 buf[]; };/*
include/uapi/linux/romfs_fs.h +2 -2
@@ -27,7 +27,7 @@ struct romfs_super_block {__be32 word1;__be32 size;__be32 checksum; -char name[0 ];/* volume name */ +char name[];/* volume name */ };/* On disk inode */
@@ -37,7 +37,7 @@ struct romfs_inode {__be32 spec;__be32 size;__be32 checksum; -char name[0 ]; +char name[]; };#define ROMFH_TYPE 7
include/uapi/linux/rtnetlink.h +1 -1
@@ -440,7 +440,7 @@ struct rtnexthop {/* RTA_VIA */ struct rtvia {__kernel_sa_family_t rtvia_family; -__u8 rtvia_addr[0 ]; +__u8 rtvia_addr[]; };/* RTM_CACHEINFO */
include/uapi/linux/sctp.h +5 -5
@@ -365,7 +365,7 @@ struct sctp_assoc_change {__u16 sac_outbound_streams;__u16 sac_inbound_streams;sctp_assoc_t sac_assoc_id; -__u8 sac_info[0 ]; +__u8 sac_info[]; };/*
@@ -436,7 +436,7 @@ struct sctp_remote_error {__u32 sre_length;__be16 sre_error;sctp_assoc_t sre_assoc_id; -__u8 sre_data[0 ]; +__u8 sre_data[]; };
@@ -453,7 +453,7 @@ struct sctp_send_failed {__u32 ssf_error;struct sctp_sndrcvinfo ssf_info;sctp_assoc_t ssf_assoc_id; -__u8 ssf_data[0 ]; +__u8 ssf_data[]; };struct sctp_send_failed_event {
@@ -463,7 +463,7 @@ struct sctp_send_failed_event {__u32 ssf_error;struct sctp_sndinfo ssfe_info;sctp_assoc_t ssf_assoc_id; -__u8 ssf_data[0 ]; +__u8 ssf_data[]; };/*
@@ -1029,7 +1029,7 @@ struct sctp_getaddrs_old {struct sctp_getaddrs {sctp_assoc_t assoc_id;/*input*/ __u32 addr_num;/*output*/ -__u8 addrs[0 ];/*output, variable size*/ +__u8 addrs[];/*output, variable size*/ };/* A socket user request obtained via SCTP_GET_ASSOC_STATS that retrieves
include/uapi/linux/seg6.h +1 -1
@@ -30,7 +30,7 @@ struct ipv6_sr_hdr {__u8 flags;__u16 tag; -struct in6_addr segments[0 ]; +struct in6_addr segments[]; };#define SR6_FLAG1_PROTECTED (1 << 6)
include/uapi/linux/seg6_iptunnel.h +1 -1
@@ -26,7 +26,7 @@ enum {struct seg6_iptunnel_encap {int mode; -struct ipv6_sr_hdr srh[0 ]; +struct ipv6_sr_hdr srh[]; };#define SEG6_IPTUN_ENCAP_SIZE (x) ((sizeof(*x)) + (((x)->srh->hdrlen + 1) << 3))
include/uapi/linux/stm.h +1 -1
@@ -36,7 +36,7 @@ struct stp_policy_id {/* padding */ __u16 __reserved_0;__u32 __reserved_1; -char id[0 ]; +char id[]; };#define STP_POLICY_ID_SET _IOWR('%', 0, struct stp_policy_id)
include/uapi/linux/target_core_user.h +1 -1
@@ -152,7 +152,7 @@ struct tcmu_tmr_entry {__u32 cmd_cnt;__u64 __pad3;__u64 __pad4; -__u16 cmd_ids[0 ]; +__u16 cmd_ids[]; } __packed;#define TCMU_OP_ALIGN_SIZE sizeof(__u64)
include/uapi/linux/usb/audio.h +1 -1
@@ -341,7 +341,7 @@ struct uac_feature_unit_descriptor {__u8 bUnitID;__u8 bSourceID;__u8 bControlSize; -__u8 bmaControls[0 ];/* variable length */ +__u8 bmaControls[];/* variable length */ } __attribute__((packed));static inline __u8 uac_feature_unit_iFeature (struct uac_feature_unit_descriptor *desc)
include/uapi/linux/usb/cdc.h +3 -3
@@ -171,7 +171,7 @@ struct usb_cdc_mdlm_detail_desc {/* type is associated with mdlm_desc.bGUID */ __u8 bGuidDescriptorType; -__u8 bDetailData[0 ]; +__u8 bDetailData[]; } __attribute__ ((packed));/* "OBEX Control Model Functional Descriptor" */
@@ -379,7 +379,7 @@ struct usb_cdc_ncm_ndp16 {__le32 dwSignature;__le16 wLength;__le16 wNextNdpIndex; -struct usb_cdc_ncm_dpe16 dpe16[0 ]; +struct usb_cdc_ncm_dpe16 dpe16[]; } __attribute__ ((packed));/* 32-bit NCM Datagram Pointer Entry */
@@ -395,7 +395,7 @@ struct usb_cdc_ncm_ndp32 {__le16 wReserved6;__le32 dwNextNdpIndex;__le32 dwReserved12; -struct usb_cdc_ncm_dpe32 dpe32[0 ]; +struct usb_cdc_ncm_dpe32 dpe32[]; } __attribute__ ((packed));/* CDC NCM subclass 3.2.1 and 3.2.2 */
include/uapi/linux/usb/ch9.h +1 -1
@@ -818,7 +818,7 @@ struct usb_key_descriptor {__u8 tTKID[3 ];__u8 bReserved; -__u8 bKeyData[0 ]; +__u8 bKeyData[]; } __attribute__((packed));/*-------------------------------------------------------------------------*/
include/uapi/linux/usb/raw_gadget.h +2 -2
@@ -60,7 +60,7 @@ enum usb_raw_event_type {struct usb_raw_event {__u32 type;__u32 length; -__u8 data[0 ]; +__u8 data[]; };#define USB_RAW_IO_FLAGS_ZERO 0x0001
@@ -90,7 +90,7 @@ struct usb_raw_ep_io {__u16 ep;__u16 flags;__u32 length; -__u8 data[0 ]; +__u8 data[]; };/* Maximum number of non-control endpoints in struct usb_raw_eps_info. */
include/uapi/linux/usbdevice_fs.h +2 -2
@@ -131,7 +131,7 @@ struct usbdevfs_urb {unsigned int signr;/* signal to be sent on completion, or 0 if none should be sent. */ void __user *usercontext; -struct usbdevfs_iso_packet_desc iso_frame_desc[0 ]; +struct usbdevfs_iso_packet_desc iso_frame_desc[]; };/* ioctls for talking directly to drivers */
@@ -176,7 +176,7 @@ struct usbdevfs_disconnect_claim {struct usbdevfs_streams {unsigned int num_streams;/* Not used by USBDEVFS_FREE_STREAMS */ unsigned int num_eps; -unsigned char eps[0 ]; +unsigned char eps[]; };/*
include/uapi/linux/vhost_types.h +2 -2
@@ -107,7 +107,7 @@ struct vhost_memory_region {struct vhost_memory {__u32 nregions;__u32 padding; -struct vhost_memory_region regions[0 ]; +struct vhost_memory_region regions[]; };/* VHOST_SCSI specific definitions */
@@ -135,7 +135,7 @@ struct vhost_scsi_target {struct vhost_vdpa_config {__u32 off;__u32 len; -__u8 buf[0 ]; +__u8 buf[]; };/* vhost vdpa IOVA range
include/uapi/linux/virtio_9p.h +1 -1
@@ -38,7 +38,7 @@ struct virtio_9p_config {/* length of the tag name */ __virtio16 tag_len;/* non-NULL terminated tag name */ -__u8 tag[0 ]; +__u8 tag[]; } __attribute__((packed));#endif /* _LINUX_VIRTIO_9P_H */
include/uapi/linux/xfrm.h +5 -5
@@ -33,7 +33,7 @@ struct xfrm_sec_ctx {__u8 ctx_alg;__u16 ctx_len;__u32 ctx_sid; -char ctx_str[0 ]; +char ctx_str[]; };/* Security Context Domains of Interpretation */
@@ -96,27 +96,27 @@ struct xfrm_replay_state_esn {__u32 oseq_hi;__u32 seq_hi;__u32 replay_window; -__u32 bmp[0 ]; +__u32 bmp[]; };struct xfrm_algo {char alg_name[64 ];unsigned int alg_key_len;/* in bits */ -char alg_key[0 ]; +char alg_key[]; };struct xfrm_algo_auth {char alg_name[64 ];unsigned int alg_key_len;/* in bits */ unsigned int alg_trunc_len;/* in bits */ -char alg_key[0 ]; +char alg_key[]; };struct xfrm_algo_aead {char alg_name[64 ];unsigned int alg_key_len;/* in bits */ unsigned int alg_icv_len;/* in bits */ -char alg_key[0 ]; +char alg_key[]; };struct xfrm_stats {
include/uapi/rdma/hfi/hfi1_user.h +1 -1
@@ -180,7 +180,7 @@ struct hfi1_sdma_comp_entry {struct hfi1_status {__aligned_u64 dev;/* device/hw status bits */ __aligned_u64 port;/* port state and status bits */ -char freezemsg[0 ]; +char freezemsg[]; };enum sdma_req_opcode {
include/uapi/rdma/ib_user_verbs.h +36 -36
276 lines not on this page · raw message
include/uapi/rdma/rdma_user_cm.h +1 -1
@@ -184,7 +184,7 @@ struct rdma_ucm_query_addr_resp {struct rdma_ucm_query_path_resp {__u32 num_paths;__u32 reserved; -struct ib_path_rec_data path_data[0 ]; +struct ib_path_rec_data path_data[]; };struct rdma_ucm_conn_param {
include/uapi/rdma/rdma_user_ioctl_cmds.h +1 -1
@@ -81,7 +81,7 @@ struct ib_uverbs_ioctl_hdr {__aligned_u64 reserved1;__u32 driver_id;__u32 reserved2; - struct ib_uverbs_attr attrs[0]; + struct ib_uverbs_attr attrs[]; };#endif
include/uapi/scsi/fc/fc_els.h +9 -9
@@ -264,7 +264,7 @@ struct fc_tlv_desc {* Size of descriptor excluding * desc_tag and desc_len fields. */ -__u8 desc_value[0 ];/* Descriptor Value */ +__u8 desc_value[];/* Descriptor Value */ };/* Descriptor tag and len fields are considered the mandatory header
@@ -1027,7 +1027,7 @@ struct fc_fn_li_desc {* threshold to caause the LI event */ __be32 pname_count;/* number of portname_list elements */ -__be64 pname_list[0 ];/* list of N_Port_Names accessible +__be64 pname_list[];/* list of N_Port_Names accessible * through the attached port */ };
@@ -1069,7 +1069,7 @@ struct fc_fn_peer_congn_desc {* congestion event */ __be32 pname_count;/* number of portname_list elements */ -__be64 pname_list[0 ];/* list of N_Port_Names accessible +__be64 pname_list[];/* list of N_Port_Names accessible * through the attached port */ };
@@ -1104,7 +1104,7 @@ struct fc_els_fpin {* Size of ELS excluding fpin_cmd, * fpin_zero and desc_len fields. */ -struct fc_tlv_desc fpin_desc[0 ];/* Descriptor list */ +struct fc_tlv_desc fpin_desc[];/* Descriptor list */ };/* Diagnostic Function Descriptor - FPIN Registration */
@@ -1115,7 +1115,7 @@ struct fc_df_desc_fpin_reg {* desc_tag and desc_len fields. */ __be32 count;/* Number of desc_tags elements */ -__be32 desc_tags[0 ];/* Array of Descriptor Tags. +__be32 desc_tags[];/* Array of Descriptor Tags. * Each tag indicates a function * supported by the N_Port (request) * or by the N_Port and Fabric
@@ -1135,7 +1135,7 @@ struct fc_els_rdf {* Size of ELS excluding fpin_cmd, * fpin_zero and desc_len fields. */ -struct fc_tlv_desc desc[0 ];/* Descriptor list */ +struct fc_tlv_desc desc[];/* Descriptor list */ };/*
@@ -1148,7 +1148,7 @@ struct fc_els_rdf_resp {* and desc_list_len fields. */ struct fc_els_lsri_desc lsri; -struct fc_tlv_desc desc[0 ];/* Supported Descriptor list */ +struct fc_tlv_desc desc[];/* Supported Descriptor list */ };
@@ -1231,7 +1231,7 @@ struct fc_els_edc {* Size of ELS excluding edc_cmd, * edc_zero and desc_len fields. */ -struct fc_tlv_desc desc[0 ]; +struct fc_tlv_desc desc[];/* Diagnostic Descriptor list */ };
@@ -1245,7 +1245,7 @@ struct fc_els_edc_resp {* and desc_list_len fields. */ struct fc_els_lsri_desc lsri; -struct fc_tlv_desc desc[0 ]; +struct fc_tlv_desc desc[];/* Supported Diagnostic Descriptor list */ };
include/uapi/scsi/scsi_bsg_fc.h +1 -1
@@ -209,7 +209,7 @@ struct fc_bsg_host_vendor {__u64 vendor_id;/* start of vendor command area */ -__u32 vendor_cmd[0 ]; +__u32 vendor_cmd[]; };/* Response:
include/uapi/sound/asound.h +1 -1
@@ -1106,7 +1106,7 @@ struct snd_ctl_elem_value {struct snd_ctl_tlv {unsigned int numid;/* control element numeric identification */ unsigned int length;/* in bytes aligned to 4 */ -unsigned int tlv[0 ];/* first TLV */ +unsigned int tlv[];/* first TLV */ };#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
include/uapi/sound/firewire.h +3 -3
@@ -38,11 +38,11 @@ struct snd_efw_transaction {__be32 category;__be32 command;__be32 status; -__be32 params[0 ]; +__be32 params[]; };struct snd_firewire_event_efw_response {unsigned int type; -__be32 response[0 ];/* some responses */ +__be32 response[];/* some responses */ };struct snd_firewire_event_digi00x_message {
@@ -63,7 +63,7 @@ struct snd_firewire_tascam_change {struct snd_firewire_event_tascam_control {unsigned int type; -struct snd_firewire_tascam_change changes[0 ]; +struct snd_firewire_tascam_change changes[]; };struct snd_firewire_event_motu_register_dsp_change {
include/uapi/sound/skl-tplg-interface.h +1 -1
@@ -151,7 +151,7 @@ struct skl_dfw_algo_data { __u32 rsvd:30;__u32 param_id;__u32 max; -char params[0 ]; +char params[]; } __packed;enum skl_tkn_dir {
include/uapi/sound/sof/header.h +1 -1
@@ -23,7 +23,7 @@ struct sof_abi_hdr {__u32 size;/**< size in bytes of data excl. this struct */ __u32 abi;/**< SOF ABI version */ __u32 reserved[4 ];/**< reserved for future use */ - __u32 data[0]; /**< Component data - opaque to core */ + __u32 data[]; /**< Component data - opaque to core */ } __packed;#endif
include/uapi/sound/usb_stream.h +1 -1
@@ -61,7 +61,7 @@ struct usb_stream {unsigned inpacket_split_at;unsigned next_inpacket_split;unsigned next_inpacket_split_at; -struct usb_stream_packet inpacket[0 ]; +struct usb_stream_packet inpacket[]; };enum usb_stream_state {
tools/arch/x86/include/uapi/asm/kvm.h +6 -6
@@ -198,13 +198,13 @@ struct kvm_msrs {__u32 nmsrs;/* number of msrs in entries */ __u32 pad; -struct kvm_msr_entry entries[0 ]; +struct kvm_msr_entry entries[]; };/* for KVM_GET_MSR_INDEX_LIST */ struct kvm_msr_list {__u32 nmsrs;/* number of msrs in entries */ -__u32 indices[0 ]; +__u32 indices[]; };/* Maximum size of any access bitmap in bytes */
@@ -241,7 +241,7 @@ struct kvm_cpuid_entry {struct kvm_cpuid {__u32 nent;__u32 padding; -struct kvm_cpuid_entry entries[0 ]; +struct kvm_cpuid_entry entries[]; };struct kvm_cpuid_entry2 {
@@ -263,7 +263,7 @@ struct kvm_cpuid_entry2 {struct kvm_cpuid2 {__u32 nent;__u32 padding; -struct kvm_cpuid_entry2 entries[0 ]; +struct kvm_cpuid_entry2 entries[]; };/* for KVM_GET_PIT and KVM_SET_PIT */
@@ -389,7 +389,7 @@ struct kvm_xsave {* the contents of CPUID leaf 0xD on the host. */ __u32 region[1024 ]; -__u32 extra[0 ]; +__u32 extra[]; };#define KVM_MAX_XCRS 16
@@ -515,7 +515,7 @@ struct kvm_pmu_event_filter {__u32 fixed_counter_bitmap;__u32 flags;__u32 pad[4 ]; -__u64 events[0 ]; +__u64 events[]; };#define KVM_PMU_EVENT_ALLOW 0
tools/include/uapi/drm/i915_drm.h +3 -3
@@ -2060,7 +2060,7 @@ struct i915_context_engines_load_balance {__u64 mbz64;/* reserved for future use; must be zero */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __attribute__((packed));#define I915_DEFINE_CONTEXT_ENGINES_LOAD_BALANCE (name__,N__ ) struct { \
@@ -2098,7 +2098,7 @@ struct i915_context_engines_bond {__u64 flags;/* all undefined flags must be zero */ __u64 mbz64[4 ];/* reserved for future use; must be zero */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __attribute__((packed));#define I915_DEFINE_CONTEXT_ENGINES_BOND (name__,N__ ) struct { \
@@ -2225,7 +2225,7 @@ struct i915_context_engines_parallel_submit {* length = width (i) * num_siblings (j) * index = j + i * num_siblings */ -struct i915_engine_class_instance engines[0 ]; +struct i915_engine_class_instance engines[]; } __packed;
tools/include/uapi/linux/bpf.h +1 -1
@@ -79,7 +79,7 @@ struct bpf_insn {/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ struct bpf_lpm_trie_key {__u32 prefixlen;/* up to 32 for AF_INET, 128 for AF_INET6 */ -__u8 data[0 ];/* Arbitrary size */ +__u8 data[];/* Arbitrary size */ };struct bpf_cgroup_storage_key {
tools/include/uapi/linux/fs.h +1 -1
@@ -90,7 +90,7 @@ struct file_dedupe_range {__u16 dest_count;/* in - total elements in info array */ __u16 reserved1;/* must be zero */ __u32 reserved2;/* must be zero */ -struct file_dedupe_range_info info[0 ]; +struct file_dedupe_range_info info[]; };/* And dynamically-tunable limits and defaults: */
tools/include/uapi/linux/if_tun.h +1 -1
@@ -108,7 +108,7 @@ struct tun_pi {struct tun_filter {__u16 flags;/* TUN_FLT_ flags see above */ __u16 count;/* Number of addresses */ -__u8 addr[0 ][ETH_ALEN ]; +__u8 addr[][ETH_ALEN ]; };#endif /* _UAPI__IF_TUN_H */
tools/include/uapi/linux/kvm.h +4 -4
@@ -539,7 +539,7 @@ struct kvm_coalesced_mmio {struct kvm_coalesced_mmio_ring {__u32 first, last; -struct kvm_coalesced_mmio coalesced_mmio[0 ]; +struct kvm_coalesced_mmio coalesced_mmio[]; };#define KVM_COALESCED_MMIO_MAX \
@@ -618,7 +618,7 @@ struct kvm_clear_dirty_log {/* for KVM_SET_SIGNAL_MASK */ struct kvm_signal_mask {__u32 len; -__u8 sigset[0 ]; +__u8 sigset[]; };/* for KVM_TPR_ACCESS_REPORTING */
@@ -1216,7 +1216,7 @@ struct kvm_irq_routing_entry {struct kvm_irq_routing {__u32 nr;__u32 flags; -struct kvm_irq_routing_entry entries[0 ]; +struct kvm_irq_routing_entry entries[]; };#endif
@@ -1335,7 +1335,7 @@ struct kvm_dirty_tlb {struct kvm_reg_list {__u64 n;/* number of regs */ -__u64 reg[0 ]; +__u64 reg[]; };struct kvm_one_reg {
tools/include/uapi/linux/perf_event.h +1 -1
@@ -491,7 +491,7 @@ struct perf_event_query_bpf {/* * User provided buffer to store program ids */ -__u32 ids[0 ]; +__u32 ids[]; };/*
tools/include/uapi/linux/pkt_cls.h +2 -2
@@ -180,7 +180,7 @@ struct tc_u32_sel {short hoff;__be32 hmask; -struct tc_u32_key keys[0 ]; +struct tc_u32_key keys[]; };struct tc_u32_mark {
@@ -192,7 +192,7 @@ struct tc_u32_mark {struct tc_u32_pcnt {__u64 rcnt;__u64 rhit; -__u64 kcnts[0 ]; +__u64 kcnts[]; };/* Flags */
tools/include/uapi/linux/seg6.h +2 -2
@@ -30,7 +30,7 @@ struct ipv6_sr_hdr {__u8 flags;__u16 tag; -struct in6_addr segments[0 ]; +struct in6_addr segments[]; };#define SR6_FLAG1_PROTECTED (1 << 6)
@@ -49,7 +49,7 @@ struct ipv6_sr_hdr {struct sr6_tlv {__u8 type;__u8 len; -__u8 data[0 ]; +__u8 data[]; };#endif
tools/include/uapi/linux/usbdevice_fs.h +2 -2
@@ -131,7 +131,7 @@ struct usbdevfs_urb {unsigned int signr;/* signal to be sent on completion, or 0 if none should be sent. */ void __user *usercontext; -struct usbdevfs_iso_packet_desc iso_frame_desc[0 ]; +struct usbdevfs_iso_packet_desc iso_frame_desc[]; };/* ioctls for talking directly to drivers */
@@ -176,7 +176,7 @@ struct usbdevfs_disconnect_claim {struct usbdevfs_streams {unsigned int num_streams;/* Not used by USBDEVFS_FREE_STREAMS */ unsigned int num_eps; -unsigned char eps[0 ]; +unsigned char eps[]; };/*
tools/include/uapi/sound/asound.h +1 -1
@@ -1106,7 +1106,7 @@ struct snd_ctl_elem_value {struct snd_ctl_tlv {unsigned int numid;/* control element numeric identification */ unsigned int length;/* in bytes aligned to 4 */ -unsigned int tlv[0 ];/* first TLV */ +unsigned int tlv[];/* first TLV */ };#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
Signature · 1 line
2.27.0
Daniel Borkmann
maintainerQuoted 36 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S { ... T1 member; T2 array[- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays
Quoted 7 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!JFYI: I'm adding this to my -next tree. :)
Fyi, this breaks BPF CI:
https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'struct bpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
struct bpf_lpm_trie_key trie_key;
^ 1 error generated.
make: *** [Makefile:519: /tmp/runner/work/bpf/bpf/tools/testing/selftests/bpf/map_ptr_kern.o] Error 1
make: *** Waiting for unfinished jobs....
Error: Process completed with exit code 2.
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Quoted 43 lines · Daniel Borkmann
Quoted 42 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S { ... T1 member; T2 array[- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arraysSigned-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!
Quoted 3 lines
Quoted 1 line
JFYI: I'm adding this to my -next tree. :)
Fyi, this breaks BPF CI:
Thanks for the report! It seems the 0-day robot didn't catch that one. I'll fix it up right away. :)
--
Gustavo
Quoted 11 lines
https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'structbpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]struct bpf_lpm_trie_key trie_key; ^1 error generated.
make: *** [Makefile:519:/tmp/runner/work/bpf/bpf/tools/testing/selftests/bpf/map_ptr_kern.o] Error 1
make: *** Waiting for unfinished jobs....
Error: Process completed with exit code 2.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 45 lines · Daniel Borkmann
Quoted 36 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S { ... T1 member; T2 array[- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arraysQuoted 7 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!JFYI: I'm adding this to my -next tree. :)
Quoted 8 lines
Fyi, this breaks BPF CI:
https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'structbpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]struct bpf_lpm_trie_key trie_key; ^
This will break the rdma-core userspace as well, with a similar error:
/usr/bin/clang-13 -DVERBS_DEBUG -Dibverbs_EXPORTS -Iinclude -I/usr/include/libnl3 -I/usr/include/drm -g -O2 -fdebug-prefix-map=/__w/1/s=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wmissing-prototypes -Wmissing-declarations -Wwrite-strings -Wformat=2 -Wcast-function-type -Wformat-nonliteral -Wdate-time -Wnested-externs -Wshadow -Wstrict-prototypes -Wold-style-definition -Werror -Wredundant-decls -g -fPIC -std=gnu11 -MD -MT libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o -MF libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o.d -o libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o -c ../libibverbs/cmd_flow.c
In file included from ../libibverbs/cmd_flow.c:33:
In file included from include/infiniband/cmd_write.h:36:
In file included from include/infiniband/cmd_ioctl.h:41:
In file included from include/infiniband/verbs.h:48:
In file included from include/infiniband/verbs_api.h:66:
In file included from include/infiniband/ib_user_ioctl_verbs.h:38:include/rdma/ib_user_verbs.h:436:34: error: field 'base' with variable sized type 'struct ib_uverbs_create_cq_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
struct ib_uverbs_create_cq_resp base;
^
include/rdma/ib_user_verbs.h:644:34: error: field 'base' with variable sized type 'struct ib_uverbs_create_qp_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
struct ib_uverbs_create_qp_resp base;Which is why I gave up trying to change these..
Though maybe we could just switch off -Wgnu-variable-sized-type-not-at-end during configuration ?
Jason
Quoted 66 lines · Jason Gunthorpe
Quoted 45 lines · Daniel Borkmann
Quoted 36 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S { ... T1 member; T2 array[- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arraysQuoted 7 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!JFYI: I'm adding this to my -next tree. :)
Quoted 8 lines
Fyi, this breaks BPF CI:
https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'structbpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]struct bpf_lpm_trie_key trie_key; ^This will break the rdma-core userspace as well, with a similar error:
/usr/bin/clang-13-DVERBS_DEBUG -Dibverbs_EXPORTS -Iinclude -I/usr/include/libnl3 -I/usr/include/drm -g -O2 -fdebug-prefix-map=/__w/1/s=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wmissing-prototypes -Wmissing-declarations -Wwrite-strings -Wformat=2 -Wcast-function-type -Wformat-nonliteral -Wdate-time -Wnested-externs -Wshadow -Wstrict-prototypes -Wold-style-definition -Werror -Wredundant-decls -g -fPIC -std=gnu11 -MD -MTlibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-MF libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o.d -olibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-c../libibverbs/cmd_flow.c
In file included from../libibverbs/cmd_flow.c:33:
In file included frominclude/infiniband/cmd_write.h:36:
In file included frominclude/infiniband/cmd_ioctl.h:41:
In file included frominclude/infiniband/verbs.h:48:
In file included frominclude/infiniband/verbs_api.h:66:
In file included frominclude/infiniband/ib_user_ioctl_verbs.h:38:include/rdma/ib_user_verbs.h:436:34: error: field 'base' with variable sized type 'structib_uverbs_create_cq_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
Quoted 8 lines
struct ib_uverbs_create_cq_resp base; ^ include/rdma/ib_user_verbs.h:644:34: error: field 'base' with variable sized type 'struct ib_uverbs_create_qp_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] struct ib_uverbs_create_qp_resp base;Which is why I gave up trying to change these..
Though maybe we could just switch off -Wgnu-variable-sized-type-not-at-end during configuration ?
No. I think now we can easily workaround these sorts of problems with something like this:
struct flex {
any_type any_member;
union {
type array[0];
__DECLARE_FLEX_ARRAY(type, array_flex);
};
};and use array_flex in kernel-space.
The same for the one-elment arrays in UAPI:
struct flex {
any_type any_member;
union {
type array[1];
__DECLARE_FLEX_ARRAY(type, array_flex);
};
};I'll use the idiom above to resolve all these warnings in a follow-up patch. :)
Thanks
Quoted 79 lines · Gustavo A. R. Silva
Quoted 66 lines · Jason Gunthorpe
Quoted 45 lines · Daniel Borkmann
Quoted 36 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S { ... T1 member; T2 array[- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arraysQuoted 7 lines
Signed-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!JFYI: I'm adding this to my -next tree. :)
Quoted 8 lines
Fyi, this breaks BPF CI:
https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'structbpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]struct bpf_lpm_trie_key trie_key; ^This will break the rdma-core userspace as well, with a similar error:
/usr/bin/clang-13-DVERBS_DEBUG -Dibverbs_EXPORTS -Iinclude -I/usr/include/libnl3 -I/usr/include/drm -g -O2 -fdebug-prefix-map=/__w/1/s=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wmissing-prototypes -Wmissing-declarations -Wwrite-strings -Wformat=2 -Wcast-function-type -Wformat-nonliteral -Wdate-time -Wnested-externs -Wshadow -Wstrict-prototypes -Wold-style-definition -Werror -Wredundant-decls -g -fPIC -std=gnu11 -MD -MTlibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-MF libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o.d -olibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-c../libibverbs/cmd_flow.c
In file included from../libibverbs/cmd_flow.c:33:
In file included frominclude/infiniband/cmd_write.h:36:
In file included frominclude/infiniband/cmd_ioctl.h:41:
In file included frominclude/infiniband/verbs.h:48:
In file included frominclude/infiniband/verbs_api.h:66:
In file included frominclude/infiniband/ib_user_ioctl_verbs.h:38:include/rdma/ib_user_verbs.h:436:34: error: field 'base' with variable sized type 'structib_uverbs_create_cq_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]Quoted 8 lines
struct ib_uverbs_create_cq_resp base; ^ include/rdma/ib_user_verbs.h:644:34: error: field 'base' with variable sized type 'struct ib_uverbs_create_qp_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] struct ib_uverbs_create_qp_resp base;Which is why I gave up trying to change these..
Though maybe we could just switch off -Wgnu-variable-sized-type-not-at-end during configuration ?
No. I think now we can easily workaround these sorts of problems with something like this:
Quoted 7 lines
struct flex {
any_type any_member;
union {
type array[0];
__DECLARE_FLEX_ARRAY(type, array_flex);
};
};Mmmh... nope; this doesn't work[1].
We need to think in a different strategy.
--
Gustavo
Quoted 3 lines · Gustavo A. R. Silva
Quoted 1 line
Quoted 1 line
Though maybe we could just switch off -Wgnu-variable-sized-type-not-at-end during configuration ?
We need to think in a different strategy.
I think we will need to switch off the warning in userspace - this is doable for rdma-core.
On the other hand, if the goal is to enable the array size check compiler warning I would suggest focusing only on those structs that actually hit that warning in the kernel. IIRC infiniband doesn't trigger it because it just pointer casts the flex array to some other struct.
It isn't actually an array it is a placeholder for a trailing structure, so it is never indexed.
This is also why we hit the warning because the convient way for userspace to compose the message is to squash the header and trailer structs together in a super struct on the stack, then invoke the ioctl.
Jason
Quoted 6 lines · Jason Gunthorpe
Quoted 3 lines · Gustavo A. R. Silva
Quoted 1 line
Quoted 1 line
Though maybe we could just switch off -Wgnu-variable-sized-type-not-at-end during configuration ?
We need to think in a different strategy.
Quoted 8 lines
I think we will need to switch off the warning in userspace - this is doable for rdma-core.
On the other hand, if the goal is to enable the array size check compiler warning I would suggest focusing only on those structs that actually hit that warning in the kernel. IIRC infiniband doesn't trigger it because it just pointer casts the flex array to some other struct.
Yep; this is actually why I reverted those changes in rdma (before sending out the patch) when 0-day reported the same problems you pointed out[1].
Also, that's the strategy I'm following right now with the one-element array into flex-array member transformations. I'm addressing those cases in which the trailing array is actually being iterated over, first.
I just added the patch to my -next tree, so it can be build-tested by other people, and let's see what else is reported this week. :)
--
Gustavo
[1] https://lore.kernel.org/lkml/620ca2a5.NkAEIDEfiYoxE9%2Fu%[email protected]/
Quoted 10 lines
It isn't actually an array it is a placeholder for a trailing structure, so it is never indexed.
This is also why we hit the warning because the convient way for userspace to compose the message is to squash the header and trailer structs together in a super struct on the stack, then invoke the ioctl.
Jason
Quoted 10 lines · Jason Gunthorpe
Quoted 9 lines · Daniel Borkmann
[...]
Fyi, this breaks BPF CI:https://github.com/kernel-patches/bpf/runs/7078719372?check_suite_focus=true
[...]
progs/map_ptr_kern.c:314:26: error: field 'trie_key' with variable sized type 'structbpf_lpm_trie_key' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]struct bpf_lpm_trie_key trie_key; ^
The issue here seems to be a collision between "unknown array size" and known sizes:
struct bpf_lpm_trie_key {
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
__u8 data[0]; /* Arbitrary size */};
struct lpm_key {
struct bpf_lpm_trie_key trie_key;
__u32 data;
};This is treating trie_key as a header, which it's not: it's a complete structure. :)
Perhaps:
struct lpm_key {
__u32 prefixlen;
__u32 data;
};I don't see anything else trying to include bpf_lpm_trie_key.
Quoted 12 lines
This will break the rdma-core userspace as well, with a similar error:
/usr/bin/clang-13-DVERBS_DEBUG -Dibverbs_EXPORTS -Iinclude -I/usr/include/libnl3 -I/usr/include/drm -g -O2 -fdebug-prefix-map=/__w/1/s=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wmissing-prototypes -Wmissing-declarations -Wwrite-strings -Wformat=2 -Wcast-function-type -Wformat-nonliteral -Wdate-time -Wnested-externs -Wshadow -Wstrict-prototypes -Wold-style-definition -Werror -Wredundant-decls -g -fPIC -std=gnu11 -MD -MTlibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-MF libibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o.d -olibibverbs/CMakeFiles/ibverbs.dir/cmd_flow.c.o-c../libibverbs/cmd_flow.c
In file included from../libibverbs/cmd_flow.c:33:
In file included frominclude/infiniband/cmd_write.h:36:
In file included frominclude/infiniband/cmd_ioctl.h:41:
In file included frominclude/infiniband/verbs.h:48:
In file included frominclude/infiniband/verbs_api.h:66:
In file included frominclude/infiniband/ib_user_ioctl_verbs.h:38:include/rdma/ib_user_verbs.h:436:34: error: field 'base' with variable sized type 'structib_uverbs_create_cq_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
Quoted 4 lines
struct ib_uverbs_create_cq_resp base;
^
include/rdma/ib_user_verbs.h:644:34: error: field 'base' with variable sized type 'struct ib_uverbs_create_qp_resp' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end]
struct ib_uverbs_create_qp_resp base;This looks very similar, a struct of unknown size is being treated as a header struct:
struct ib_uverbs_create_cq_resp {
__u32 cq_handle;
__u32 cqe;
__aligned_u64 driver_data[0];
};struct ib_uverbs_ex_create_cq_resp {
struct ib_uverbs_create_cq_resp base;
__u32 comp_mask;
__u32 response_length;
};And it only gets used here:
DECLARE_UVERBS_WRITE(IB_USER_VERBS_CMD_CREATE_CQ,
ib_uverbs_create_cq,
UAPI_DEF_WRITE_UDATA_IO(
struct ib_uverbs_create_cq,
struct ib_uverbs_create_cq_resp),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UAPI_DEF_METHOD_NEEDS_FN(create_cq)),which must also be assuming it's a header. So probably better to just drop the driver_data field? I don't see anything using it (that I can find) besides as a sanity-check that the field exists and is at the end of the struct.
Signature · 1 line
Kees Cook
Quoted 4 lines · Kees Cook
which must also be assuming it's a header. So probably better to just drop the
driver_datafield? I don't see anything using it (that I can find) besides as a sanity-check that the field exists and is at the end of the struct.
The field is guaranteeing alignment of the following structure. IIRC there are a few cases that we don't have a u64 already to force this.
Jason
David Woodhouse
maintainerQuoted 16 lines · Kees Cook
The issue here seems to be a collision between "unknown array size" and known sizes:
struct
bpf_lpm_trie_key{__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ __u8 data[0]; /* Arbitrary size */};
struct lpm_key { struct bpf_lpm_trie_key trie_key; __u32 data; };This is treating
trie_keyas a header, which it's not: it's a complete structure. :)
Quoted 8 lines
Perhaps:
struct lpm_key { __u32 prefixlen; __u32 data; };I don't see anything else trying to include
bpf_lpm_trie_key.
What was the eventual conclusion here?
These changes broke userspace compilation, because a *lot* of these structures ending with VLAs are very much used as headers.
QEMU does it, for example...
uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
{
struct {
struct kvm_msrs info;
struct kvm_msr_entry entries[1];
} msr_data = {};... which works in C but not in C++, which gives an error I can't work out how to avoid.
Am I missing something, or did we break our userspace headers for C++ and make them C-only?
$ cat test_kvm.cpp #include <cstdlib> #include <asm/kvm.h>
struct msr_data {
struct kvm_msrs info;
struct kvm_msr_entry entries[1];
};struct msr_data *alloc_msr_data(void)
{
return static_cast<struct msr_data *>(malloc(sizeof(struct msr_data)));
} $ g++ -c -o test_kvm.o test_kvm.cpp
In file included from test_kvm.cpp:2:
/usr/include/x86_64-linux-gnu/asm/kvm.h:194:30: error: flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’
194 | struct kvm_msr_entry entries[];
| ^~~~~~~
test_kvm.cpp:6:30: note: next member ‘kvm_msr_entry msr_data::entries [1]’ declared here
6 | struct kvm_msr_entry entries[1];
| ^~~~~~~
test_kvm.cpp:4:8: note: in the definition of ‘struct msr_data’
4 | struct msr_data {
| ^~~~~~~~Quoted 47 lines · David Woodhouse
Quoted 16 lines · Kees Cook
The issue here seems to be a collision between "unknown array size" and known sizes:
struct
bpf_lpm_trie_key{__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ __u8 data[0]; /* Arbitrary size */};
struct lpm_key { struct bpf_lpm_trie_key trie_key; __u32 data; };This is treating
trie_keyas a header, which it's not: it's a complete structure. :)Quoted 8 lines
Perhaps:
struct lpm_key { __u32 prefixlen; __u32 data; };I don't see anything else trying to include
bpf_lpm_trie_key.What was the eventual conclusion here?
These changes broke userspace compilation, because a *lot* of these structures ending with VLAs are very much used as headers.
QEMU does it, for example...
uint64_tkvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index){ struct { struct kvm_msrs info; struct kvm_msr_entry entries[1]; } msr_data = {};... which works in C but not in C++, which gives an error I can't work out how to avoid.
Am I missing something, or did we break our userspace headers for C++ and make them C-only?
Quoted 8 lines
$ cat test_kvm.cpp #include <cstdlib> #include <asm/kvm.h>struct msr_data { struct kvm_msrs info; struct kvm_msr_entry entries[1]; };
Something like this should eventually land:
tools/arch/x86/include/uapi/asm/kvm.h +5 -2
@@ -192,11 +192,14 @@ struct kvm_msr_entry {__u64 data; }; -/* for KVM_GET_MSRS and KVM_SET_MSRS */ -struct kvm_msrs { +struct kvm_msrs_hdr {__u32 nmsrs;/* number of msrs in entries */ __u32 pad; +}; +/* for KVM_GET_MSRS and KVM_SET_MSRS */ +struct kvm_msrs { +struct kvm_msrs_hdr ;struct kvm_msr_entry entries[]; };
tools/testing/selftests/kvm/Makefile.kvm +2 -0
@@ -261,6 +261,8 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ -fno-builtin-memcmp -fno-builtin-memcpy \ -fno-builtin-memset -fno-builtin-strnlen \ -fno-stack-protector -fno-PIE -fno-strict-aliasing \ + -Wno-microsoft-anon-tag \ + -fms-extensions \ -I$(LINUX_TOOL_INCLUDE) -I$(LINUX_TOOL_ARCH_INCLUDE) \ -I$(LINUX_HDR_PATH) -Iinclude -I$(<D) -Iinclude/$(ARCH) \ -I ../rseq -I.. $(EXTRA_CFLAGS) $(KHDR_INCLUDES)
tools/testing/selftests/kvm/lib/x86/processor.c +1 -1
@@ -1076,7 +1076,7 @@ uint64_t vcpu_get_msr(struct kvm_vcpu *vcpu, uint64_t msr_index)int _vcpu_set_msr (struct kvm_vcpu *vcpu,uint64_t msr_index,uint64_t msr_value) {struct { -struct kvm_msrs header; +struct kvm_msrs_hdr header;struct kvm_msr_entry entry; } buffer = {};
(patch above untested)
-Gustavo
Quoted 18 lines
struct
msr_data*alloc_msr_data(void){ return static_cast<struct msr_data *>(malloc(sizeof(struct msr_data))); }$ g++ -c -o test_kvm.o test_kvm.cpp In file included from test_kvm.cpp:2: /usr/include/x86_64-linux-gnu/asm/kvm.h:194:30: error: flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’ 194 | struct kvm_msr_entry entries[]; | ^~~~~~~ test_kvm.cpp:6:30: note: next member ‘kvm_msr_entry msr_data::entries [1]’ declared here 6 | struct kvm_msr_entry entries[1]; | ^~~~~~~ test_kvm.cpp:4:8: note: in the definition of ‘struct msr_data’ 4 | struct msr_data { | ^~~~~~~~
David Woodhouse
maintainerQuoted 48 lines · Gustavo A. R. Silva
Quoted 19 lines
These changes broke userspace compilation, because a *lot* of these structures ending with VLAs are very much used as headers.
QEMU does it, for example...
uint64_tkvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index){
struct {
structkvm_msrsinfo;
structkvm_msr_entryentries[1];
}msr_data= {};... which works in C but not in C++, which gives an error I can't work out how to avoid.
Am I missing something, or did we break our userspace headers for C++ and make them C-only?
Quoted 8 lines
$ cat test_kvm.cpp #include <cstdlib> #include <asm/kvm.h>struct msr_data { struct kvm_msrs info; struct kvm_msr_entry entries[1]; };Something like this should eventually land:
tools/arch/x86/include/uapi/asm/kvm.h +1
-2@@ -192,11 +192,14 @@ struct kvm_msr_entry { __u64 data; }; -/* for KVM_GET_MSRS and KVM_SET_MSRS */ -struct kvm_msrs { +struct kvm_msrs_hdr {
__u32nmsrs; /* number of msrs in entries */__u32pad;tools/arch/x86/include/uapi/asm/kvm.h +4
-0+}; +/* for KVM_GET_MSRS and KVM_SET_MSRS */ +struct kvm_msrs { + struct kvm_msrs_hdr;
Quoted 2 lines
struct
kvm_msr_entryentries[];
};
I guess that would work, although it's still breaking the userspace API.
I was thinking of something along the lines of
#ifdef __cplusplus
#define __KERNEL_VLA 0
#else
#define __KERNEL_VLA
#endif
struct kvm_msrs {
__u32 nmsrs; /* number of msrs in entries */
__u32 pad;
struct kvm_msr_entry entries[__KERNEL_VLA];};
I suppose it could depend on __KERNEL__ instead of __cplusplus too?
David Woodhouse
maintainerPATCH 1/1 KVM: x86: Fix C++ user API for structures with variable length arrays
In reply to Gustavo A. R. SilvaFrom: David Woodhouse <[email protected]>
Commit 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++. Not just in the sense of 'userspace needs to be updated, but UAPI is supposed to be stable", but broken in the sense that I can't actually see *how* the structures can be used from C++ in the same way that they were usable before.
These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's kvm_arch_get_supported_msr_feature():
struct {
struct kvm_msrs info;
struct kvm_msr_entry entries[1];
} msr_data = {};While that works in C, it fails in C++ with an error like:
flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’
Fix this by using __DECLARE_FLEX_ARRAY() for the VLA, which is a helper provided by <linux/stddef.h> that already uses [0] for C++ compilation.
Also put the header fields into a struct_group() to provide (in C) a separate struct (e.g 'struct kvm_msrs_hdr') without the trailing VLA.
--- arch/x86/include/uapi/asm/kvm.h | 29 ++++++++++++++++++----------- include/uapi/linux/kvm.h | 9 ++++++--- 2 files changed, 24 insertions(+), 14 deletions(-)
arch/x86/include/uapi/asm/kvm.h +18 -11
@@ -194,16 +194,19 @@ struct kvm_msr_entry {/* for KVM_GET_MSRS and KVM_SET_MSRS */ struct kvm_msrs { -__u32 nmsrs;/* number of msrs in entries */ -__u32 pad; - -struct kvm_msr_entry entries[]; + __struct_group(kvm_msrs_hdr, hdr, /* no attrs */, + __u32 nmsrs; /* number of msrs in entries */ +__u32 pad; + ); + __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };/* for KVM_GET_MSR_INDEX_LIST */ struct kvm_msr_list { -__u32 nmsrs;/* number of msrs in entries */ -__u32 indices[]; + __struct_group(kvm_msr_list_hdr, hdr, /* no attrs */, + __u32 nmsrs; /* number of msrs in entries */ + ); + __DECLARE_FLEX_ARRAY(__u32, indices); };/* Maximum size of any access bitmap in bytes */
@@ -265,9 +268,11 @@ struct kvm_cpuid_entry2 {/* for KVM_SET_CPUID2 */ struct kvm_cpuid2 { -__u32 nent; -__u32 padding; -struct kvm_cpuid_entry2 entries[]; + __struct_group(kvm_cpuid2_hdr, hdr, /* no attrs */, + __u32 nent; +__u32 padding; + ); + __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry2, entries); };/* for KVM_GET_PIT and KVM_SET_PIT */
@@ -397,8 +402,10 @@ struct kvm_xsave {* The offsets of the state save areas in struct kvm_xsave follow * the contents of CPUID leaf 0xD on the host. */ -__u32 region[1024 ]; -__u32 extra[]; + __struct_group(kvm_xsave_hdr, hdr, /* no attrs */, + __u32 region[1024]; + ); +__DECLARE_FLEX_ARRAY (__u32, extra); };#define KVM_MAX_XCRS 16
include/uapi/linux/kvm.h +6 -3
@@ -11,6 +11,7 @@#include <linux/const.h> #include <linux/types.h> #include <linux/compiler.h> +#include <linux/stddef.h> #include <linux/ioctl.h> #include <asm/kvm.h>
@@ -1034,9 +1035,11 @@ struct kvm_irq_routing_entry { };struct kvm_irq_routing { -__u32 nr; -__u32 flags; -struct kvm_irq_routing_entry entries[]; + __struct_group(kvm_irq_routing_hdr, hdr, /* no attrs */, + __u32 nr; +__u32 flags; + ); + __DECLARE_FLEX_ARRAY(struct kvm_irq_routing_entry, entries); };#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
Signature · 1 line
2.43.0
Re: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 19 lines · David Woodhouse
From: David Woodhouse <[email protected]>
Commit
94dfc73e7cf4("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++. Not just in the sense of 'userspace needs to be updated, but UAPI is supposed to be stable", but broken in the sense that I can't actually see *how* the structures can be used from C++ in the same way that they were usable before.These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's
kvm_arch_get_supported_msr_feature():struct { struct kvm_msrs info; struct kvm_msr_entry entries[1]; } msr_data = {};
Quoted 5 lines
While that works in C, it fails in C++ with an error like:
flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’Fix this by using
__DECLARE_FLEX_ARRAY()for the VLA, which is a helper provided by <linux/stddef.h> that already uses [0] for C++ compilation.
This is likely the best plan for these cases. I had to do similar for ACPICA upstream, leaving these flex arrays as [0] for the non-GCC (and Clang) builds:
https://github.com/acpica/acpica/commit/e73b227e8e475c20cc394f237ea35d592fdf9ec3
Quoted 2 lines
Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.
Right, my only worry is if C++ would want those header structs too. In that case, you'd probably want to use a macro to include them (since not all compilers are supporting transparent struct members yet):
#define __kvm_msrs_hdr \ __u32 nmsrs; /* number of msrs in entries */ \ __u32 pad
struct kvm_msrs_hdr {
__kvm_msrs_hdr;
};struct kvm_msrs {
__kvm_msrs_hdr;
__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
};Quoted 3 lines
Fixes 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members")Signed-off-by David Woodhouse <[email protected]>
Regardless:
Signature · 1 line
Kees Cook
David Woodhouse
maintainerRe: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 12 lines · Kees Cook
Quoted 3 lines
Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.Right, my only worry is if C++ would want those header structs too. In that case, you'd probably want to use a macro to include them (since not all compilers are supporting transparent struct members yet):
#define __kvm_msrs_hdr \ __u32 nmsrs; /* number of msrs in entries */ \ __u32 pad
Quoted 8 lines
struct kvm_msrs_hdr { __kvm_msrs_hdr; };struct kvm_msrs { __kvm_msrs_hdr; __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };
Hm, does the struct_group() not also depend on the compiler supporting anonymous struct members? Is there a distinction I'm missing?
Re: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 17 lines · David Woodhouse
Quoted 16 lines · Kees Cook
Quoted 3 lines
Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.Right, my only worry is if C++ would want those header structs too. In that case, you'd probably want to use a macro to include them (since not all compilers are supporting transparent struct members yet):
#define __kvm_msrs_hdr \ __u32 nmsrs; /* number of msrs in entries */ \ __u32 padstruct kvm_msrs_hdr { __kvm_msrs_hdr; };
Quoted 7 lines
Quoted 4 lines
struct kvm_msrs { __kvm_msrs_hdr; __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };Hm, does the
struct_group()not also depend on the compiler supporting anonymous struct members? Is there a distinction I'm missing?
Sorry, I should have been mor clear: the _tag_ that struct_group creates isn't supported for all C++ compilers (so is commented out for C++) so if a C++ project wanted to use the struct by its tag ("struct kvm_msrs_hdr"), you'd need the construct I wrote above.
-Kees
Signature · 1 line
Kees Cook
David Woodhouse
maintainerRe: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 25 lines · Kees Cook
Quoted 22 lines · David Woodhouse
Quoted 20 lines · Kees Cook
Quoted 3 lines
Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.Right, my only worry is if C++ would want those header structs too. In that case, you'd probably want to use a macro to include them (since not all compilers are supporting transparent struct members yet):
#define __kvm_msrs_hdr \ __u32 nmsrs; /* number of msrs in entries */ \ __u32 padstruct kvm_msrs_hdr { __kvm_msrs_hdr; };struct kvm_msrs { __kvm_msrs_hdr; __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };
Quoted 8 lines
Quoted 2 lines
Hm, does the
struct_group()not also depend on the compiler supporting anonymous struct members? Is there a distinction I'm missing?Sorry, I should have been mor clear: the _tag_ that
struct_groupcreates isn't supported for all C++ compilers (so is commented out for C++) so if a C++ project wanted to use the struct by its tag ("structkvm_msrs_hdr"), you'd need the construct I wrote above.
Understood, yes. I was actually getting confused about why we'd use that #define __kvm_msrs_hdr, and why we wouldn't do it like this:
struct kvm_msr_hdr {
__u32 nmsrs;
__u32 pad;
}
struct kvm_msrs {
struct kvm_msr_hdr /* anonymous */;
__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);};
(In fact, that doesn't even work with GCC). Nevertheless, my question at the time was intended as: if we can't do it like *that*, then surely the struct_group() construct will fail on those compilers too?
But that was a brain fart because what struct_group() does is actually more like:
struct kvm_msrs {
union {
struct { __u32 nmsrs; __u32 pad; };
struct /* foo in C */ { __u32 nmsrs; __u32 pad; } foo;
};
__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);};
And that *does* work.
But yeah, I think C++ should be fine without the new header structs. What I posted at least allows it to *build* with actual instantiations of these structures with real payload again.
Sean Christopherson
maintainerRe: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
In reply to David WoodhouseQuoted 19 lines · David Woodhouse
From: David Woodhouse <[email protected]>
Commit
94dfc73e7cf4("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++. Not just in the sense of 'userspace needs to be updated, but UAPI is supposed to be stable", but broken in the sense that I can't actually see *how* the structures can be used from C++ in the same way that they were usable before.These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's
kvm_arch_get_supported_msr_feature():struct { struct kvm_msrs info; struct kvm_msr_entry entries[1]; } msr_data = {};
Quoted 8 lines
While that works in C, it fails in C++ with an error like:
flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’Fix this by using
__DECLARE_FLEX_ARRAY()for the VLA, which is a helper provided by <linux/stddef.h> that already uses [0] for C++ compilation.Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.
Unless I'm missing something, this is an entirely optional change that needs to be done separately, especialy since I want to tag this for:
I definitely don't hate the __struct_group definitions, but I don't know that I love them either as they make the code a bit harder to read, and more importantly there's a non-zero chance that defining the new structurs could break userspace builds and force an update, e.g. if userspace already concocts its own header overlay, which would be very unpleasant for a stable@ patch.
If we do define headers, I think I'd want a wrapper around __struct_group() to prettify the common case and force consistent naming, e.g.
#define kvm_struct_header(NAME, MEMBERS...) \ __struct_group(NAME ##_header, h, /* no attrs */, MEMBERS)
struct kvm_msrs {
kvm_struct_header(kvm_msrs,
__u32 nmsrs; /* number of msrs in entries */
__u32 pad;
);
__DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries);
};But that's likely going to lead to some amount of bikeshedding, e.g. arguably kvm_header() would be sufficient and easier on the eyes. Which is all the more reason to handle it separately.
Quoted 7 lines
Fixes 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members")Signed-off-by David Woodhouse <[email protected]>--- arch/x86/include/uapi/asm/kvm.h | 29 ++++++++++++++++++----------- include/uapi/linux/kvm.h | 9 ++++++---/* for
KVM_GET_PITandKVM_SET_PIT*/
arch/x86/include/uapi/asm/kvm.h struct kvm_xsave { · line 407
Quoted 8 lines
arch/x86/include/uapi/asm/kvm.h +3
-2@@ -397,8 +402,10 @@ struct kvm_xsave {* The offsets of the state save areas in struct kvm_xsave follow * the contents of CPUID leaf 0xD on the host. */ -__u32 region[1024 ]; -__u32 extra[]; + __struct_group(kvm_xsave_hdr, hdr, /* no attrs */, + __u32 region[1024]; + );
This is *very* misleading, as XSTATE itself has a header, but this is something else entirely (just the always-allocated region).
arch/x86/include/uapi/asm/kvm.h struct kvm_xsave { · line 409
Quoted 2 lines
arch/x86/include/uapi/asm/kvm.h +1
-0+__DECLARE_FLEX_ARRAY (__u32, extra); };
There are several structs that got missed:
kvm_pmu_event_filter
kvm_reg_list
kvm_signal_mask
kvm_coalesced_mmio_ring
kvm_cpuid
kvm_stats_desc
David Woodhouse
maintainerRe: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 83 lines · Sean Christopherson
Quoted 19 lines · David Woodhouse
From: David Woodhouse <[email protected]>
Commit
94dfc73e7cf4("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++. Not just in the sense of 'userspace needs to be updated, but UAPI is supposed to be stable", but broken in the sense that I can't actually see *how* the structures can be used from C++ in the same way that they were usable before.These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's
kvm_arch_get_supported_msr_feature():struct {
structkvm_msrsinfo;
structkvm_msr_entryentries[1];
}msr_data= {};Quoted 8 lines
While that works in C, it fails in C++ with an error like:
flexible array member ‘kvm_msrs::entries’ not at end of ‘struct msr_data’Fix this by using
__DECLARE_FLEX_ARRAY()for the VLA, which is a helper provided by <linux/stddef.h> that already uses [0] for C++ compilation.Also put the header fields into a
struct_group()to provide (in C) a separate struct (e.g 'structkvm_msrs_hdr') without the trailing VLA.Unless I'm missing something, this is an entirely optional change that needs to be done separately, especialy since I want to tag this for:
I definitely don't hate the
__struct_groupdefinitions, but I don't know that I love them either as they make the code a bit harder to read, and more importantly there's a non-zero chance that defining the new structurs could break userspace builds and force an update, e.g. if userspace already concocts its own header overlay, which would be very unpleasant for a stable@ patch.If we do define headers, I think I'd want a wrapper around
__struct_group()to prettify the common case and force consistent naming, e.g.#define kvm_struct_header(NAME, MEMBERS...) \ __struct_group(NAME ##_header, h, /* no attrs */, MEMBERS)struct kvm_msrs { kvm_struct_header(kvm_msrs, __u32 nmsrs; /* number of msrs in entries */ __u32 pad; ); __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };But that's likely going to lead to some amount of bikeshedding, e.g. arguably
kvm_header()would be sufficient and easier on the eyes. Which is all the more reason to handle it separately.Quoted 7 lines
Fixes 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members")Signed-off-by David Woodhouse <[email protected]>---
arch/x86/include/uapi/asm/kvm.h | 29 ++++++++++++++++++----------- include/uapi/linux/kvm.h | 9 ++++++---
/* forKVM_GET_PITandKVM_SET_PIT*/arch/x86/include/uapi/asm/kvm.h struct kvm_xsave { · line 407
Quoted 8 lines
arch/x86/include/uapi/asm/kvm.h +3
-2@@ -397,8 +402,10 @@ struct kvm_xsave {* The offsets of the state save areas in struct kvm_xsave follow * the contents of CPUID leaf 0xD on the host. */ -__u32 region[1024 ]; -__u32 extra[]; + __struct_group(kvm_xsave_hdr, hdr, /* no attrs */, + __u32 region[1024]; + );This is *very* misleading, as XSTATE itself has a header, but this is something else entirely (just the always-allocated region).
arch/x86/include/uapi/asm/kvm.h struct kvm_xsave { · line 409
Quoted 2 lines
arch/x86/include/uapi/asm/kvm.h +1
-0+__DECLARE_FLEX_ARRAY (__u32, extra); };There are several structs that got missed:
Quoted 6 lines
kvm_pmu_event_filter
kvm_reg_list
kvm_signal_mask
kvm_coalesced_mmio_ring
kvm_cpuid
kvm_stats_desc
Ack. Shall we do just the __DECLARE_FLEX_ARRAY() part, including those missed structures?
Sean Christopherson
maintainerRe: [PATCH] KVM: x86: Fix C++ user API for structures with variable length arrays
Quoted 13 lines · David Woodhouse
Quoted 11 lines · Sean Christopherson
Quoted 2 lines
arch/x86/include/uapi/asm/kvm.h +1
-0+__DECLARE_FLEX_ARRAY (__u32, extra);};
There are several structs that got missed:
kvm_pmu_event_filter
kvm_reg_list
kvm_signal_mask
kvm_coalesced_mmio_ring
kvm_cpuid
kvm_stats_desc
Quoted 2 lines
Ack. Shall we do just the
__DECLARE_FLEX_ARRAY()part, including those missed structures?
Ya, can you send a v2?
David Woodhouse
maintainerPATCH v2 1/1 KVM: x86: Use __DECLARE_FLEX_ARRAY() for UAPI structures with VLAs
From: David Woodhouse <[email protected]>
Commit 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++.
These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's kvm_arch_get_supported_msr_feature():
struct {
struct kvm_msrs info;
struct kvm_msr_entry entries[1];
} msr_data = {};While that works in C, it fails in C++ with an error like:
flexible array member 'kvm_msrs::entries' not at end of 'struct msr_data'
Fix this by using __DECLARE_FLEX_ARRAY() for the VLA, which uses [0] for C++ compilation.
--- arch/x86/include/uapi/asm/kvm.h | 12 ++++++------ include/uapi/linux/kvm.h | 11 ++++++----- 2 files changed, 12 insertions(+), 11 deletions(-)
arch/x86/include/uapi/asm/kvm.h +6 -6
@@ -197,13 +197,13 @@ struct kvm_msrs {__u32 nmsrs;/* number of msrs in entries */ __u32 pad; -struct kvm_msr_entry entries[]; + __DECLARE_FLEX_ARRAY(struct kvm_msr_entry, entries); };/* for KVM_GET_MSR_INDEX_LIST */ struct kvm_msr_list {__u32 nmsrs;/* number of msrs in entries */ -__u32 indices[]; + __DECLARE_FLEX_ARRAY(__u32, indices); };/* Maximum size of any access bitmap in bytes */
@@ -245,7 +245,7 @@ struct kvm_cpuid_entry {struct kvm_cpuid {__u32 nent;__u32 padding; -struct kvm_cpuid_entry entries[]; + __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry, entries); };struct kvm_cpuid_entry2 {
@@ -267,7 +267,7 @@ struct kvm_cpuid_entry2 {struct kvm_cpuid2 {__u32 nent;__u32 padding; -struct kvm_cpuid_entry2 entries[]; + __DECLARE_FLEX_ARRAY(struct kvm_cpuid_entry2, entries); };/* for KVM_GET_PIT and KVM_SET_PIT */
@@ -398,7 +398,7 @@ struct kvm_xsave {* the contents of CPUID leaf 0xD on the host. */ __u32 region[1024 ]; -__u32 extra[]; +__DECLARE_FLEX_ARRAY (__u32, extra); };#define KVM_MAX_XCRS 16
@@ -564,7 +564,7 @@ struct kvm_pmu_event_filter {__u32 fixed_counter_bitmap;__u32 flags;__u32 pad[4 ]; -__u64 events[]; +__DECLARE_FLEX_ARRAY (__u64, events); };#define KVM_PMU_EVENT_ALLOW 0
include/uapi/linux/kvm.h +6 -5
@@ -11,6 +11,7 @@#include <linux/const.h> #include <linux/types.h> #include <linux/compiler.h> +#include <linux/stddef.h> #include <linux/ioctl.h> #include <asm/kvm.h>
@@ -528,7 +529,7 @@ struct kvm_coalesced_mmio {struct kvm_coalesced_mmio_ring {__u32 first, last; -struct kvm_coalesced_mmio coalesced_mmio[]; + __DECLARE_FLEX_ARRAY(struct kvm_coalesced_mmio, coalesced_mmio); };#define KVM_COALESCED_MMIO_MAX \
@@ -578,7 +579,7 @@ struct kvm_clear_dirty_log {/* for KVM_SET_SIGNAL_MASK */ struct kvm_signal_mask {__u32 len; -__u8 sigset[]; + __DECLARE_FLEX_ARRAY(__u8, sigset); };/* for KVM_TPR_ACCESS_REPORTING */
@@ -1036,7 +1037,7 @@ struct kvm_irq_routing_entry {struct kvm_irq_routing {__u32 nr;__u32 flags; -struct kvm_irq_routing_entry entries[]; + __DECLARE_FLEX_ARRAY(struct kvm_irq_routing_entry, entries); };#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
@@ -1127,7 +1128,7 @@ struct kvm_dirty_tlb {struct kvm_reg_list {__u64 n;/* number of regs */ -__u64 reg[]; + __DECLARE_FLEX_ARRAY(__u64, reg); };struct kvm_one_reg {
@@ -1579,7 +1580,7 @@ struct kvm_stats_desc {__u16 size;__u32 offset;__u32 bucket_size; -char name[]; +__DECLARE_FLEX_ARRAY (char, name); };#define KVM_GET_STATS_FD _IO(KVMIO, 0xce)
Signature · 1 line
2.43.0
Re: [PATCH v2] KVM: x86: Use __DECLARE_FLEX_ARRAY() for UAPI structures with VLAs
Quoted 9 lines · David Woodhouse
Commit
94dfc73e7cf4("treewide: uapi: Replace zero-length arrays with flexible-array members") broke the userspace API for C++.These structures ending in VLAs are typically a *header*, which can be followed by an arbitrary number of entries. Userspace typically creates a larger structure with some non-zero number of entries, for example in QEMU's
kvm_arch_get_supported_msr_feature():[...]
Applied to kvm-x86 fixes, way back on March 12th (i.e. this has been in -next for several weeks). Thanks!
[1/1] KVM: x86: Use __DECLARE_FLEX_ARRAY() for UAPI structures with VLAs
https://github.com/kvm-x86/linux/commit/2619da73bb2f
Quoted 33 lines · On Mon, 27 Jun 2022 20:04:32 +0200 "Gustavo A. R. Silva"…
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S {
...
T1 member;
T2 array[
- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
Quoted 6 lines
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arrays
Thanks this fixes warning with gcc-12 in iproute2.
In function ‘xfrm_algo_parse’,
inlined from ‘xfrm_state_modify.constprop’ at xfrm_state.c:573:5:
xfrm_state.c:162:32: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
162 | buf[j] = val;
| ~~~~~~~^~~~~Quoted 6 lines · Stephen Hemminger
Thanks this fixes warning with gcc-12 in iproute2.
In function ‘xfrm_algo_parse’,
inlined from ‘xfrm_state_modify.constprop’ at xfrm_state.c:573:5:
xfrm_state.c:162:32: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]162 | buf[j] = val; | ~~~~~~~^~~~~
Great! This gives me hope. :)
Thanks
--
Gustavo
Quoted 44 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
This code was transformed with the help of Coccinelle:
(linux-5.19-rc2$ spatch --jobs $(getconf_NPROCESSORS_ONLN) --sp-filescript.cocci--include-headers --dir . > output.patch)@@
identifier S, member, array;
type T1, T2;
@@struct S {
...
T1 member;
T2 array[
- 0
];
};-fstrict-flex-arrays=3 is coming and we need to land these changes to prevent issues like these in the short future:
../fs/minix/dir.c:337:3: warning: 'strcpy' will always overflow; destination buffer has size 0, but the source string has length 2 (including NUL byte) [-Wfortify-source]strcpy(de3->name, "."); ^Since these are all [0] to [] changes, the risk to UAPI is nearly zero. If this breaks anything, we can use a union with a new member name.
[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://www.kernel.org/doc/html/v5.16/process/deprecated.html#zero-length-and-one-element-arraysSigned-off-by Gustavo A. R. Silva <[email protected]>---
Hi all!JFYI: I'm adding this to my -next tree. :)
[..]
Quoted 1 line
include/uapi/linux/ndctl.h | 10 +--
For ndctl.h
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Geert Uytterhoeven
maintainerHi Gustavo,
Thanks for your patch!
Quoted 5 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
These rules apply to the kernel, but uapi is not considered part of the kernel, so different rules apply. Uapi header files should work with whatever compiler that can be used for compiling userspace.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Quoted 12 lines · Geert Uytterhoeven
Hi Gustavo,
Thanks for your patch!
Quoted 5 lines · Gustavo A. R. Silva
There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use “flexible array members”[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2].
Quoted 3 lines
These rules apply to the kernel, but uapi is not considered part of the kernel, so different rules apply. Uapi header files should work with whatever compiler that can be used for compiling userspace.
Right, userspace isn't bound by these rules, but the kernel ends up consuming these structures, so we need to fix them. The [0] -> [] changes (when they are not erroneously being used within other structures) is valid for all compilers. Flexible arrays are C99; it's been 23 years. :)
But, yes, where we DO break stuff we need to workaround it, etc.
Signature · 1 line
Kees Cook