1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-08 08:58:27 +03:00

Merge pull request #26321 from keszybz/flex-arrays

Enable new compiler diagnostics for invalid array accesses
This commit is contained in:
Yu Watanabe 2023-02-07 12:07:21 +09:00 committed by GitHub
commit e7ced42d24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 704 additions and 331 deletions

View File

@ -354,6 +354,8 @@ basic_disabled_warnings = [
]
possible_common_cc_flags = [
'-Warray-bounds', # clang
'-Warray-bounds=2',
'-Wdate-time',
'-Wendif-labels',
'-Werror=format=2',
@ -387,10 +389,13 @@ possible_common_cc_flags = [
'-Wsuggest-attribute=noreturn',
'-Wunused-function',
'-Wwrite-strings',
'-Wzero-length-bounds',
# negative arguments are correctly detected starting with meson 0.46.
'-Wno-error=#warnings', # clang
'-Wno-string-plus-int', # clang
'-fstrict-flex-arrays',
]
c_args = get_option('c_args')

View File

@ -376,3 +376,15 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
(v) = UPDATE_FLAG(v, flag, b)
#define FLAGS_SET(v, flags) \
((~(v) & (flags)) == 0)
/* Declare a flexible array usable in a union.
* This is essentially a work-around for a pointless constraint in C99
* and might go away in some future version of the standard.
*
* See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=3080ea5553cc909b000d1f1d964a9041962f2c5b
*/
#define DECLARE_FLEX_ARRAY(type, name) \
struct { \
dummy_t __empty__ ## name; \
type name[]; \
}

View File

@ -28,7 +28,7 @@ struct DHCPMessage {
uint8_t sname[64];
uint8_t file[128];
be32_t magic;
uint8_t options[0];
uint8_t options[];
} _packed_;
typedef struct DHCPMessage DHCPMessage;

View File

@ -93,22 +93,28 @@ struct FieldObject FieldObject__contents;
struct FieldObject__packed FieldObject__contents _packed_;
assert_cc(sizeof(struct FieldObject) == sizeof(struct FieldObject__packed));
#define EntryObject__contents { \
ObjectHeader object; \
le64_t seqnum; \
le64_t realtime; \
le64_t monotonic; \
sd_id128_t boot_id; \
le64_t xor_hash; \
union { \
struct { \
le64_t object_offset; \
le64_t hash; \
} regular[0]; \
struct { \
le32_t object_offset; \
} compact[0]; \
} items; \
#define EntryObject__contents { \
ObjectHeader object; \
le64_t seqnum; \
le64_t realtime; \
le64_t monotonic; \
sd_id128_t boot_id; \
le64_t xor_hash; \
union { \
struct { \
dummy_t __empty__regular; \
struct { \
le64_t object_offset; \
le64_t hash; \
} regular[]; \
}; \
struct { \
dummy_t __empty_compact; \
struct { \
le32_t object_offset; \
} compact[]; \
}; \
} items; \
}
struct EntryObject EntryObject__contents;
@ -129,8 +135,8 @@ struct EntryArrayObject {
ObjectHeader object;
le64_t next_entry_array_offset;
union {
le64_t regular[0];
le32_t compact[0];
DECLARE_FLEX_ARRAY(le64_t, regular);
DECLARE_FLEX_ARRAY(le32_t, compact);
} items;
} _packed_;

View File

@ -101,17 +101,12 @@ struct JsonVariant {
/* If is_reference as indicated above is set, this is where the reference object is actually stored. */
JsonVariant *reference;
/* Strings are placed immediately after the structure. Note that when this is a JsonVariant embedded
* into an array we might encode strings up to INLINE_STRING_LENGTH characters directly inside the
* element, while longer strings are stored as references. When this object is not embedded into an
* array, but stand-alone we allocate the right size for the whole structure, i.e. the array might be
* much larger than INLINE_STRING_LENGTH.
*
* Note that because we want to allocate arrays of the JsonVariant structure we specify [0] here,
* rather than the prettier []. If we wouldn't, then this char array would have undefined size, and so
* would the union and then the struct this is included in. And of structures with undefined size we
* can't allocate arrays (at least not easily). */
char string[0];
/* Strings are placed immediately after the structure. Note that when this is a JsonVariant
* embedded into an array we might encode strings up to INLINE_STRING_LENGTH characters
* directly inside the element, while longer strings are stored as references. When this
* object is not embedded into an array, but stand-alone, we allocate the right size for the
* whole structure, i.e. the array might be much larger than INLINE_STRING_LENGTH. */
DECLARE_FLEX_ARRAY(char, string);
};
};

