netfilter: Replace zero-length array with flexible-array member
Subsystems (4)
PATCH 1/1 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 76497732932f ("cxgb3/l2t: Fix undefined behaviour")
--- include/linux/netfilter/ipset/ip_set.h | 2 +- include/linux/netfilter/x_tables.h | 8 ++++---- include/linux/netfilter_arp/arp_tables.h | 2 +- include/linux/netfilter_bridge/ebtables.h | 2 +- include/linux/netfilter_ipv4/ip_tables.h | 2 +- include/linux/netfilter_ipv6/ip6_tables.h | 2 +- include/net/netfilter/nf_conntrack_extend.h | 2 +- include/net/netfilter/nf_conntrack_timeout.h | 2 +- include/net/netfilter/nf_tables.h | 6 +++--- include/uapi/linux/netfilter_bridge/ebt_among.h | 2 +- net/bridge/netfilter/ebtables.c | 2 +- net/ipv4/netfilter/arp_tables.c | 4 ++-- net/ipv4/netfilter/ip_tables.c | 4 ++-- net/ipv6/netfilter/ip6_tables.c | 4 ++-- net/netfilter/ipset/ip_set_bitmap_ip.c | 2 +- net/netfilter/ipset/ip_set_bitmap_ipmac.c | 2 +- net/netfilter/ipset/ip_set_bitmap_port.c | 2 +- net/netfilter/ipset/ip_set_hash_gen.h | 4 ++-- net/netfilter/nfnetlink_acct.c | 2 +- net/netfilter/nft_set_pipapo.c | 2 +- net/netfilter/xt_hashlimit.c | 2 +- net/netfilter/xt_recent.c | 4 ++-- 22 files changed, 32 insertions(+), 32 deletions(-)
include/linux/netfilter/ipset/ip_set.h +1 -1
@@ -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 {
include/linux/netfilter/x_tables.h +4 -4
@@ -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 {
include/linux/netfilter_arp/arp_tables.h +1 -1
@@ -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 *
include/linux/netfilter_bridge/ebtables.h +1 -1
@@ -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 {
include/linux/netfilter_ipv4/ip_tables.h +1 -1
@@ -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 */
include/linux/netfilter_ipv6/ip6_tables.h +1 -1
@@ -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 *
include/net/netfilter/nf_conntrack_extend.h +1 -1
@@ -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)
include/net/netfilter/nf_conntrack_timeout.h +1 -1
@@ -14,7 +14,7 @@struct nf_ct_timeout {__u16 l3num;const struct nf_conntrack_l4proto *l4proto; -char data[0 ]; +char data[]; };struct ctnl_timeout {
include/net/netfilter/nf_tables.h +3 -3
@@ -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[]; };/**
@@ -572,7 +572,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)
@@ -1385,7 +1385,7 @@ struct nft_trans {int msg_type;bool put_net;struct nft_ctx ctx; -char data[0 ]; +char data[]; };struct nft_trans_rule {
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) \
net/bridge/netfilter/ebtables.c +1 -1
@@ -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 */
net/ipv4/netfilter/arp_tables.c +2 -2
@@ -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,
net/ipv4/netfilter/ip_tables.c +2 -2
@@ -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
net/ipv6/netfilter/ip6_tables.c +2 -2
@@ -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
net/netfilter/ipset/ip_set_bitmap_ip.c +1 -1
@@ -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)) ; };
net/netfilter/ipset/ip_set_bitmap_ipmac.c +1 -1
@@ -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)) ; };
net/netfilter/ipset/ip_set_bitmap_port.c +1 -1
@@ -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)) ; };
net/netfilter/ipset/ip_set_hash_gen.h +2 -2
@@ -68,7 +68,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)) ; };
@@ -77,7 +77,7 @@ struct htable {atomic_t ref;/* References for resizing */ atomic_t uref;/* References for dumping */ u8 htable_bits;/* size of hash table == 2^htable_bits */ -struct hbucket __rcu *bucket[0 ];/* hashtable buckets */ +struct hbucket __rcu *bucket[];/* hashtable buckets */ };#define hbucket (h, i) ((h)->bucket[i])
net/netfilter/nfnetlink_acct.c +1 -1
@@ -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 {
net/netfilter/nft_set_pipapo.c +1 -1
@@ -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 */
net/netfilter/xt_hashlimit.c +1 -1
@@ -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
net/netfilter/xt_recent.c +2 -2
@@ -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 {
Signature · 1 line
2.25.0
Applied, thanks.
Quoted 2 lines · Pablo Neira Ayuso
Applied, thanks.
Thanks, Pablo.
--
Gustavo