netfilter: Replace zero-length array with flexible-array member
The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to declare
variable-length types such as these ones is a flexible array member[1][2],
introduced in C99:
struct foo {
int stuff;
struct boo array[];
};
By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by
this change:
"Flexible array members have incomplete type, and so the sizeof operator
may not be applied. As a quirk of the original implementation of
zero-length arrays, sizeof evaluates to zero."[1]
Lastly, fix checkpatch.pl warning
WARNING: __aligned(size) is preferred over __attribute__((aligned(size)))
in net/bridge/netfilter/ebtables.c
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 7649773293
("cxgb3/l2t: Fix undefined behaviour")
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
eb9d7af3b7
commit
6daf141401
@ -98,7 +98,7 @@ struct ip_set_counter {
|
||||
|
||||
struct ip_set_comment_rcu {
|
||||
struct rcu_head rcu;
|
||||
char str[0];
|
||||
char str[];
|
||||
};
|
||||
|
||||
struct ip_set_comment {
|
||||
|
@ -264,7 +264,7 @@ struct xt_table_info {
|
||||
unsigned int stacksize;
|
||||
void ***jumpstack;
|
||||
|
||||
unsigned char entries[0] __aligned(8);
|
||||
unsigned char entries[] __aligned(8);
|
||||
};
|
||||
|
||||
int xt_register_target(struct xt_target *target);
|
||||
@ -464,7 +464,7 @@ struct compat_xt_entry_match {
|
||||
} kernel;
|
||||
u_int16_t match_size;
|
||||
} u;
|
||||
unsigned char data[0];
|
||||
unsigned char data[];
|
||||
};
|
||||
|
||||
struct compat_xt_entry_target {
|
||||
@ -480,7 +480,7 @@ struct compat_xt_entry_target {
|
||||
} kernel;
|
||||
u_int16_t target_size;
|
||||
} u;
|
||||
unsigned char data[0];
|
||||
unsigned char data[];
|
||||
};
|
||||
|
||||
/* FIXME: this works only on 32 bit tasks
|
||||
@ -494,7 +494,7 @@ struct compat_xt_counters {
|
||||
struct compat_xt_counters_info {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
compat_uint_t num_counters;
|
||||
struct compat_xt_counters counters[0];
|
||||
struct compat_xt_counters counters[];
|
||||
};
|
||||
|
||||
struct _compat_xt_align {
|
||||
|
@ -67,7 +67,7 @@ struct compat_arpt_entry {
|
||||
__u16 next_offset;
|
||||
compat_uint_t comefrom;
|
||||
struct compat_xt_counters counters;
|
||||
unsigned char elems[0];
|
||||
unsigned char elems[];
|
||||
};
|
||||
|
||||
static inline struct xt_entry_target *
|
||||
|
@ -85,7 +85,7 @@ struct ebt_table_info {
|
||||
/* room to maintain the stack used for jumping from and into udc */
|
||||
struct ebt_chainstack **chainstack;
|
||||
char *entries;
|
||||
struct ebt_counter counters[0] ____cacheline_aligned;
|
||||
struct ebt_counter counters[] ____cacheline_aligned;
|
||||
};
|
||||
|
||||
struct ebt_table {
|
||||
|
@ -76,7 +76,7 @@ struct compat_ipt_entry {
|
||||
__u16 next_offset;
|
||||
compat_uint_t comefrom;
|
||||
struct compat_xt_counters counters;
|
||||
unsigned char elems[0];
|
||||
unsigned char elems[];
|
||||
};
|
||||
|
||||
/* Helper functions */
|
||||
|
@ -43,7 +43,7 @@ struct compat_ip6t_entry {
|
||||
__u16 next_offset;
|
||||
compat_uint_t comefrom;
|
||||
struct compat_xt_counters counters;
|
||||
unsigned char elems[0];
|
||||
unsigned char elems[];
|
||||
};
|
||||
|
||||
static inline struct xt_entry_target *
|
||||
|
@ -45,7 +45,7 @@ enum nf_ct_ext_id {
|
||||
struct nf_ct_ext {
|
||||
u8 offset[NF_CT_EXT_NUM];
|
||||
u8 len;
|
||||
char data[0];
|
||||
char data[];
|
||||
};
|
||||
|
||||
static inline bool __nf_ct_ext_exist(const struct nf_ct_ext *ext, u8 id)
|
||||
|
@ -14,7 +14,7 @@
|
||||
struct nf_ct_timeout {
|
||||
__u16 l3num;
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
char data[0];
|
||||
char data[];
|
||||
};
|
||||
|
||||
struct ctnl_timeout {
|
||||
|
@ -224,7 +224,7 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
|
||||
*/
|
||||
struct nft_userdata {
|
||||
u8 len;
|
||||
unsigned char data[0];
|
||||
unsigned char data[];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -565,7 +565,7 @@ struct nft_set_ext_tmpl {
|
||||
struct nft_set_ext {
|
||||
u8 genmask;
|
||||
u8 offset[NFT_SET_EXT_NUM];
|
||||
char data[0];
|
||||
char data[];
|
||||
};
|
||||
|
||||
static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl)
|
||||
@ -1375,7 +1375,7 @@ struct nft_trans {
|
||||
int msg_type;
|
||||
bool put_net;
|
||||
struct nft_ctx ctx;
|
||||
char data[0];
|
||||
char data[];
|
||||
};
|
||||
|
||||
struct nft_trans_rule {
|
||||
|
@ -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) \
|
||||
|
@ -1561,7 +1561,7 @@ struct compat_ebt_entry_mwt {
|
||||
compat_uptr_t ptr;
|
||||
} u;
|
||||
compat_uint_t match_size;
|
||||
compat_uint_t data[0] __attribute__ ((aligned (__alignof__(struct compat_ebt_replace))));
|
||||
compat_uint_t data[] __aligned(__alignof__(struct compat_ebt_replace));
|
||||
};
|
||||
|
||||
/* account for possible padding between match_size and ->data */
|
||||
|
@ -1057,7 +1057,7 @@ struct compat_arpt_replace {
|
||||
u32 underflow[NF_ARP_NUMHOOKS];
|
||||
u32 num_counters;
|
||||
compat_uptr_t counters;
|
||||
struct compat_arpt_entry entries[0];
|
||||
struct compat_arpt_entry entries[];
|
||||
};
|
||||
|
||||
static inline void compat_release_entry(struct compat_arpt_entry *e)
|
||||
@ -1383,7 +1383,7 @@ static int compat_copy_entries_to_user(unsigned int total_size,
|
||||
struct compat_arpt_get_entries {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
compat_uint_t size;
|
||||
struct compat_arpt_entry entrytable[0];
|
||||
struct compat_arpt_entry entrytable[];
|
||||
};
|
||||
|
||||
static int compat_get_entries(struct net *net,
|
||||
|
@ -1211,7 +1211,7 @@ struct compat_ipt_replace {
|
||||
u32 underflow[NF_INET_NUMHOOKS];
|
||||
u32 num_counters;
|
||||
compat_uptr_t counters; /* struct xt_counters * */
|
||||
struct compat_ipt_entry entries[0];
|
||||
struct compat_ipt_entry entries[];
|
||||
};
|
||||
|
||||
static int
|
||||
@ -1562,7 +1562,7 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
|
||||
struct compat_ipt_get_entries {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
compat_uint_t size;
|
||||
struct compat_ipt_entry entrytable[0];
|
||||
struct compat_ipt_entry entrytable[];
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -1227,7 +1227,7 @@ struct compat_ip6t_replace {
|
||||
u32 underflow[NF_INET_NUMHOOKS];
|
||||
u32 num_counters;
|
||||
compat_uptr_t counters; /* struct xt_counters * */
|
||||
struct compat_ip6t_entry entries[0];
|
||||
struct compat_ip6t_entry entries[];
|
||||
};
|
||||
|
||||
static int
|
||||
@ -1571,7 +1571,7 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
|
||||
struct compat_ip6t_get_entries {
|
||||
char name[XT_TABLE_MAXNAMELEN];
|
||||
compat_uint_t size;
|
||||
struct compat_ip6t_entry entrytable[0];
|
||||
struct compat_ip6t_entry entrytable[];
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -46,7 +46,7 @@ struct bitmap_ip {
|
||||
u8 netmask; /* subnet netmask */
|
||||
struct timer_list gc; /* garbage collection */
|
||||
struct ip_set *set; /* attached to this ip_set */
|
||||
unsigned char extensions[0] /* data extensions */
|
||||
unsigned char extensions[] /* data extensions */
|
||||
__aligned(__alignof__(u64));
|
||||
};
|
||||
|
||||
|
@ -49,7 +49,7 @@ struct bitmap_ipmac {
|
||||
size_t memsize; /* members size */
|
||||
struct timer_list gc; /* garbage collector */
|
||||
struct ip_set *set; /* attached to this ip_set */
|
||||
unsigned char extensions[0] /* MAC + data extensions */
|
||||
unsigned char extensions[] /* MAC + data extensions */
|
||||
__aligned(__alignof__(u64));
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct bitmap_port {
|
||||
size_t memsize; /* members size */
|
||||
struct timer_list gc; /* garbage collection */
|
||||
struct ip_set *set; /* attached to this ip_set */
|
||||
unsigned char extensions[0] /* data extensions */
|
||||
unsigned char extensions[] /* data extensions */
|
||||
__aligned(__alignof__(u64));
|
||||
};
|
||||
|
||||
|
@ -76,7 +76,7 @@ struct hbucket {
|
||||
DECLARE_BITMAP(used, AHASH_MAX_TUNED);
|
||||
u8 size; /* size of the array */
|
||||
u8 pos; /* position of the first free entry */
|
||||
unsigned char value[0] /* the array of the values */
|
||||
unsigned char value[] /* the array of the values */
|
||||
__aligned(__alignof__(u64));
|
||||
};
|
||||
|
||||
@ -109,7 +109,7 @@ struct htable {
|
||||
u8 htable_bits; /* size of hash table == 2^htable_bits */
|
||||
u32 maxelem; /* Maxelem per region */
|
||||
struct ip_set_region *hregion; /* Region locks and ext sizes */
|
||||
struct hbucket __rcu *bucket[0]; /* hashtable buckets */
|
||||
struct hbucket __rcu *bucket[]; /* hashtable buckets */
|
||||
};
|
||||
|
||||
#define hbucket(h, i) ((h)->bucket[i])
|
||||
|
@ -33,7 +33,7 @@ struct nf_acct {
|
||||
refcount_t refcnt;
|
||||
char name[NFACCT_NAME_MAX];
|
||||
struct rcu_head rcu_head;
|
||||
char data[0];
|
||||
char data[];
|
||||
};
|
||||
|
||||
struct nfacct_filter {
|
||||
|
@ -433,7 +433,7 @@ struct nft_pipapo_match {
|
||||
unsigned long * __percpu *scratch;
|
||||
size_t bsize_max;
|
||||
struct rcu_head rcu;
|
||||
struct nft_pipapo_field f[0];
|
||||
struct nft_pipapo_field f[];
|
||||
};
|
||||
|
||||
/* Current working bitmap index, toggled between field matches */
|
||||
|
@ -132,7 +132,7 @@ struct xt_hashlimit_htable {
|
||||
const char *name;
|
||||
struct net *net;
|
||||
|
||||
struct hlist_head hash[0]; /* hashtable itself */
|
||||
struct hlist_head hash[]; /* hashtable itself */
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -71,7 +71,7 @@ struct recent_entry {
|
||||
u_int8_t ttl;
|
||||
u_int8_t index;
|
||||
u_int16_t nstamps;
|
||||
unsigned long stamps[0];
|
||||
unsigned long stamps[];
|
||||
};
|
||||
|
||||
struct recent_table {
|
||||
@ -82,7 +82,7 @@ struct recent_table {
|
||||
unsigned int entries;
|
||||
u8 nstamps_max_mask;
|
||||
struct list_head lru_list;
|
||||
struct list_head iphash[0];
|
||||
struct list_head iphash[];
|
||||
};
|
||||
|
||||
struct recent_net {
|
||||
|
Loading…
Reference in New Issue
Block a user