Hi David, The following patchset contains Netfilter fixes for you net tree, they are: 1) There was a race condition between parallel save/swap and delete, which resulted a kernel crash due to the increase ref for save, swap, wrong ref decrease operations. Reported and fixed by Vishwanath Pai. 2) OVS should call into CT NAT for packets of new expected connections only when the conntrack state is persisted with the 'commit' option to the OVS CT action. From Jarno Rajahalme. 3) Resolve kconfig dependencies with new OVS NAT support. From Arnd Bergmann. 4) Early validation of entry->target_offset to make sure it doesn't take us out from the blob, from Florian Westphal. 5) Again early validation of entry->next_offset to make sure it doesn't take out from the blob, also from Florian. 6) Check that entry->target_offset is always of of sizeof(struct xt_entry) for unconditional entries, when checking both from check_underflow() and when checking for loops in mark_source_chains(), again from Florian. 7) Fix inconsistent behaviour in nfnetlink_queue when NFQA_CFG_F_FAIL_OPEN is set and netlink_unicast() fails due to buffer overrun, we have to reinject the packet as the user expects. 8) Enforce nul-terminated table names from getsockopt GET_ENTRIES requests. 9) Don't assume skb->sk is set from nft_bridge_reject and synproxy, this fixes a recent update of the code to namespaceify ip_default_ttl, patch from Liping Zhang. This batch comes with four patches to validate x_tables blobs coming from userspace. CONFIG_USERNS exposes the x_tables interface to unpriviledged users and to be honest this interface never received the attention for this move away from the CAP_NET_ADMIN domain. Florian is working on another round with more patches with more sanity checks, so expect a bit more Netfilter fixes in this development cycle than usual. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit d7be81a5916bdb1d904803958e5991a16f7ae4b2: ravb: fix software timestamping (2016-03-27 22:41:37 -0400) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 29421198c3a860092e27c2ad8499dfe603398817: netfilter: ipv4: fix NULL dereference (2016-03-28 17:59:29 +0200) ---------------------------------------------------------------- Arnd Bergmann (1): openvswitch: call only into reachable nf-nat code Florian Westphal (3): netfilter: x_tables: validate e->target_offset early netfilter: x_tables: make sure e->next_offset covers remaining blob size netfilter: x_tables: fix unconditional helper Jarno Rajahalme (1): openvswitch: Fix checking for new expected connections. Liping Zhang (1): netfilter: ipv4: fix NULL dereference Pablo Neira Ayuso (2): netfilter: nfnetlink_queue: honor NFQA_CFG_F_FAIL_OPEN when netlink unicast fails netfilter: x_tables: enforce nul-terminated table name from getsockopt GET_ENTRIES Vishwanath Pai (1): netfilter: ipset: fix race condition in ipset save, swap and delete include/linux/netfilter/ipset/ip_set.h | 4 +++ net/bridge/netfilter/ebtables.c | 4 +++ net/bridge/netfilter/nft_reject_bridge.c | 20 ++++++------ net/ipv4/netfilter/arp_tables.c | 43 +++++++++++++------------ net/ipv4/netfilter/ip_tables.c | 48 ++++++++++++++-------------- net/ipv4/netfilter/ipt_SYNPROXY.c | 54 +++++++++++++++++--------------- net/ipv6/netfilter/ip6_tables.c | 48 ++++++++++++++-------------- net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- net/netfilter/ipset/ip_set_core.c | 33 ++++++++++++++++--- net/netfilter/ipset/ip_set_hash_gen.h | 2 +- net/netfilter/ipset/ip_set_list_set.c | 2 +- net/netfilter/nfnetlink_queue.c | 7 ++++- net/openvswitch/Kconfig | 4 ++- net/openvswitch/conntrack.c | 21 +++++++------ 14 files changed, 170 insertions(+), 122 deletions(-)
From: Vishwanath Pai <vpai@akamai.com> This fix adds a new reference counter (ref_netlink) for the struct ip_set. The other reference counter (ref) can be swapped out by ip_set_swap and we need a separate counter to keep track of references for netlink events like dump. Using the same ref counter for dump causes a race condition which can be demonstrated by the following script: ipset create hash_ip1 hash:ip family inet hashsize 1024 maxelem 500000 \ counters ipset create hash_ip2 hash:ip family inet hashsize 300000 maxelem 500000 \ counters ipset create hash_ip3 hash:ip family inet hashsize 1024 maxelem 500000 \ counters ipset save & ipset swap hash_ip3 hash_ip2 ipset destroy hash_ip3 /* will crash the machine */ Swap will exchange the values of ref so destroy will see ref = 0 instead of ref = 1. With this fix in place swap will not succeed because ipset save still has ref_netlink on the set (ip_set_swap doesn't swap ref_netlink). Both delete and swap will error out if ref_netlink != 0 on the set. Note: The changes to *_head functions is because previously we would increment ref whenever we called these functions, we don't do that anymore. Reviewed-by: Joshua Hunt <johunt@akamai.com> Signed-off-by: Vishwanath Pai <vpai@akamai.com> Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/linux/netfilter/ipset/ip_set.h | 4 ++++ net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- net/netfilter/ipset/ip_set_core.c | 33 ++++++++++++++++++++++++++++----- net/netfilter/ipset/ip_set_hash_gen.h | 2 +- net/netfilter/ipset/ip_set_list_set.c | 2 +- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index 0e1f433..f48b8a6 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -234,6 +234,10 @@ struct ip_set { spinlock_t lock; /* References to the set */ u32 ref; + /* References to the set for netlink events like dump, + * ref can be swapped out by ip_set_swap + */ + u32 ref_netlink; /* The core set type */ struct ip_set_type *type; /* The type variant doing the real job */ diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h index b0bc475..2e8e7e5 100644 --- a/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/net/netfilter/ipset/ip_set_bitmap_gen.h @@ -95,7 +95,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) if (!nested) goto nla_put_failure; if (mtype_do_head(skb, map) || - nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || + nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) goto nla_put_failure; if (unlikely(ip_set_put_flags(skb, set))) diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 7e6568c..a748b0c 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -497,6 +497,26 @@ __ip_set_put(struct ip_set *set) write_unlock_bh(&ip_set_ref_lock); } +/* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need + * a separate reference counter + */ +static inline void +__ip_set_get_netlink(struct ip_set *set) +{ + write_lock_bh(&ip_set_ref_lock); + set->ref_netlink++; + write_unlock_bh(&ip_set_ref_lock); +} + +static inline void +__ip_set_put_netlink(struct ip_set *set) +{ + write_lock_bh(&ip_set_ref_lock); + BUG_ON(set->ref_netlink == 0); + set->ref_netlink--; + write_unlock_bh(&ip_set_ref_lock); +} + /* Add, del and test set entries from kernel. * * The set behind the index must exist and must be referenced @@ -1002,7 +1022,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, if (!attr[IPSET_ATTR_SETNAME]) { for (i = 0; i < inst->ip_set_max; i++) { s = ip_set(inst, i); - if (s && s->ref) { + if (s && (s->ref || s->ref_netlink)) { ret = -IPSET_ERR_BUSY; goto out; } @@ -1024,7 +1044,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, if (!s) { ret = -ENOENT; goto out; - } else if (s->ref) { + } else if (s->ref || s->ref_netlink) { ret = -IPSET_ERR_BUSY; goto out; } @@ -1171,6 +1191,9 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb, from->family == to->family)) return -IPSET_ERR_TYPE_MISMATCH; + if (from->ref_netlink || to->ref_netlink) + return -EBUSY; + strncpy(from_name, from->name, IPSET_MAXNAMELEN); strncpy(from->name, to->name, IPSET_MAXNAMELEN); strncpy(to->name, from_name, IPSET_MAXNAMELEN); @@ -1206,7 +1229,7 @@ ip_set_dump_done(struct netlink_callback *cb) if (set->variant->uref) set->variant->uref(set, cb, false); pr_debug("release set %s\n", set->name); - __ip_set_put_byindex(inst, index); + __ip_set_put_netlink(set); } return 0; } @@ -1328,7 +1351,7 @@ dump_last: if (!cb->args[IPSET_CB_ARG0]) { /* Start listing: make sure set won't be destroyed */ pr_debug("reference set\n"); - set->ref++; + set->ref_netlink++; } write_unlock_bh(&ip_set_ref_lock); nlh = start_msg(skb, NETLINK_CB(cb->skb).portid, @@ -1396,7 +1419,7 @@ release_refcount: if (set->variant->uref) set->variant->uref(set, cb, false); pr_debug("release set %s\n", set->name); - __ip_set_put_byindex(inst, index); + __ip_set_put_netlink(set); cb->args[IPSET_CB_ARG0] = 0; } out: diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index e5336ab..d32fd6b 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -1082,7 +1082,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask)) goto nla_put_failure; #endif - if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || + if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) goto nla_put_failure; if (unlikely(ip_set_put_flags(skb, set))) diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 24c6c19..a2a89e4 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -458,7 +458,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb) if (!nested) goto nla_put_failure; if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || - nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || + nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(sizeof(*map) + n * set->dsize))) goto nla_put_failure; -- 2.1.4
From: Jarno Rajahalme <jarno@ovn.org> OVS should call into CT NAT for packets of new expected connections only when the conntrack state is persisted with the 'commit' option to the OVS CT action. The test for this condition is doubly wrong, as the CT status field is ANDed with the bit number (IPS_EXPECTED_BIT) rather than the mask (IPS_EXPECTED), and due to the wrong assumption that the expected bit would apply only for the first (i.e., 'new') packet of a connection, while in fact the expected bit remains on for the lifetime of an expected connection. The 'ctinfo' value IP_CT_RELATED derived from the ct status can be used instead, as it is only ever applicable to the 'new' packets of the expected connection. Fixes: 05752523e565 ('openvswitch: Interface with NAT.') Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/openvswitch/conntrack.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index dc5eb29..47f7c62 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -664,11 +664,12 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key, /* Determine NAT type. * Check if the NAT type can be deduced from the tracked connection. - * Make sure expected traffic is NATted only when committing. + * Make sure new expected connections (IP_CT_RELATED) are NATted only + * when committing. */ if (info->nat & OVS_CT_NAT && ctinfo != IP_CT_NEW && ct->status & IPS_NAT_MASK && - (!(ct->status & IPS_EXPECTED_BIT) || info->commit)) { + (ctinfo != IP_CT_RELATED || info->commit)) { /* NAT an established or related connection like before. */ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) /* This is the REPLY direction for a connection -- 2.1.4
From: Arnd Bergmann <arnd@arndb.de> The openvswitch code has gained support for calling into the nf-nat-ipv4/ipv6 modules, however those can be loadable modules in a configuration in which openvswitch is built-in, leading to link errors: net/built-in.o: In function `__ovs_ct_lookup': :(.text+0x2cc2c8): undefined reference to `nf_nat_icmp_reply_translation' :(.text+0x2cc66c): undefined reference to `nf_nat_icmpv6_reply_translation' The dependency on (!NF_NAT || NF_NAT) prevents similar issues, but NF_NAT is set to 'y' if any of the symbols selecting it are built-in, but the link error happens when any of them are modular. A second issue is that even if CONFIG_NF_NAT_IPV6 is built-in, CONFIG_NF_NAT_IPV4 might be completely disabled. This is unlikely to be useful in practice, but the driver currently only handles IPv6 being optional. This patch improves the Kconfig dependency so that openvswitch cannot be built-in if either of the two other symbols are set to 'm', and it replaces the incorrect #ifdef in ovs_ct_nat_execute() with two "if (IS_ENABLED())" checks that should catch all corner cases also make the code more readable. The same #ifdef exists ovs_ct_nat_to_attr(), where it does not cause a link error, but for consistency I'm changing it the same way. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Fixes: 05752523e565 ("openvswitch: Interface with NAT.") Acked-by: Joe Stringer <joe@ovn.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/openvswitch/Kconfig | 4 +++- net/openvswitch/conntrack.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 234a733..ce94729 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig @@ -7,7 +7,9 @@ config OPENVSWITCH depends on INET depends on !NF_CONNTRACK || \ (NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \ - (!NF_NAT || NF_NAT))) + (!NF_NAT || NF_NAT) && \ + (!NF_NAT_IPV4 || NF_NAT_IPV4) && \ + (!NF_NAT_IPV6 || NF_NAT_IPV6))) select LIBCRC32C select MPLS select NET_MPLS_GSO diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index 47f7c62..3797879 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -535,14 +535,15 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, switch (ctinfo) { case IP_CT_RELATED: case IP_CT_RELATED_REPLY: - if (skb->protocol == htons(ETH_P_IP) && + if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && + skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->protocol == IPPROTO_ICMP) { if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, hooknum)) err = NF_DROP; goto push; -#if IS_ENABLED(CONFIG_NF_NAT_IPV6) - } else if (skb->protocol == htons(ETH_P_IPV6)) { + } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && + skb->protocol == htons(ETH_P_IPV6)) { __be16 frag_off; u8 nexthdr = ipv6_hdr(skb)->nexthdr; int hdrlen = ipv6_skip_exthdr(skb, @@ -557,7 +558,6 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, err = NF_DROP; goto push; } -#endif } /* Non-ICMP, fall thru to initialize if needed. */ case IP_CT_NEW: @@ -1239,7 +1239,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, } if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { - if (info->family == NFPROTO_IPV4) { + if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && + info->family == NFPROTO_IPV4) { if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN, info->range.min_addr.ip) || (info->range.max_addr.ip @@ -1247,8 +1248,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX, info->range.max_addr.ip)))) return false; -#if IS_ENABLED(CONFIG_NF_NAT_IPV6) - } else if (info->family == NFPROTO_IPV6) { + } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && + info->family == NFPROTO_IPV6) { if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN, &info->range.min_addr.in6) || (memcmp(&info->range.max_addr.in6, @@ -1257,7 +1258,6 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX, &info->range.max_addr.in6)))) return false; -#endif } else { return false; } -- 2.1.4
From: Florian Westphal <fw@strlen.de> We should check that e->target_offset is sane before mark_source_chains gets called since it will fetch the target entry for loop detection. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/ipv4/netfilter/arp_tables.c | 17 ++++++++--------- net/ipv4/netfilter/ip_tables.c | 17 ++++++++--------- net/ipv6/netfilter/ip6_tables.c | 17 ++++++++--------- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index bf08192..830bbe8 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -474,14 +474,12 @@ next: return 1; } -static inline int check_entry(const struct arpt_entry *e, const char *name) +static inline int check_entry(const struct arpt_entry *e) { const struct xt_entry_target *t; - if (!arp_checkentry(&e->arp)) { - duprintf("arp_tables: arp check failed %p %s.\n", e, name); + if (!arp_checkentry(&e->arp)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) struct xt_target *target; int ret; - ret = check_entry(e, name); - if (ret) - return ret; - e->counters.pcnt = xt_percpu_counter_alloc(); if (IS_ERR_VALUE(e->counters.pcnt)) return -ENOMEM; @@ -576,6 +570,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { @@ -590,6 +585,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_ARP_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1246,7 +1245,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct arpt_entry *)e, name); + ret = check_entry((struct arpt_entry *)e); if (ret) return ret; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e53f8d6..1d72a3c 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -569,14 +569,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ipt_entry *e, const char *name) +check_entry(const struct ipt_entry *e) { const struct xt_entry_target *t; - if (!ip_checkentry(&e->ip)) { - duprintf("ip check failed %p %s.\n", e, name); + if (!ip_checkentry(&e->ip)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -666,10 +664,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - e->counters.pcnt = xt_percpu_counter_alloc(); if (IS_ERR_VALUE(e->counters.pcnt)) return -ENOMEM; @@ -741,6 +735,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { @@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1506,7 +1505,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ipt_entry *)e, name); + ret = check_entry((struct ipt_entry *)e); if (ret) return ret; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 84f9baf..26a5ad1 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -581,14 +581,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) } static int -check_entry(const struct ip6t_entry *e, const char *name) +check_entry(const struct ip6t_entry *e) { const struct xt_entry_target *t; - if (!ip6_checkentry(&e->ipv6)) { - duprintf("ip_tables: ip check failed %p %s.\n", e, name); + if (!ip6_checkentry(&e->ipv6)) return -EINVAL; - } if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) @@ -679,10 +677,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, struct xt_mtchk_param mtpar; struct xt_entry_match *ematch; - ret = check_entry(e, name); - if (ret) - return ret; - e->counters.pcnt = xt_percpu_counter_alloc(); if (IS_ERR_VALUE(e->counters.pcnt)) return -ENOMEM; @@ -753,6 +747,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, unsigned int valid_hooks) { unsigned int h; + int err; if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { @@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, return -EINVAL; } + err = check_entry(e); + if (err) + return err; + /* Check hooks & underflows */ for (h = 0; h < NF_INET_NUMHOOKS; h++) { if (!(valid_hooks & (1 << h))) @@ -1518,7 +1517,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, } /* For purposes of check_entry casting the compat entry is fine */ - ret = check_entry((struct ip6t_entry *)e, name); + ret = check_entry((struct ip6t_entry *)e); if (ret) return ret; -- 2.1.4
From: Florian Westphal <fw@strlen.de> Otherwise this function may read data beyond the ruleset blob. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/ipv4/netfilter/arp_tables.c | 6 ++++-- net/ipv4/netfilter/ip_tables.c | 6 ++++-- net/ipv6/netfilter/ip6_tables.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 830bbe8..51d4fe5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -573,7 +573,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, int err; if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || - (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { + (unsigned char *)e + sizeof(struct arpt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1232,7 +1233,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 1d72a3c..fb7694e 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -738,7 +738,8 @@ check_entry_size_and_hooks(struct ipt_entry *e, int err; if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || - (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { + (unsigned char *)e + sizeof(struct ipt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1492,7 +1493,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 26a5ad1..b248528f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -750,7 +750,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e, int err; if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || - (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { + (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p\n", e); return -EINVAL; } @@ -1504,7 +1505,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, duprintf("check_compat_entry_size_and_hooks %p\n", e); if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || - (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { + (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || + (unsigned char *)e + e->next_offset > limit) { duprintf("Bad offset %p, limit = %p\n", e, limit); return -EINVAL; } -- 2.1.4
From: Florian Westphal <fw@strlen.de> Ben Hawkes says: In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it is possible for a user-supplied ipt_entry structure to have a large next_offset field. This field is not bounds checked prior to writing a counter value at the supplied offset. Problem is that mark_source_chains should not have been called -- the rule doesn't have a next entry, so its supposed to return an absolute verdict of either ACCEPT or DROP. However, the function conditional() doesn't work as the name implies. It only checks that the rule is using wildcard address matching. However, an unconditional rule must also not be using any matches (no -m args). The underflow validator only checked the addresses, therefore passing the 'unconditional absolute verdict' test, while mark_source_chains also tested for presence of matches, and thus proceeeded to the next (not-existent) rule. Unify this so that all the callers have same idea of 'unconditional rule'. Reported-by: Ben Hawkes <hawkes@google.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/ipv4/netfilter/arp_tables.c | 18 +++++++++--------- net/ipv4/netfilter/ip_tables.c | 23 +++++++++++------------ net/ipv6/netfilter/ip6_tables.c | 23 +++++++++++------------ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 51d4fe5..a1bb5e7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -359,11 +359,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, } /* All zeroes == unconditional rule. */ -static inline bool unconditional(const struct arpt_arp *arp) +static inline bool unconditional(const struct arpt_entry *e) { static const struct arpt_arp uncond; - return memcmp(arp, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct arpt_entry) && + memcmp(&e->arp, &uncond, sizeof(uncond)) == 0; } /* Figures out from what hook each rule can be called: returns 0 if @@ -402,11 +403,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct arpt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && unconditional(&e->arp)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -551,7 +551,7 @@ static bool check_underflow(const struct arpt_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->arp)) + if (!unconditional(e)) return false; t = arpt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -598,9 +598,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index fb7694e..89b5d95 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) /* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ipt_ip *ip) +static inline bool unconditional(const struct ipt_entry *e) { static const struct ipt_ip uncond; - return memcmp(ip, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct ipt_entry) && + memcmp(&e->ip, &uncond, sizeof(uncond)) == 0; #undef FWINV } @@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, } else if (s == e) { (*rulenum)++; - if (s->target_offset == sizeof(struct ipt_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) == 0 && - t->verdict < 0 && - unconditional(&s->ip)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP_TRACE_COMMENT_POLICY] @@ -476,11 +476,10 @@ mark_source_chains(const struct xt_table_info *newinfo, e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct ipt_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && unconditional(&e->ip)) || - visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -715,7 +714,7 @@ static bool check_underflow(const struct ipt_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->ip)) + if (!unconditional(e)) return false; t = ipt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -763,9 +762,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index b248528f..541b59f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int offset) /* All zeroes == unconditional rule. */ /* Mildly perf critical (only if packet tracing is on) */ -static inline bool unconditional(const struct ip6t_ip6 *ipv6) +static inline bool unconditional(const struct ip6t_entry *e) { static const struct ip6t_ip6 uncond; - return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; + return e->target_offset == sizeof(struct ip6t_entry) && + memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; } static inline const struct xt_entry_target * @@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, } else if (s == e) { (*rulenum)++; - if (s->target_offset == sizeof(struct ip6t_entry) && + if (unconditional(s) && strcmp(t->target.u.kernel.target->name, XT_STANDARD_TARGET) == 0 && - t->verdict < 0 && - unconditional(&s->ipv6)) { + t->verdict < 0) { /* Tail of chains: STANDARD target (return/policy) */ *comment = *chainname == hookname ? comments[NF_IP6_TRACE_COMMENT_POLICY] @@ -488,11 +488,10 @@ mark_source_chains(const struct xt_table_info *newinfo, e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); /* Unconditional return/END. */ - if ((e->target_offset == sizeof(struct ip6t_entry) && + if ((unconditional(e) && (strcmp(t->target.u.user.name, XT_STANDARD_TARGET) == 0) && - t->verdict < 0 && - unconditional(&e->ipv6)) || visited) { + t->verdict < 0) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, @@ -727,7 +726,7 @@ static bool check_underflow(const struct ip6t_entry *e) const struct xt_entry_target *t; unsigned int verdict; - if (!unconditional(&e->ipv6)) + if (!unconditional(e)) return false; t = ip6t_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) @@ -775,9 +774,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, newinfo->hook_entry[h] = hook_entries[h]; if ((unsigned char *)e - base == underflows[h]) { if (!check_underflow(e)) { - pr_err("Underflows must be unconditional and " - "use the STANDARD target with " - "ACCEPT/DROP\n"); + pr_debug("Underflows must be unconditional and " + "use the STANDARD target with " + "ACCEPT/DROP\n"); return -EINVAL; } newinfo->underflow[h] = underflows[h]; -- 2.1.4
When netlink unicast fails to deliver the message to userspace, we should also check if the NFQA_CFG_F_FAIL_OPEN flag is set so we reinject the packet back to the stack. I think the user expects no packet drops when this flag is set due to queueing to userspace errors, no matter if related to the internal queue or when sending the netlink message to userspace. The userspace application will still get the ENOBUFS error via recvmsg() so the user still knows that, with the current configuration that is in place, the userspace application is not consuming the messages at the pace that the kernel needs. Reported-by: "Yigal Reiss (yreiss)" <yreiss@cisco.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Tested-by: "Yigal Reiss (yreiss)" <yreiss@cisco.com> --- net/netfilter/nfnetlink_queue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 7542999..cb5b630 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -582,7 +582,12 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue, /* nfnetlink_unicast will either free the nskb or add it to a socket */ err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT); if (err < 0) { - queue->queue_user_dropped++; + if (queue->flags & NFQA_CFG_F_FAIL_OPEN) { + failopen = 1; + err = 0; + } else { + queue->queue_user_dropped++; + } goto err_out_unlock; } -- 2.1.4
Make sure the table names via getsockopt GET_ENTRIES is nul-terminated in ebtables and all the x_tables variants and their respective compat code. Uncovered by KASAN. Reported-by: Baozeng Ding <sploving1@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/bridge/netfilter/ebtables.c | 4 ++++ net/ipv4/netfilter/arp_tables.c | 2 ++ net/ipv4/netfilter/ip_tables.c | 2 ++ net/ipv6/netfilter/ip6_tables.c | 2 ++ 4 files changed, 10 insertions(+) diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 67b2e27..8570bc7 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1521,6 +1521,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) if (copy_from_user(&tmp, user, sizeof(tmp))) return -EFAULT; + tmp.name[sizeof(tmp.name) - 1] = '\0'; + t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); if (!t) return ret; @@ -2332,6 +2334,8 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, if (copy_from_user(&tmp, user, sizeof(tmp))) return -EFAULT; + tmp.name[sizeof(tmp.name) - 1] = '\0'; + t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); if (!t) return ret; diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a1bb5e7..4133b0f 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -969,6 +969,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, sizeof(struct arpt_get_entries) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; t = xt_find_table_lock(net, NFPROTO_ARP, get.name); if (!IS_ERR_OR_NULL(t)) { @@ -1663,6 +1664,7 @@ static int compat_get_entries(struct net *net, *len, sizeof(get) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; xt_compat_lock(NFPROTO_ARP); t = xt_find_table_lock(net, NFPROTO_ARP, get.name); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 89b5d95..631c100 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1156,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, *len, sizeof(get) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; t = xt_find_table_lock(net, AF_INET, get.name); if (!IS_ERR_OR_NULL(t)) { @@ -1935,6 +1936,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, *len, sizeof(get) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; xt_compat_lock(AF_INET); t = xt_find_table_lock(net, AF_INET, get.name); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 541b59f..86b67b7 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1168,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, *len, sizeof(get) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; t = xt_find_table_lock(net, AF_INET6, get.name); if (!IS_ERR_OR_NULL(t)) { @@ -1944,6 +1945,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, *len, sizeof(get) + get.size); return -EINVAL; } + get.name[sizeof(get.name) - 1] = '\0'; xt_compat_lock(AF_INET6); t = xt_find_table_lock(net, AF_INET6, get.name); -- 2.1.4
From: Liping Zhang <liping.zhang@spreadtrum.com> Commit fa50d974d104 ("ipv4: Namespaceify ip_default_ttl sysctl knob") use sock_net(skb->sk) to get the net namespace, but we can't assume that sk_buff->sk is always exist, so when it is NULL, oops will happen. Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com> Reviewed-by: Nikolay Borisov <kernel@kyup.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- net/bridge/netfilter/nft_reject_bridge.c | 20 ++++++------ net/ipv4/netfilter/ipt_SYNPROXY.c | 54 +++++++++++++++++--------------- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index adc8d72..77f7e7a 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c @@ -40,7 +40,8 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) * or the bridge port (NF_BRIDGE PREROUTING). */ -static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, +static void nft_reject_br_send_v4_tcp_reset(struct net *net, + struct sk_buff *oldskb, const struct net_device *dev, int hook) { @@ -48,7 +49,6 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, struct iphdr *niph; const struct tcphdr *oth; struct tcphdr _oth; - struct net *net = sock_net(oldskb->sk); if (!nft_bridge_iphdr_validate(oldskb)) return; @@ -75,7 +75,8 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, br_deliver(br_port_get_rcu(dev), nskb); } -static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, +static void nft_reject_br_send_v4_unreach(struct net *net, + struct sk_buff *oldskb, const struct net_device *dev, int hook, u8 code) { @@ -86,7 +87,6 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, void *payload; __wsum csum; u8 proto; - struct net *net = sock_net(oldskb->sk); if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) return; @@ -273,17 +273,17 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr, case htons(ETH_P_IP): switch (priv->type) { case NFT_REJECT_ICMP_UNREACH: - nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, - pkt->hook, + nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, + pkt->in, pkt->hook, priv->icmp_code); break; case NFT_REJECT_TCP_RST: - nft_reject_br_send_v4_tcp_reset(pkt->skb, pkt->in, - pkt->hook); + nft_reject_br_send_v4_tcp_reset(pkt->net, pkt->skb, + pkt->in, pkt->hook); break; case NFT_REJECT_ICMPX_UNREACH: - nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, - pkt->hook, + nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, + pkt->in, pkt->hook, nft_reject_icmp_code(priv->icmp_code)); break; } diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 7b8fbb3..db5b875 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c @@ -18,10 +18,10 @@ #include <net/netfilter/nf_conntrack_synproxy.h> static struct iphdr * -synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) +synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, + __be32 daddr) { struct iphdr *iph; - struct net *net = sock_net(skb->sk); skb_reset_network_header(skb); iph = (struct iphdr *)skb_put(skb, sizeof(*iph)); @@ -40,14 +40,12 @@ synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) } static void -synproxy_send_tcp(const struct synproxy_net *snet, +synproxy_send_tcp(struct net *net, const struct sk_buff *skb, struct sk_buff *nskb, struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, struct iphdr *niph, struct tcphdr *nth, unsigned int tcp_hdr_size) { - struct net *net = nf_ct_net(snet->tmpl); - nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); nskb->ip_summed = CHECKSUM_PARTIAL; nskb->csum_start = (unsigned char *)nth - nskb->head; @@ -72,7 +70,7 @@ free_nskb: } static void -synproxy_send_client_synack(const struct synproxy_net *snet, +synproxy_send_client_synack(struct net *net, const struct sk_buff *skb, const struct tcphdr *th, const struct synproxy_options *opts) { @@ -91,7 +89,7 @@ synproxy_send_client_synack(const struct synproxy_net *snet, return; skb_reserve(nskb, MAX_TCP_HEADER); - niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); + niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); skb_reset_transport_header(nskb); nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); @@ -109,15 +107,16 @@ synproxy_send_client_synack(const struct synproxy_net *snet, synproxy_build_options(nth, opts); - synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, + synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); } static void -synproxy_send_server_syn(const struct synproxy_net *snet, +synproxy_send_server_syn(struct net *net, const struct sk_buff *skb, const struct tcphdr *th, const struct synproxy_options *opts, u32 recv_seq) { + struct synproxy_net *snet = synproxy_pernet(net); struct sk_buff *nskb; struct iphdr *iph, *niph; struct tcphdr *nth; @@ -132,7 +131,7 @@ synproxy_send_server_syn(const struct synproxy_net *snet, return; skb_reserve(nskb, MAX_TCP_HEADER); - niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); + niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); skb_reset_transport_header(nskb); nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); @@ -153,12 +152,12 @@ synproxy_send_server_syn(const struct synproxy_net *snet, synproxy_build_options(nth, opts); - synproxy_send_tcp(snet, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, + synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, niph, nth, tcp_hdr_size); } static void -synproxy_send_server_ack(const struct synproxy_net *snet, +synproxy_send_server_ack(struct net *net, const struct ip_ct_tcp *state, const struct sk_buff *skb, const struct tcphdr *th, const struct synproxy_options *opts) @@ -177,7 +176,7 @@ synproxy_send_server_ack(const struct synproxy_net *snet, return; skb_reserve(nskb, MAX_TCP_HEADER); - niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); + niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); skb_reset_transport_header(nskb); nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); @@ -193,11 +192,11 @@ synproxy_send_server_ack(const struct synproxy_net *snet, synproxy_build_options(nth, opts); - synproxy_send_tcp(snet, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); + synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); } static void -synproxy_send_client_ack(const struct synproxy_net *snet, +synproxy_send_client_ack(struct net *net, const struct sk_buff *skb, const struct tcphdr *th, const struct synproxy_options *opts) { @@ -215,7 +214,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, return; skb_reserve(nskb, MAX_TCP_HEADER); - niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); + niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); skb_reset_transport_header(nskb); nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); @@ -231,15 +230,16 @@ synproxy_send_client_ack(const struct synproxy_net *snet, synproxy_build_options(nth, opts); - synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, + synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); } static bool -synproxy_recv_client_ack(const struct synproxy_net *snet, +synproxy_recv_client_ack(struct net *net, const struct sk_buff *skb, const struct tcphdr *th, struct synproxy_options *opts, u32 recv_seq) { + struct synproxy_net *snet = synproxy_pernet(net); int mss; mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); @@ -255,7 +255,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) synproxy_check_timestamp_cookie(opts); - synproxy_send_server_syn(snet, skb, th, opts, recv_seq); + synproxy_send_server_syn(net, skb, th, opts, recv_seq); return true; } @@ -263,7 +263,8 @@ static unsigned int synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) { const struct xt_synproxy_info *info = par->targinfo; - struct synproxy_net *snet = synproxy_pernet(par->net); + struct net *net = par->net; + struct synproxy_net *snet = synproxy_pernet(net); struct synproxy_options opts = {}; struct tcphdr *th, _th; @@ -292,12 +293,12 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) XT_SYNPROXY_OPT_SACK_PERM | XT_SYNPROXY_OPT_ECN); - synproxy_send_client_synack(snet, skb, th, &opts); + synproxy_send_client_synack(net, skb, th, &opts); return NF_DROP; } else if (th->ack && !(th->fin || th->rst || th->syn)) { /* ACK from client */ - synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); + synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); return NF_DROP; } @@ -308,7 +309,8 @@ static unsigned int ipv4_synproxy_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *nhs) { - struct synproxy_net *snet = synproxy_pernet(nhs->net); + struct net *net = nhs->net; + struct synproxy_net *snet = synproxy_pernet(net); enum ip_conntrack_info ctinfo; struct nf_conn *ct; struct nf_conn_synproxy *synproxy; @@ -365,7 +367,7 @@ static unsigned int ipv4_synproxy_hook(void *priv, * therefore we need to add 1 to make the SYN sequence * number match the one of first SYN. */ - if (synproxy_recv_client_ack(snet, skb, th, &opts, + if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq) + 1)) this_cpu_inc(snet->stats->cookie_retrans); @@ -391,12 +393,12 @@ static unsigned int ipv4_synproxy_hook(void *priv, XT_SYNPROXY_OPT_SACK_PERM); swap(opts.tsval, opts.tsecr); - synproxy_send_server_ack(snet, state, skb, th, &opts); + synproxy_send_server_ack(net, state, skb, th, &opts); nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); swap(opts.tsval, opts.tsecr); - synproxy_send_client_ack(snet, skb, th, &opts); + synproxy_send_client_ack(net, skb, th, &opts); consume_skb(skb); return NF_STOLEN; -- 2.1.4
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Mon, 28 Mar 2016 19:57:53 +0200 > The following patchset contains Netfilter fixes for you net tree, > they are: ... > This batch comes with four patches to validate x_tables blobs coming > from userspace. CONFIG_USERNS exposes the x_tables interface to > unpriviledged users and to be honest this interface never received the > attention for this move away from the CAP_NET_ADMIN domain. Florian is > working on another round with more patches with more sanity checks, so > expect a bit more Netfilter fixes in this development cycle than usual. > > You can pull these changes from: > > git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Looks good, pulled, thanks Pablo!
Hi David, The following patchset contains Netfilter fixes for your net tree, they are: 1) Use mod_timer_pending() to avoid reactivating a dead expectation in the h323 conntrack helper, from Liping Zhang. 2) Oneliner to fix a type in the register name defined in the nf_tables header. 3) Don't try to look further when we find an inactive elements with no descendants in the rbtree set implementation, otherwise we crash. 4) Handle valid zero CSeq in the SIP conntrack helper, from Christophe Leroy. 5) Don't display a trailing slash in conntrack helper with no classes via /proc/net/nf_conntrack_expect, from Liping Zhang. 6) Fix an expectation leak during creation from the nfqueue path, again from Liping Zhang. 7) Validate netlink port ID in verdict message from nfqueue, otherwise an injection can be possible. Again from Zhang. 8) Reject conntrack tuples with different transport protocol on original and reply tuples, also from Zhang. 9) Validate offset and length in nft_exthdr, make sure they are under sizeof(u8), from Laura Garcia Liebana. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit c518189567eaf42b2ec50a4d982484c8e38799f8: net: macb: Correct CAPS mask (2016-08-06 20:53:06 -0400) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 4da449ae1df9cfeb167e78f250b250eff64bc65e: netfilter: nft_exthdr: Add size check on u8 nft_exthdr attributes (2016-08-10 13:10:13 +0200) ---------------------------------------------------------------- Christophe Leroy (1): netfilter: nf_conntrack_sip: CSeq 0 is a valid CSeq Laura Garcia Liebana (1): netfilter: nft_exthdr: Add size check on u8 nft_exthdr attributes Liping Zhang (5): netfilter: nf_ct_h323: do not re-activate already expired timer netfilter: nf_ct_expect: remove the redundant slash when policy name is empty netfilter: nfnetlink_queue: fix memory leak when attach expectation successfully netfilter: nfnetlink_queue: reject verdict request from different portid netfilter: ctnetlink: reject new conntrack request with different l4proto Pablo Neira Ayuso (2): netfilter: nf_tables: s/MFT_REG32_01/NFT_REG32_01 netfilter: nft_rbtree: ignore inactive matching element with no descendants include/uapi/linux/netfilter/nf_tables.h | 2 +- net/netfilter/nf_conntrack_expect.c | 2 +- net/netfilter/nf_conntrack_h323_main.c | 3 ++- net/netfilter/nf_conntrack_netlink.c | 10 ++++------ net/netfilter/nf_conntrack_sip.c | 4 ++-- net/netfilter/nfnetlink_queue.c | 6 ++---- net/netfilter/nft_exthdr.c | 11 +++++++++-- net/netfilter/nft_rbtree.c | 10 ++++++---- 8 files changed, 27 insertions(+), 21 deletions(-)
Resending as my robot didn't Cc netdev, sorry. -o- Hi David, The following patchset contains Netfilter fixes for your net tree, they are: 1) Use mod_timer_pending() to avoid reactivating a dead expectation in the h323 conntrack helper, from Liping Zhang. 2) Oneliner to fix a type in the register name defined in the nf_tables header. 3) Don't try to look further when we find an inactive elements with no descendants in the rbtree set implementation, otherwise we crash. 4) Handle valid zero CSeq in the SIP conntrack helper, from Christophe Leroy. 5) Don't display a trailing slash in conntrack helper with no classes via /proc/net/nf_conntrack_expect, from Liping Zhang. 6) Fix an expectation leak during creation from the nfqueue path, again from Liping Zhang. 7) Validate netlink port ID in verdict message from nfqueue, otherwise an injection can be possible. Again from Zhang. 8) Reject conntrack tuples with different transport protocol on original and reply tuples, also from Zhang. 9) Validate offset and length in nft_exthdr, make sure they are under sizeof(u8), from Laura Garcia Liebana. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit c518189567eaf42b2ec50a4d982484c8e38799f8: net: macb: Correct CAPS mask (2016-08-06 20:53:06 -0400) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 4da449ae1df9cfeb167e78f250b250eff64bc65e: netfilter: nft_exthdr: Add size check on u8 nft_exthdr attributes (2016-08-10 13:10:13 +0200) ---------------------------------------------------------------- Christophe Leroy (1): netfilter: nf_conntrack_sip: CSeq 0 is a valid CSeq Laura Garcia Liebana (1): netfilter: nft_exthdr: Add size check on u8 nft_exthdr attributes Liping Zhang (5): netfilter: nf_ct_h323: do not re-activate already expired timer netfilter: nf_ct_expect: remove the redundant slash when policy name is empty netfilter: nfnetlink_queue: fix memory leak when attach expectation successfully netfilter: nfnetlink_queue: reject verdict request from different portid netfilter: ctnetlink: reject new conntrack request with different l4proto Pablo Neira Ayuso (2): netfilter: nf_tables: s/MFT_REG32_01/NFT_REG32_01 netfilter: nft_rbtree: ignore inactive matching element with no descendants include/uapi/linux/netfilter/nf_tables.h | 2 +- net/netfilter/nf_conntrack_expect.c | 2 +- net/netfilter/nf_conntrack_h323_main.c | 3 ++- net/netfilter/nf_conntrack_netlink.c | 10 ++++------ net/netfilter/nf_conntrack_sip.c | 4 ++-- net/netfilter/nfnetlink_queue.c | 6 ++---- net/netfilter/nft_exthdr.c | 11 +++++++++-- net/netfilter/nft_rbtree.c | 10 ++++++---- 8 files changed, 27 insertions(+), 21 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Wed, 10 Aug 2016 20:56:25 +0200 > The following patchset contains Netfilter fixes for your net tree, > they are: ... > You can pull these changes from: > > git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Pulled, thanks a lot Pablo!
Hi David, The following patchset contains Netfilter fixes for your net tree, they are: 1) Missing TCP header sanity check in TCPMSS target, from Eric Dumazet. 2) Incorrect event message type for related conntracks created via ctnetlink, from Liping Zhang. 3) Fix incorrect rcu locking when handling helpers from ctnetlink, from Gao feng. 4) Fix missing rcu locking when updating helper, from Liping Zhang. 5) Fix missing read_lock_bh when iterating over list of device addresses from TPROXY and redirect, also from Liping. 6) Fix crash when trying to dump expectations from conntrack with no helper via ctnetlink, from Liping. 7) Missing RCU protection to expecation list update given ctnetlink iterates over the list under rcu read lock side, from Liping too. 8) Don't dump autogenerated seed in nft_hash to userspace, this is very confusing to the user, again from Liping. 9) Fix wrong conntrack netns module refcount in ipt_CLUSTERIP, from Gao feng. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit 0b9aefea860063bb39e36bd7fe6c7087fed0ba87: tcp: minimize false-positives on TCP/GRO check (2017-04-03 18:43:41 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to fe50543c194e2e1aee2f3eba41fcafd187b3dbde: netfilter: ipt_CLUSTERIP: Fix wrong conntrack netns refcnt usage (2017-04-13 23:21:40 +0200) ---------------------------------------------------------------- Eric Dumazet (1): netfilter: xt_TCPMSS: add more sanity tests on tcph->doff Gao Feng (2): netfilter: helper: Add the rcu lock when call __nf_conntrack_helper_find netfilter: ipt_CLUSTERIP: Fix wrong conntrack netns refcnt usage Liping Zhang (6): netfilter: ctnetlink: using bit to represent the ct event netfilter: ctnetlink: make it safer when checking the ct helper name netfilter: make it safer during the inet6_dev->addr_list traversal netfilter: ctnetlink: skip dumping expect when nfct_help(ct) is NULL netfilter: nf_ct_expect: use proper RCU list traversal/update APIs netfilter: nft_hash: do not dump the auto generated seed net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +- net/netfilter/nf_conntrack_expect.c | 4 ++-- net/netfilter/nf_conntrack_helper.c | 17 ++++++++++----- net/netfilter/nf_conntrack_netlink.c | 41 +++++++++++++++++++++++++----------- net/netfilter/nf_nat_redirect.c | 2 ++ net/netfilter/nft_hash.c | 10 ++++++--- net/netfilter/xt_TCPMSS.c | 6 +++++- net/netfilter/xt_TPROXY.c | 5 ++++- 8 files changed, 62 insertions(+), 25 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Fri, 14 Apr 2017 02:26:42 +0200 > The following patchset contains Netfilter fixes for your net tree, > they are: ... > You can pull these changes from: > > git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Pulled, thanks Pablo.
Hi David, The following patchset contains Netfilter patches for your net tree: 1) Fix NULL pointer dereference from nf_nat_decode_session() if NAT is not loaded, from Prashant Bhole. 2) Fix socket extension module autoload. 3) Don't bogusly reject sets with the NFT_SET_EVAL flag set on from the dynset extension. 4) Fix races with nf_tables module removal and netns exit path, patches from Florian Westphal. 5) Don't hit BUG_ON if jumpstack goes too deep, instead hit WARN_ON_ONCE, from Taehee Yoo. 6) Another NULL pointer dereference from ctnetlink, again if NAT is not loaded, from Florian Westphal. 7) Fix x_tables match list corruption in xt_connmark module removal path, also from Florian. 8) nf_conncount doesn't properly deal with conntrack zones, hence garbage collector may get rid of entries in a different zone. From Yi-Hung Wei. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks. ---------------------------------------------------------------- The following changes since commit 6892286e9c09925780fe2cb6db3585b56b71fe8e: tcp: Do not reload skb pointer after skb_gro_receive(). (2018-06-11 20:00:56 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 21ba8847f857028dc83a0f341e16ecc616e34740: netfilter: nf_conncount: Fix garbage collection with zones (2018-06-12 20:07:07 +0200) ---------------------------------------------------------------- Florian Westphal (4): netfilter: nf_tables: fix module unload race netfilter: nf_tables: close race between netns exit and rmmod netfilter: ctnetlink: avoid null pointer dereference netfilter: xt_connmark: fix list corruption on rmmod Pablo Neira Ayuso (2): netfilter: nft_socket: fix module autoload netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL Prashant Bhole (1): netfilter: fix null-ptr-deref in nf_nat_decode_session Taehee Yoo (1): netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain() Yi-Hung Wei (1): netfilter: nf_conncount: Fix garbage collection with zones include/linux/netfilter.h | 2 +- include/net/netfilter/nf_conntrack_count.h | 3 ++- include/uapi/linux/netfilter/nf_tables.h | 2 +- net/netfilter/nf_conncount.c | 13 +++++++++---- net/netfilter/nf_conntrack_netlink.c | 3 ++- net/netfilter/nf_tables_api.c | 25 +++++++++++++++++++------ net/netfilter/nf_tables_core.c | 3 ++- net/netfilter/nfnetlink.c | 10 +++++++--- net/netfilter/nft_chain_filter.c | 5 +++++ net/netfilter/nft_connlimit.c | 2 +- net/netfilter/nft_dynset.c | 4 +--- net/netfilter/nft_socket.c | 1 + net/netfilter/xt_connmark.c | 2 +- 13 files changed, 52 insertions(+), 23 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 13 Jun 2018 12:56:51 +0200
> The following patchset contains Netfilter patches for your net tree:
>
> 1) Fix NULL pointer dereference from nf_nat_decode_session() if NAT is
> not loaded, from Prashant Bhole.
>
> 2) Fix socket extension module autoload.
>
> 3) Don't bogusly reject sets with the NFT_SET_EVAL flag set on from
> the dynset extension.
>
> 4) Fix races with nf_tables module removal and netns exit path,
> patches from Florian Westphal.
>
> 5) Don't hit BUG_ON if jumpstack goes too deep, instead hit
> WARN_ON_ONCE, from Taehee Yoo.
>
> 6) Another NULL pointer dereference from ctnetlink, again if NAT is
> not loaded, from Florian Westphal.
>
> 7) Fix x_tables match list corruption in xt_connmark module removal
> path, also from Florian.
>
> 8) nf_conncount doesn't properly deal with conntrack zones, hence
> garbage collector may get rid of entries in a different zone.
> From Yi-Hung Wei.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled, thank you.
Hi David, The following patchset contains Netfilter fixes for net: 1) Make sure we don't go over the maximum jump stack boundary, from Taehee Yoo. 2) Missing rcu_barrier() in hash and rbtree sets, also from Taehee. 3) Missing check to nul-node in rbtree timeout routine, from Taehee. 4) Use dev->name from flowtable to fix a memleak, from Florian. 5) Oneliner to free flowtable object on removal, from Florian. 6) Memleak in chain rename transaction, again from Florian. 7) Don't allow two chains to use the same name in the same transaction, from Florian. 8) handle DCCP SYNC/SYNCACK as invalid, this triggers an uninitialized timer in conntrack reported by syzbot, from Florian. 9) Fix leak in case netlink_dump_start() fails, from Florian. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks. ---------------------------------------------------------------- The following changes since commit 1992d99882afda6dc17f9d49c06150856a91282f: net/smc: take sock lock in smc_ioctl() (2018-07-16 14:45:13 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 90fd131afc565159c9e0ea742f082b337e10f8c6: netfilter: nf_tables: move dumper state allocation into ->start (2018-07-24 00:36:33 +0200) ---------------------------------------------------------------- Florian Westphal (6): netfilter: nf_tables: use dev->name directly netfilter: nf_tables: free flow table struct too netfilter: nf_tables: fix memory leaks on chain rename netfilter: nf_tables: don't allow to rename to already-pending name netfilter: conntrack: dccp: treat SYNC/SYNCACK as invalid if no prior state netfilter: nf_tables: move dumper state allocation into ->start Taehee Yoo (3): netfilter: nf_tables: fix jumpstack depth validation netfilter: nft_set_hash: add rcu_barrier() in the nft_rhash_destroy() netfilter: nft_set_rbtree: fix panic when destroying set by GC include/net/netfilter/nf_tables.h | 5 +- net/netfilter/nf_conntrack_proto_dccp.c | 8 +- net/netfilter/nf_tables_api.c | 304 +++++++++++++++++--------------- net/netfilter/nft_immediate.c | 3 + net/netfilter/nft_lookup.c | 13 +- net/netfilter/nft_set_hash.c | 1 + net/netfilter/nft_set_rbtree.c | 7 +- 7 files changed, 191 insertions(+), 150 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Tue, 24 Jul 2018 18:31:24 +0200 > The following patchset contains Netfilter fixes for net: ... > You can pull these changes from: > > git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Pulled, thank you.
Hi David, The following patchset contains Netfilter fixes for net, specifically fixes for the nf_conncount infrastructure which is causing troubles since 5c789e131cbb9 ("netfilter: nf_conncount: Add list lock and gc worker, and RCU for init tree search"). Patches aim to simplify this infrastructure while fixing up the problems: 1) Use fixed size CONNCOUNT_SLOTS in nf_conncount, from Shawn Bohrer. 2) Incorrect signedness in age calculation from find_or_evict(), from Florian Westphal. 3) Proper locking for the garbage collector workqueue callback, first make a patch to count how many nodes can be collected without holding locks, then grab lock and release them. Also from Florian. 4) Restart node lookup from the insertion path, after releasing nodes via packet path garbage collection. Shawn Bohrer described a scenario that may result in inserting a connection in an already dead list node. Patch from Florian. 5) Merge lookup and add function to avoid a hold release and re-grab. From Florian. 6) Be safe and iterate over the node lists under the spinlock. 7) Speculative list nodes removal via garbage collection, check if list node got a connection while it was scheduled for deletion via gc. 8) Accidental argument swap in find_next_bit() that leads to more frequent scheduling of the workqueue. From Florian Westphal. And one patch that falls within the miscelanea category in this batch: 9) Missing error path for nla_nest_start(), from Kangjie Lu. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit a3c9311f62b4943228ae90f769775dd3bcbfa7c0: include/linux/phy/phy.h: fix minor kerneldoc errors (2018-12-27 16:31:10 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to a007232066f6839d6f256bab21e825d968f1a163: netfilter: nf_conncount: fix argument order to find_next_bit (2018-12-29 02:45:22 +0100) ---------------------------------------------------------------- Florian Westphal (5): netfilter: nf_conncount: don't skip eviction when age is negative netfilter: nf_conncount: split gc in two phases netfilter: nf_conncount: restart search when nodes have been erased netfilter: nf_conncount: merge lookup and add functions netfilter: nf_conncount: fix argument order to find_next_bit Kangjie Lu (1): netfilter: nf_tables: fix a missing check of nla_put_failure Pablo Neira Ayuso (2): netfilter: nf_conncount: move all list iterations under spinlock netfilter: nf_conncount: speculative garbage collection on empty lists Shawn Bohrer (1): netfilter: nf_conncount: replace CONNCOUNT_LOCK_SLOTS with CONNCOUNT_SLOTS include/net/netfilter/nf_conntrack_count.h | 19 +- net/netfilter/nf_conncount.c | 290 +++++++++++++---------------- net/netfilter/nf_tables_api.c | 2 + net/netfilter/nft_connlimit.c | 14 +- 4 files changed, 136 insertions(+), 189 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Sat, 29 Dec 2018 13:57:54 +0100 > The following patchset contains Netfilter fixes for net, specifically > fixes for the nf_conncount infrastructure which is causing troubles > since 5c789e131cbb9 ("netfilter: nf_conncount: Add list lock and gc > worker, and RCU for init tree search"). Patches aim to simplify this > infrastructure while fixing up the problems: ... > And one patch that falls within the miscelanea category in this batch: > > 9) Missing error path for nla_nest_start(), from Kangjie Lu. > > You can pull these changes from: > > git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Pulled, thank you.
Hi David, The following patchset contains Netfilter fixes for your net tree: 1) Remove a direct dependency with IPv6 introduced by the sip_external_media feature, from Alin Nastac. 2) Fix bogus ENOENT when removing interval elements from set. 3) Set transport_header from br_netfilter to mimic the stack behaviour, this partially fixes a checksum validation bug from the SCTP connection tracking, from Xin Long. 4) Fix undefined reference to symbol in xt_TEE, due to missing Kconfig dependencies, from Arnd Bergmann. 5) Check for NULL in skb_header_pointer() calls in ip6t_shr, from Kangjie Lu. 6) Fix bogus EBUSY when removing an existing conntrack helper from a transaction. 7) Fix module autoload of the redirect extension. 8) Remove duplicated transition in flowtable diagram in the existing documentation. 9) Missing .release_ops call from error path in newrule() which results module refcount leak, from Taehee Yoo. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks! ---------------------------------------------------------------- The following changes since commit 4ec850e5dfec092b26cf3b7d5a6c9e444ea4babd: net: dwmac-sun8i: fix a missing check of of_get_phy_mode (2019-03-12 14:52:00 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to b25a31bf0ca091aa8bdb9ab329b0226257568bbe: netfilter: nf_tables: add missing ->release_ops() in error path of newrule() (2019-03-20 08:32:58 +0100) ---------------------------------------------------------------- Alin Nastac (1): netfilter: nf_conntrack_sip: remove direct dependency on IPv6 Arnd Bergmann (1): netfilter: fix NETFILTER_XT_TARGET_TEE dependencies Kangjie Lu (1): netfilter: ip6t_srh: fix NULL pointer dereferences Pablo Neira Ayuso (4): netfilter: nft_set_rbtree: check for inactive element after flag mismatch netfilter: nf_tables: bogus EBUSY in helper removal from transaction netfilter: nft_redir: fix module autoload with ip4 netfilter: nf_flowtable: remove duplicated transition in diagram Taehee Yoo (1): netfilter: nf_tables: add missing ->release_ops() in error path of newrule() Xin Long (1): netfilter: bridge: set skb transport_header before entering NF_INET_PRE_ROUTING Documentation/networking/nf_flowtable.txt | 8 +++---- net/bridge/br_netfilter_hooks.c | 1 + net/bridge/br_netfilter_ipv6.c | 2 ++ net/ipv6/netfilter/ip6t_srh.c | 6 +++++ net/netfilter/Kconfig | 1 + net/netfilter/nf_conntrack_sip.c | 37 +++++++++++++------------------ net/netfilter/nf_tables_api.c | 5 ++++- net/netfilter/nft_objref.c | 19 +++++++++++++--- net/netfilter/nft_redir.c | 2 +- net/netfilter/nft_set_rbtree.c | 7 +++--- 10 files changed, 54 insertions(+), 34 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 21 Mar 2019 12:28:36 +0100
> The following patchset contains Netfilter fixes for your net tree:
>
> 1) Remove a direct dependency with IPv6 introduced by the
> sip_external_media feature, from Alin Nastac.
>
> 2) Fix bogus ENOENT when removing interval elements from set.
>
> 3) Set transport_header from br_netfilter to mimic the stack
> behaviour, this partially fixes a checksum validation bug
> from the SCTP connection tracking, from Xin Long.
>
> 4) Fix undefined reference to symbol in xt_TEE, due to missing
> Kconfig dependencies, from Arnd Bergmann.
>
> 5) Check for NULL in skb_header_pointer() calls in ip6t_shr,
> from Kangjie Lu.
>
> 6) Fix bogus EBUSY when removing an existing conntrack helper from
> a transaction.
>
> 7) Fix module autoload of the redirect extension.
>
> 8) Remove duplicated transition in flowtable diagram in the existing
> documentation.
>
> 9) Missing .release_ops call from error path in newrule() which
> results module refcount leak, from Taehee Yoo.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled, thanks.
Hi David, The following patchset contains Netfilter fixes for net: 1) Missing register size validation in bitwise and cmp offloads. 2) Fix error code in ip_set_sockfn_get() when copy_to_user() fails, from Dan Carpenter. 3) Oneliner to copy MAC address in IPv6 hash:ip,mac sets, from Stefano Brivio. 4) Missing policy validation in ipset with NL_VALIDATE_STRICT, from Jozsef Kadlecsik. 5) Fix unaligned access to private data area of nf_tables instructions, from Lukas Wunner. 6) Relax check for object updates, reported as a regression by Eric Garver, patch from Fernando Fernandez Mancera. 7) Crash on ebtables dnat extension when used from the output path. From Florian Westphal. 8) Fix bogus EOPNOTSUPP when updating basechain flags. 9) Fix bogus EBUSY when updating a basechain that is already offloaded. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks. ---------------------------------------------------------------- The following changes since commit 1204c70d9dcba31164f78ad5d8c88c42335d51f8: Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (2019-11-01 17:48:11 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 774e4d34dbebc9dc441535c4712794d336a9478c: Merge branch 'master' of git://blackhole.kfki.hu/nf (2019-11-04 20:59:00 +0100) ---------------------------------------------------------------- Dan Carpenter (1): netfilter: ipset: Fix an error code in ip_set_sockfn_get() Fernando Fernandez Mancera (1): netfilter: nf_tables: fix unexpected EOPNOTSUPP error Florian Westphal (1): bridge: ebtables: don't crash when using dnat target in output chains Jozsef Kadlecsik (1): netfilter: ipset: Fix nla_policies to fully support NL_VALIDATE_STRICT Lukas Wunner (1): netfilter: nf_tables: Align nft_expr private data to 64-bit Pablo Neira Ayuso (4): netfilter: nf_tables_offload: check for register data length mismatches netfilter: nf_tables: bogus EOPNOTSUPP on basechain update netfilter: nf_tables_offload: skip EBUSY on chain update Merge branch 'master' of git://blackhole.kfki.hu/nf Stefano Brivio (1): netfilter: ipset: Copy the right MAC address in hash:ip,mac IPv6 sets include/net/netfilter/nf_tables.h | 3 +- net/bridge/netfilter/ebt_dnat.c | 19 ++++++++++--- net/netfilter/ipset/ip_set_core.c | 49 +++++++++++++++++++++----------- net/netfilter/ipset/ip_set_hash_ipmac.c | 2 +- net/netfilter/ipset/ip_set_hash_net.c | 1 + net/netfilter/ipset/ip_set_hash_netnet.c | 1 + net/netfilter/nf_tables_api.c | 7 ++--- net/netfilter/nf_tables_offload.c | 3 +- net/netfilter/nft_bitwise.c | 5 ++-- net/netfilter/nft_cmp.c | 2 +- 10 files changed, 62 insertions(+), 30 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 6 Nov 2019 12:12:28 +0100
> The following patchset contains Netfilter fixes for net:
>
> 1) Missing register size validation in bitwise and cmp offloads.
>
> 2) Fix error code in ip_set_sockfn_get() when copy_to_user() fails,
> from Dan Carpenter.
>
> 3) Oneliner to copy MAC address in IPv6 hash:ip,mac sets, from
> Stefano Brivio.
>
> 4) Missing policy validation in ipset with NL_VALIDATE_STRICT,
> from Jozsef Kadlecsik.
>
> 5) Fix unaligned access to private data area of nf_tables instructions,
> from Lukas Wunner.
>
> 6) Relax check for object updates, reported as a regression by
> Eric Garver, patch from Fernando Fernandez Mancera.
>
> 7) Crash on ebtables dnat extension when used from the output path.
> From Florian Westphal.
>
> 8) Fix bogus EOPNOTSUPP when updating basechain flags.
>
> 9) Fix bogus EBUSY when updating a basechain that is already offloaded.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled, thanks Pablo.
Hi, The following patchset contains Netfilter fixes for net: 1) Missing netns context in arp_tables, from Florian Westphal. 2) Underflow in flowtable reference counter, from wenxu. 3) Fix incorrect ethernet destination address in flowtable offload, from wenxu. 4) Check for status of neighbour entry, from wenxu. 5) Fix NAT port mangling, from wenxu. 6) Unbind callbacks from destroy path to cleanup hardware properly on flowtable removal. 7) Fix missing casting statistics timestamp, add nf_flowtable_time_stamp and use it. 8) NULL pointer exception when timeout argument is null in conntrack dccp and sctp protocol helpers, from Florian Westphal. 9) Possible nul-dereference in ipset with IPSET_ATTR_LINENO, also from Florian. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thanks. ---------------------------------------------------------------- The following changes since commit bd6f48546b9cb7a785344fc78058c420923d7ed8: net: stmmac: dwmac-meson8b: Fix the RGMII TX delay on Meson8b/8m2 SoCs (2019-12-27 16:37:07 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 22dad713b8a5ff488e07b821195270672f486eb2: netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present (2020-01-08 23:31:46 +0100) ---------------------------------------------------------------- Florian Westphal (3): netfilter: arp_tables: init netns pointer in xt_tgchk_param struct netfilter: conntrack: dccp, sctp: handle null timeout argument netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present Pablo Neira Ayuso (2): netfilter: nf_tables: unbind callbacks from flowtable destroy path netfilter: flowtable: add nf_flowtable_time_stamp wenxu (4): netfilter: nft_flow_offload: fix underflow in flowtable reference counter netfilter: nf_flow_table_offload: fix incorrect ethernet dst address netfilter: nf_flow_table_offload: check the status of dst_neigh netfilter: nf_flow_table_offload: fix the nat port mangle. include/net/netfilter/nf_flow_table.h | 6 ++++ net/ipv4/netfilter/arp_tables.c | 27 ++++++++++-------- net/netfilter/ipset/ip_set_core.c | 3 +- net/netfilter/nf_conntrack_proto_dccp.c | 3 ++ net/netfilter/nf_conntrack_proto_sctp.c | 3 ++ net/netfilter/nf_flow_table_core.c | 7 +---- net/netfilter/nf_flow_table_ip.c | 4 +-- net/netfilter/nf_flow_table_offload.c | 50 ++++++++++++++++++++++++--------- net/netfilter/nf_tables_api.c | 8 ++++-- net/netfilter/nft_flow_offload.c | 3 -- 10 files changed, 75 insertions(+), 39 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 9 Jan 2020 00:17:04 +0100
> The following patchset contains Netfilter fixes for net:
>
> 1) Missing netns context in arp_tables, from Florian Westphal.
>
> 2) Underflow in flowtable reference counter, from wenxu.
>
> 3) Fix incorrect ethernet destination address in flowtable offload,
> from wenxu.
>
> 4) Check for status of neighbour entry, from wenxu.
>
> 5) Fix NAT port mangling, from wenxu.
>
> 6) Unbind callbacks from destroy path to cleanup hardware properly
> on flowtable removal.
>
> 7) Fix missing casting statistics timestamp, add nf_flowtable_time_stamp
> and use it.
>
> 8) NULL pointer exception when timeout argument is null in conntrack
> dccp and sctp protocol helpers, from Florian Westphal.
>
> 9) Possible nul-dereference in ipset with IPSET_ATTR_LINENO, also from
> Florian.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled, thanks Pablo.
Hi, This batch contains Netfilter fixes for net: 1) Restrict hashlimit size to 1048576, from Cong Wang. 2) Check for offload flags from nf_flow_table_offload_setup(), this fixes a crash in case the hardware offload is disabled. From Florian Westphal. 3) Three preparation patches to extend the conntrack clash resolution, from Florian. 4) Extend clash resolution to deal with DNS packets from the same flow racing to set up the NAT configuration. 5) Small documentation fix in pipapo, from Stefano Brivio. 6) Remove misleading unlikely() from pipapo_refill(), also from Stefano. 7) Reduce hashlimit mutex scope, from Cong Wang. This patch is actually triggering another problem, still under discussion, another patch to fix this will follow up. You can pull these changes from: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git Thank you. ---------------------------------------------------------------- The following changes since commit 259039fa30457986929a324d769f543c1509987f: Merge branch 'stmmac-fixes' (2020-02-07 11:36:22 +0100) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git HEAD for you to fetch changes up to 9a7712048f9d43da5022e75eca3d6b81080e76d3: netfilter: nft_set_pipapo: Don't abuse unlikely() in pipapo_refill() (2020-02-18 22:07:09 +0100) ---------------------------------------------------------------- Cong Wang (2): netfilter: xt_hashlimit: reduce hashlimit_mutex scope for htable_put() netfilter: xt_hashlimit: limit the max size of hashtable Florian Westphal (5): netfilter: flowtable: skip offload setup if disabled netfilter: conntrack: remove two args from resolve_clash netfilter: conntrack: place confirm-bit setting in a helper netfilter: conntrack: split resolve_clash function netfilter: conntrack: allow insertion of clashing entries Stefano Brivio (2): netfilter: nft_set_pipapo: Fix mapping table example in comments netfilter: nft_set_pipapo: Don't abuse unlikely() in pipapo_refill() include/linux/rculist_nulls.h | 7 + include/uapi/linux/netfilter/nf_conntrack_common.h | 12 +- net/netfilter/nf_conntrack_core.c | 192 ++++++++++++++++++--- net/netfilter/nf_conntrack_proto_udp.c | 20 ++- net/netfilter/nf_flow_table_offload.c | 6 +- net/netfilter/nft_set_pipapo.c | 6 +- net/netfilter/xt_hashlimit.c | 22 ++- 7 files changed, 220 insertions(+), 45 deletions(-)
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Tue, 18 Feb 2020 23:20:52 +0100
> This batch contains Netfilter fixes for net:
>
> 1) Restrict hashlimit size to 1048576, from Cong Wang.
>
> 2) Check for offload flags from nf_flow_table_offload_setup(),
> this fixes a crash in case the hardware offload is disabled.
> From Florian Westphal.
>
> 3) Three preparation patches to extend the conntrack clash resolution,
> from Florian.
>
> 4) Extend clash resolution to deal with DNS packets from the same flow
> racing to set up the NAT configuration.
>
> 5) Small documentation fix in pipapo, from Stefano Brivio.
>
> 6) Remove misleading unlikely() from pipapo_refill(), also from Stefano.
>
> 7) Reduce hashlimit mutex scope, from Cong Wang. This patch is actually
> triggering another problem, still under discussion, another patch to
> fix this will follow up.
>
> You can pull these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
Pulled, thanks Pablo.