]> git.baikalelectronics.ru Git - kernel.git/commitdiff
netfilter: Replace zero-length array with flexible-array member
authorGustavo A. R. Silva <gustavo@embeddedor.com>
Thu, 20 Feb 2020 13:59:14 +0000 (07:59 -0600)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 15 Mar 2020 14:20:16 +0000 (15:20 +0100)
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 80c49dd975f4 ("cxgb3/l2t: Fix undefined behaviour")

Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
22 files changed:
include/linux/netfilter/ipset/ip_set.h
include/linux/netfilter/x_tables.h
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_bridge/ebtables.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
include/net/netfilter/nf_conntrack_extend.h
include/net/netfilter/nf_conntrack_timeout.h
include/net/netfilter/nf_tables.h
include/uapi/linux/netfilter_bridge/ebt_among.h
net/bridge/netfilter/ebtables.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv6/netfilter/ip6_tables.c
net/netfilter/ipset/ip_set_bitmap_ip.c
net/netfilter/ipset/ip_set_bitmap_ipmac.c
net/netfilter/ipset/ip_set_bitmap_port.c
net/netfilter/ipset/ip_set_hash_gen.h
net/netfilter/nfnetlink_acct.c
net/netfilter/nft_set_pipapo.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_recent.c

index 5448c8b443dbf52aeac423ee987d19bb63b23e76..ab192720e2d6635f8e82bb6eeaaa96a5b0c47a26 100644 (file)
@@ -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 {
index 1b261c51b3a3a4467174eb12d2326048b0b6231c..5da88451853b28a92e040b42a7d50f4b34b33d14 100644 (file)
@@ -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 {
index e98028f00e47921824aac7ca28a6b9317ad76cd9..7d3537c40ec95a0bdb4b57f47d0f3b03bd62a2e2 100644 (file)
@@ -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 *
index 162f59d0d17a282adf24c263e5de0e3a1a658ec9..2f5c4e6ecd8a4c52ac7627bbd059cff79b87e55c 100644 (file)
@@ -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 {
index e9e1ed74cdf1ec0d6afdca976b073d9881dc27f9..b394bd4f68a34f4e0bda6b2d86ea5691124c9fc9 100644 (file)
@@ -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 */
index 78ab959c4575448e0dca5af9a2dc80617535446f..8225f7821a29fbb920d79b7b351e2a8c32ce1f51 100644 (file)
@@ -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 *
index 5ae5295aa46d998e5e63995a5a2a7d1790cfe3f2..e1e588387103d904e402700e56e963cdc9dd453a 100644 (file)
@@ -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)
index 6dd72396f5344d66ae2bc2bac19d57dccd276591..659b0ea25b4d42a9c775b1dd82f71485a3f81a62 100644 (file)
@@ -14,7 +14,7 @@
 struct nf_ct_timeout {
        __u16                   l3num;
        const struct nf_conntrack_l4proto *l4proto;
-       char                    data[0];
+       char                    data[];
 };
 
 struct ctnl_timeout {
index d913cdb6a27becd127462e130336edb9654d201d..01f48b5e6bf2e9f5a2b42d1b95937ba509c16445 100644 (file)
@@ -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 {
index 9acf757bc1f79328c8693b1edac37d1b36b8d225..73b26a280c4fd7e3db4bfde98b4daee70d699a7c 100644 (file)
@@ -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) \
index e1256e03a9a86b5b1249895a0627f7fbfa8e3386..78db58c7aec2eafffa174ffa4c503c68f13bc24c 100644 (file)
@@ -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 */
index f1f78a742b36a18962a7a66884607e2aaa0a28bb..b167f4a5b684534d83fc16179703cf4a16e366ea 100644 (file)
@@ -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,
index 10b91ebdf2131168bd70641072557c8564193d1f..c2670eaa74e6c4401ab73de0df64268c0aa73b72 100644 (file)
@@ -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
index c973ace208c513a2db8c52c71f184193a89c34e9..e27393498ecbff3bd4bd72d77da77d0e8564c6f2 100644 (file)
@@ -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
index 0a2196f591064e68754b34548ff614d61a3d44e5..486959f70cf313b44b06fdaffef6827fbe04eaba 100644 (file)
@@ -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));
 };
 
index 739e343efaf63193a23666e52b615fc40658f681..2310a316e0affc69676062f7d984126e6a0b8e83 100644 (file)
@@ -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));
 };
 
index b49978dd810dcb7794e4ae6c760adaff0f9fb200..e56ced66f202d6d8b6e913f0349a9991583d4014 100644 (file)
@@ -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));
 };
 
index e52d7b7597a0d8f3d6cfed5d2af6544ae1ad2e5d..1ee43752d6d3ccb1eae1684369a8be5ea5b96656 100644 (file)
@@ -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])
index 2481470dec368efc1206dcfdfecb919855459998..5827117f26356054c75c5204645ba1fb0c301668 100644 (file)
@@ -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 {
index d752a39b97d6ded9dd8ba42e60e2028424d462f6..26395c8188b1d7db5dbbcd8f36a738497608a68e 100644 (file)
@@ -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 */
index 8c835ad637290efc7505bcfd64507c731a94e364..9c5cfd74a0ee488e9e996c8892cf9e08ddcdc1c3 100644 (file)
@@ -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
index 225a7ab6d79a9480b70ded6dc4a774e0c7b9a409..19bef176145eb9561261489d4b4c1b9b688231db 100644 (file)
@@ -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 {