View File

@ -1,6 +1,7 @@
The files in this directory are copied from kernel-5.2, and the following modifications are applied:
The files in this directory are copied from kernel-6.2, and the following modifications are applied:
- auto_dev-ioctl.h: set AUTOFS_DEV_IOCTL_VERSION_MINOR to 0
- auto_dev-ioctl.h: define AUTOFS_IOCTL if not defined
- auto_dev-ioctl.h: use of fake flexible array is fixed
- bpf_insn.h: This is imported from samples/bpf/bpf_insn.h
- bpf_insn.h: BPF_JMP_A() macro is also imported from include/linux/filter.h
- dm-ioctl.h: set DM_VERSION_MINOR to 27

View File

@ -8,8 +8,8 @@
* option, any later version, incorporated herein by reference.
*/
#ifndef _UAPI_LINUX_AUTO_DEV_IOCTL_H
#define _UAPI_LINUX_AUTO_DEV_IOCTL_H
#ifndef _LINUX_AUTO_DEV_IOCTL_H
#define _LINUX_AUTO_DEV_IOCTL_H
#include <linux/auto_fs.h>
#include <linux/string.h>
@ -109,10 +109,10 @@ struct autofs_dev_ioctl {
struct args_ismountpoint ismountpoint;
};
char path[0];
char path[];
};
static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
static __inline__ void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
{
memset(in, 0, AUTOFS_DEV_IOCTL_SIZE);
in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
@ -217,4 +217,4 @@ enum {
_IOWR(AUTOFS_IOCTL, \
AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
#endif /* _UAPI_LINUX_AUTO_DEV_IOCTL_H */
#endif /* _LINUX_AUTO_DEV_IOCTL_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI__LINUX_BPF_COMMON_H__
#define _UAPI__LINUX_BPF_COMMON_H__
#ifndef __LINUX_BPF_COMMON_H__
#define __LINUX_BPF_COMMON_H__
/* Instruction classes */
#define BPF_CLASS(code) ((code) & 0x07)
@ -54,4 +54,4 @@
#define BPF_MAXINSNS 4096
#endif
#endif /* _UAPI__LINUX_BPF_COMMON_H__ */
#endif /* __LINUX_BPF_COMMON_H__ */

View File

@ -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[];
};
/*

View File

@ -11,16 +11,14 @@
* Portions Copyright (C) Sun Microsystems 2008
*/
#ifndef _UAPI_LINUX_ETHTOOL_H
#define _UAPI_LINUX_ETHTOOL_H
#ifndef _LINUX_ETHTOOL_H
#define _LINUX_ETHTOOL_H
#include <linux/const.h>
#include <linux/types.h>
#include <linux/if_ether.h>
#ifndef __KERNEL__
#include <limits.h> /* for INT_MAX */
#endif
#ifndef __KERNEL_DIV_ROUND_UP
#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
@ -126,14 +124,14 @@ struct ethtool_cmd {
__u32 reserved[2];
};
static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
static __inline__ void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
__u32 speed)
{
ep->speed = (__u16)(speed & 0xFFFF);
ep->speed_hi = (__u16)(speed >> 16);
}
static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
static __inline__ __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
{
return ((__u32) ep->speed_hi << 16) | (__u32) ep->speed;
}
@ -163,8 +161,10 @@ static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
* in its bus driver structure (e.g. pci_driver::name). Must
* not be an empty string.
* @version: Driver version string; may be an empty string
* @fw_version: Firmware version string; may be an empty string
* @erom_version: Expansion ROM version string; may be an empty string
* @fw_version: Firmware version string; driver defined; may be an
* empty string
* @erom_version: Expansion ROM version string; driver defined; may be
* an empty string
* @bus_info: Device bus address. This should match the dev_name()
* string for the underlying bus device, if there is one. May be
* an empty string.
@ -183,10 +183,6 @@ static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
*
* Users can use the %ETHTOOL_GSSET_INFO command to get the number of
* strings in any string set (from Linux 2.6.34).
*
* Drivers should set at most @driver, @version, @fw_version and
* @bus_info in their get_drvinfo() implementation. The ethtool
* core fills in the other fields using other driver operations.
*/
struct ethtool_drvinfo {
__u32 cmd;
@ -261,7 +257,7 @@ struct ethtool_tunable {
__u32 id;
__u32 type_id;
__u32 len;
void *data[0];
void *data[];
};
#define DOWNSHIFT_DEV_DEFAULT_COUNT 0xff
@ -326,7 +322,7 @@ struct ethtool_regs {
__u32 cmd;
__u32 version;
__u32 len;
__u8 data[0];
__u8 data[];
};
/**
@ -352,7 +348,7 @@ struct ethtool_eeprom {
__u32 magic;
__u32 offset;
__u32 len;
__u8 data[0];
__u8 data[];
};
/**
@ -740,6 +736,51 @@ enum ethtool_module_power_mode {
ETHTOOL_MODULE_POWER_MODE_HIGH,
};
/**
* enum ethtool_podl_pse_admin_state - operational state of the PoDL PSE
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
* @ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN: state of PoDL PSE functions are
* unknown
* @ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED: PoDL PSE functions are disabled
* @ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED: PoDL PSE functions are enabled
*/
enum ethtool_podl_pse_admin_state {
ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN = 1,
ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED,
ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED,
};
/**
* enum ethtool_podl_pse_pw_d_status - power detection status of the PoDL PSE.
* IEEE 802.3-2018 30.15.1.1.3 aPoDLPSEPowerDetectionStatus:
* @ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN: PoDL PSE
* @ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED: "The enumeration “disabled” is
* asserted true when the PoDL PSE state diagram variable mr_pse_enable is
* false"
* @ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING: "The enumeration “searching” is
* asserted true when either of the PSE state diagram variables
* pi_detecting or pi_classifying is true."
* @ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING: "The enumeration “deliveringPower”
* is asserted true when the PoDL PSE state diagram variable pi_powered is
* true."
* @ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP: "The enumeration “sleep” is asserted
* true when the PoDL PSE state diagram variable pi_sleeping is true."
* @ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE: "The enumeration “idle” is asserted true
* when the logical combination of the PoDL PSE state diagram variables
* pi_prebiased*!pi_sleeping is true."
* @ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR: "The enumeration “error” is asserted
* true when the PoDL PSE state diagram variable overload_held is true."
*/
enum ethtool_podl_pse_pw_d_status {
ETHTOOL_PODL_PSE_PW_D_STATUS_UNKNOWN = 1,
ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED,
ETHTOOL_PODL_PSE_PW_D_STATUS_SEARCHING,
ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING,
ETHTOOL_PODL_PSE_PW_D_STATUS_SLEEP,
ETHTOOL_PODL_PSE_PW_D_STATUS_IDLE,
ETHTOOL_PODL_PSE_PW_D_STATUS_ERROR,
};
/**
* struct ethtool_gstrings - string set for data tagging
* @cmd: Command number = %ETHTOOL_GSTRINGS
@ -756,7 +797,7 @@ struct ethtool_gstrings {
__u32 cmd;
__u32 string_set;
__u32 len;
__u8 data[0];
__u8 data[];
};
/**
@ -781,7 +822,7 @@ struct ethtool_sset_info {
__u32 cmd;
__u32 reserved;
__u64 sset_mask;
__u32 data[0];
__u32 data[];
};
/**
@ -821,7 +862,7 @@ struct ethtool_test {
__u32 flags;
__u32 reserved;
__u32 len;
__u64 data[0];
__u64 data[];
};
/**
@ -838,7 +879,7 @@ struct ethtool_test {
struct ethtool_stats {
__u32 cmd;
__u32 n_stats;
__u64 data[0];
__u64 data[];
};
/**
@ -855,7 +896,7 @@ struct ethtool_stats {
struct ethtool_perm_addr {
__u32 cmd;
__u32 size;
__u8 data[0];
__u8 data[];
};
/* boolean flags controlling per-interface behavior characteristics.
@ -1063,12 +1104,12 @@ struct ethtool_rx_flow_spec {
#define ETHTOOL_RX_FLOW_SPEC_RING 0x00000000FFFFFFFFLL
#define ETHTOOL_RX_FLOW_SPEC_RING_VF 0x000000FF00000000LL
#define ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF 32
static inline __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
static __inline__ __u64 ethtool_get_flow_spec_ring(__u64 ring_cookie)
{
return ETHTOOL_RX_FLOW_SPEC_RING & ring_cookie;
}
static inline __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
static __inline__ __u64 ethtool_get_flow_spec_ring_vf(__u64 ring_cookie)
{
return (ETHTOOL_RX_FLOW_SPEC_RING_VF & ring_cookie) >>
ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF;
@ -1164,7 +1205,7 @@ struct ethtool_rxnfc {
struct ethtool_rxfh_indir {
__u32 cmd;
__u32 size;
__u32 ring_index[0];
__u32 ring_index[];
};
/**
@ -1205,7 +1246,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
@ -1290,7 +1331,7 @@ struct ethtool_dump {
__u32 version;
__u32 flag;
__u32 len;
__u8 data[0];
__u8 data[];
};
#define ETH_FW_DUMP_DISABLE 0
@ -1322,7 +1363,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[];
};
/**
@ -1344,7 +1385,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[];
};
/**
@ -1696,6 +1737,13 @@ enum ethtool_link_mode_bit_indices {
ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 90,
ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 91,
ETHTOOL_LINK_MODE_10baseT1L_Full_BIT = 92,
ETHTOOL_LINK_MODE_800000baseCR8_Full_BIT = 93,
ETHTOOL_LINK_MODE_800000baseKR8_Full_BIT = 94,
ETHTOOL_LINK_MODE_800000baseDR8_Full_BIT = 95,
ETHTOOL_LINK_MODE_800000baseDR8_2_Full_BIT = 96,
ETHTOOL_LINK_MODE_800000baseSR8_Full_BIT = 97,
ETHTOOL_LINK_MODE_800000baseVR8_Full_BIT = 98,
/* must be last entry */
__ETHTOOL_LINK_MODE_MASK_NBITS
};
@ -1807,10 +1855,11 @@ enum ethtool_link_mode_bit_indices {
#define SPEED_100000 100000
#define SPEED_200000 200000
#define SPEED_400000 400000
#define SPEED_800000 800000
#define SPEED_UNKNOWN -1
static inline int ethtool_validate_speed(__u32 speed)
static __inline__ int ethtool_validate_speed(__u32 speed)
{
return speed <= INT_MAX || speed == (__u32)SPEED_UNKNOWN;
}
@ -1820,7 +1869,7 @@ static inline int ethtool_validate_speed(__u32 speed)
#define DUPLEX_FULL 0x01
#define DUPLEX_UNKNOWN 0xff
static inline int ethtool_validate_duplex(__u8 duplex)
static __inline__ int ethtool_validate_duplex(__u8 duplex)
{
switch (duplex) {
case DUPLEX_HALF:
@ -1844,6 +1893,20 @@ static inline int ethtool_validate_duplex(__u8 duplex)
#define MASTER_SLAVE_STATE_SLAVE 3
#define MASTER_SLAVE_STATE_ERR 4
/* These are used to throttle the rate of data on the phy interface when the
* native speed of the interface is higher than the link speed. These should
* not be used for phy interfaces which natively support multiple speeds (e.g.
* MII or SGMII).
*/
/* No rate matching performed. */
#define RATE_MATCH_NONE 0
/* The phy sends pause frames to throttle the MAC. */
#define RATE_MATCH_PAUSE 1
/* The phy asserts CRS to prevent the MAC from transmitting. */
#define RATE_MATCH_CRS 2
/* The MAC is programmed with a sufficiently-large IPG. */
#define RATE_MATCH_OPEN_LOOP 3
/* Which connector port. */
#define PORT_TP 0x00
#define PORT_AUI 0x01
@ -2037,8 +2100,8 @@ enum ethtool_reset_flags {
* reported consistently by PHYLIB. Read-only.
* @master_slave_cfg: Master/slave port mode.
* @master_slave_state: Master/slave port state.
* @rate_matching: Rate adaptation performed by the PHY
* @reserved: Reserved for future use; see the note on reserved space.
* @reserved1: Reserved for future use; see the note on reserved space.
* @link_mode_masks: Variable length bitmaps.
*
* If autonegotiation is disabled, the speed and @duplex represent the
@ -2089,13 +2152,13 @@ struct ethtool_link_settings {
__u8 transceiver;
__u8 master_slave_cfg;
__u8 master_slave_state;
__u8 reserved1[1];
__u8 rate_matching;
__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];
* __u32 map_lp_advertising[link_mode_masks_nwords];
*/
};
#endif /* _UAPI_LINUX_ETHTOOL_H */
#endif /* _LINUX_ETHTOOL_H */