From: Greg Kroah-Hartman Date: Sat, 17 Oct 2015 19:49:21 +0000 (-0700) Subject: 4.2-stable patches X-Git-Tag: v3.10.91~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f589f46bf5f0b3cd711054a3b7e8cd8e69c87ce8;p=thirdparty%2Fkernel%2Fstable-queue.git 4.2-stable patches added patches: netfilter-bridge-fix-ipv6-packets-not-being-bridged-with-config_ipv6-n.patch netfilter-conntrack-use-nf_ct_tmpl_free-in-ct-synproxy-error-paths.patch netfilter-ipset-fixing-unnamed-union-init.patch netfilter-ipset-out-of-bound-access-in-hash-net-types-fixed.patch netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch --- diff --git a/queue-4.2/netfilter-bridge-fix-ipv6-packets-not-being-bridged-with-config_ipv6-n.patch b/queue-4.2/netfilter-bridge-fix-ipv6-packets-not-being-bridged-with-config_ipv6-n.patch new file mode 100644 index 00000000000..da530c76f38 --- /dev/null +++ b/queue-4.2/netfilter-bridge-fix-ipv6-packets-not-being-bridged-with-config_ipv6-n.patch @@ -0,0 +1,42 @@ +From 18e1db67e93ed75d9dc0d34c8d783ccf10547c2b Mon Sep 17 00:00:00 2001 +From: Bernhard Thaler +Date: Thu, 13 Aug 2015 08:58:15 +0200 +Subject: netfilter: bridge: fix IPv6 packets not being bridged with CONFIG_IPV6=n + +From: Bernhard Thaler + +commit 18e1db67e93ed75d9dc0d34c8d783ccf10547c2b upstream. + +230ac490f7fba introduced a dependency to CONFIG_IPV6 which breaks bridging +of IPv6 packets on a bridge with CONFIG_IPV6=n. + +Sysctl entry /proc/sys/net/bridge/bridge-nf-call-ip6tables defaults to 1, +for this reason packets are handled by br_nf_pre_routing_ipv6(). When compiled +with CONFIG_IPV6=n this function returns NF_DROP but should return NF_ACCEPT +to let packets through. + +Change CONFIG_IPV6=n br_nf_pre_routing_ipv6() return value to NF_ACCEPT. + +Tested with a simple bridge with two interfaces and IPv6 packets trying +to pass from host on left side to host on right side of the bridge. + +Fixes: 230ac490f7fba ("netfilter: bridge: split ipv6 code into separated file") +Signed-off-by: Bernhard Thaler +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/br_netfilter.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/net/netfilter/br_netfilter.h ++++ b/include/net/netfilter/br_netfilter.h +@@ -59,7 +59,7 @@ static inline unsigned int + br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, struct sk_buff *skb, + const struct nf_hook_state *state) + { +- return NF_DROP; ++ return NF_ACCEPT; + } + #endif + diff --git a/queue-4.2/netfilter-conntrack-use-nf_ct_tmpl_free-in-ct-synproxy-error-paths.patch b/queue-4.2/netfilter-conntrack-use-nf_ct_tmpl_free-in-ct-synproxy-error-paths.patch new file mode 100644 index 00000000000..f9e627acc49 --- /dev/null +++ b/queue-4.2/netfilter-conntrack-use-nf_ct_tmpl_free-in-ct-synproxy-error-paths.patch @@ -0,0 +1,97 @@ +From 9cf94eab8b309e8bcc78b41dd1561c75b537dd0b Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Mon, 31 Aug 2015 19:11:02 +0200 +Subject: netfilter: conntrack: use nf_ct_tmpl_free in CT/synproxy error paths + +From: Daniel Borkmann + +commit 9cf94eab8b309e8bcc78b41dd1561c75b537dd0b upstream. + +Commit 0838aa7fcfcd ("netfilter: fix netns dependencies with conntrack +templates") migrated templates to the new allocator api, but forgot to +update error paths for them in CT and synproxy to use nf_ct_tmpl_free() +instead of nf_conntrack_free(). + +Due to that, memory is being freed into the wrong kmemcache, but also +we drop the per net reference count of ct objects causing an imbalance. + +In Brad's case, this leads to a wrap-around of net->ct.count and thus +lets __nf_conntrack_alloc() refuse to create a new ct object: + + [ 10.340913] xt_addrtype: ipv6 does not support BROADCAST matching + [ 10.810168] nf_conntrack: table full, dropping packet + [ 11.917416] r8169 0000:07:00.0 eth0: link up + [ 11.917438] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready + [ 12.815902] nf_conntrack: table full, dropping packet + [ 15.688561] nf_conntrack: table full, dropping packet + [ 15.689365] nf_conntrack: table full, dropping packet + [ 15.690169] nf_conntrack: table full, dropping packet + [ 15.690967] nf_conntrack: table full, dropping packet + [...] + +With slab debugging, it also reports the wrong kmemcache (kmalloc-512 vs. +nf_conntrack_ffffffff81ce75c0) and reports poison overwrites, etc. Thus, +to fix the problem, export and use nf_ct_tmpl_free() instead. + +Fixes: 0838aa7fcfcd ("netfilter: fix netns dependencies with conntrack templates") +Reported-by: Brad Jackson +Signed-off-by: Daniel Borkmann +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_conntrack.h | 1 + + net/netfilter/nf_conntrack_core.c | 3 ++- + net/netfilter/nf_synproxy_core.c | 2 +- + net/netfilter/xt_CT.c | 2 +- + 4 files changed, 5 insertions(+), 3 deletions(-) + +--- a/include/net/netfilter/nf_conntrack.h ++++ b/include/net/netfilter/nf_conntrack.h +@@ -292,6 +292,7 @@ extern unsigned int nf_conntrack_hash_rn + void init_nf_conntrack_hash_rnd(void); + + struct nf_conn *nf_ct_tmpl_alloc(struct net *net, u16 zone, gfp_t flags); ++void nf_ct_tmpl_free(struct nf_conn *tmpl); + + #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) + #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -320,12 +320,13 @@ out_free: + } + EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc); + +-static void nf_ct_tmpl_free(struct nf_conn *tmpl) ++void nf_ct_tmpl_free(struct nf_conn *tmpl) + { + nf_ct_ext_destroy(tmpl); + nf_ct_ext_free(tmpl); + kfree(tmpl); + } ++EXPORT_SYMBOL_GPL(nf_ct_tmpl_free); + + static void + destroy_conntrack(struct nf_conntrack *nfct) +--- a/net/netfilter/nf_synproxy_core.c ++++ b/net/netfilter/nf_synproxy_core.c +@@ -378,7 +378,7 @@ static int __net_init synproxy_net_init( + err3: + free_percpu(snet->stats); + err2: +- nf_conntrack_free(ct); ++ nf_ct_tmpl_free(ct); + err1: + return err; + } +--- a/net/netfilter/xt_CT.c ++++ b/net/netfilter/xt_CT.c +@@ -233,7 +233,7 @@ out: + return 0; + + err3: +- nf_conntrack_free(ct); ++ nf_ct_tmpl_free(ct); + err2: + nf_ct_l3proto_module_put(par->family); + err1: diff --git a/queue-4.2/netfilter-ipset-fixing-unnamed-union-init.patch b/queue-4.2/netfilter-ipset-fixing-unnamed-union-init.patch new file mode 100644 index 00000000000..df95f32d95e --- /dev/null +++ b/queue-4.2/netfilter-ipset-fixing-unnamed-union-init.patch @@ -0,0 +1,154 @@ +From 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 Mon Sep 17 00:00:00 2001 +From: Elad Raz +Date: Sat, 22 Aug 2015 08:44:11 +0300 +Subject: netfilter: ipset: Fixing unnamed union init + +From: Elad Raz + +commit 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 upstream. + +In continue to proposed Vinson Lee's post [1], this patch fixes compilation +issues founded at gcc 4.4.7. The initialization of .cidr field of unnamed +unions causes compilation error in gcc 4.4.x. + +References + +Visible links +[1] https://lkml.org/lkml/2015/7/5/74 + +Signed-off-by: Elad Raz +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/ipset/ip_set_hash_netnet.c | 20 ++++++++++++++++++-- + net/netfilter/ipset/ip_set_hash_netportnet.c | 20 ++++++++++++++++++-- + 2 files changed, 36 insertions(+), 4 deletions(-) + +--- a/net/netfilter/ipset/ip_set_hash_netnet.c ++++ b/net/netfilter/ipset/ip_set_hash_netnet.c +@@ -131,6 +131,13 @@ hash_netnet4_data_next(struct hash_netne + #define HOST_MASK 32 + #include "ip_set_hash_gen.h" + ++static void ++hash_netnet4_init(struct hash_netnet4_elem *e) ++{ ++ e->cidr[0] = HOST_MASK; ++ e->cidr[1] = HOST_MASK; ++} ++ + static int + hash_netnet4_kadt(struct ip_set *set, const struct sk_buff *skb, + const struct xt_action_param *par, +@@ -160,7 +167,7 @@ hash_netnet4_uadt(struct ip_set *set, st + { + const struct hash_netnet *h = set->data; + ipset_adtfn adtfn = set->variant->adt[adt]; +- struct hash_netnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, }; ++ struct hash_netnet4_elem e = { }; + struct ip_set_ext ext = IP_SET_INIT_UEXT(set); + u32 ip = 0, ip_to = 0, last; + u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2; +@@ -169,6 +176,7 @@ hash_netnet4_uadt(struct ip_set *set, st + if (tb[IPSET_ATTR_LINENO]) + *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); + ++ hash_netnet4_init(&e); + if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || + !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) + return -IPSET_ERR_PROTOCOL; +@@ -357,6 +365,13 @@ hash_netnet6_data_next(struct hash_netne + #define IP_SET_EMIT_CREATE + #include "ip_set_hash_gen.h" + ++static void ++hash_netnet6_init(struct hash_netnet6_elem *e) ++{ ++ e->cidr[0] = HOST_MASK; ++ e->cidr[1] = HOST_MASK; ++} ++ + static int + hash_netnet6_kadt(struct ip_set *set, const struct sk_buff *skb, + const struct xt_action_param *par, +@@ -385,13 +400,14 @@ hash_netnet6_uadt(struct ip_set *set, st + enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) + { + ipset_adtfn adtfn = set->variant->adt[adt]; +- struct hash_netnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, }; ++ struct hash_netnet6_elem e = { }; + struct ip_set_ext ext = IP_SET_INIT_UEXT(set); + int ret; + + if (tb[IPSET_ATTR_LINENO]) + *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); + ++ hash_netnet6_init(&e); + if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || + !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) + return -IPSET_ERR_PROTOCOL; +--- a/net/netfilter/ipset/ip_set_hash_netportnet.c ++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c +@@ -142,6 +142,13 @@ hash_netportnet4_data_next(struct hash_n + #define HOST_MASK 32 + #include "ip_set_hash_gen.h" + ++static void ++hash_netportnet4_init(struct hash_netportnet4_elem *e) ++{ ++ e->cidr[0] = HOST_MASK; ++ e->cidr[1] = HOST_MASK; ++} ++ + static int + hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb, + const struct xt_action_param *par, +@@ -175,7 +182,7 @@ hash_netportnet4_uadt(struct ip_set *set + { + const struct hash_netportnet *h = set->data; + ipset_adtfn adtfn = set->variant->adt[adt]; +- struct hash_netportnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, }; ++ struct hash_netportnet4_elem e = { }; + struct ip_set_ext ext = IP_SET_INIT_UEXT(set); + u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to; + u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2; +@@ -185,6 +192,7 @@ hash_netportnet4_uadt(struct ip_set *set + if (tb[IPSET_ATTR_LINENO]) + *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); + ++ hash_netportnet4_init(&e); + if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || + !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || + !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || +@@ -412,6 +420,13 @@ hash_netportnet6_data_next(struct hash_n + #define IP_SET_EMIT_CREATE + #include "ip_set_hash_gen.h" + ++static void ++hash_netportnet6_init(struct hash_netportnet6_elem *e) ++{ ++ e->cidr[0] = HOST_MASK; ++ e->cidr[1] = HOST_MASK; ++} ++ + static int + hash_netportnet6_kadt(struct ip_set *set, const struct sk_buff *skb, + const struct xt_action_param *par, +@@ -445,7 +460,7 @@ hash_netportnet6_uadt(struct ip_set *set + { + const struct hash_netportnet *h = set->data; + ipset_adtfn adtfn = set->variant->adt[adt]; +- struct hash_netportnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, }; ++ struct hash_netportnet6_elem e = { }; + struct ip_set_ext ext = IP_SET_INIT_UEXT(set); + u32 port, port_to; + bool with_ports = false; +@@ -454,6 +469,7 @@ hash_netportnet6_uadt(struct ip_set *set + if (tb[IPSET_ATTR_LINENO]) + *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); + ++ hash_netportnet6_init(&e); + if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || + !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || + !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || diff --git a/queue-4.2/netfilter-ipset-out-of-bound-access-in-hash-net-types-fixed.patch b/queue-4.2/netfilter-ipset-out-of-bound-access-in-hash-net-types-fixed.patch new file mode 100644 index 00000000000..e531828c94c --- /dev/null +++ b/queue-4.2/netfilter-ipset-out-of-bound-access-in-hash-net-types-fixed.patch @@ -0,0 +1,87 @@ +From 6fe7ccfd77415a6ba250c10c580eb3f9acf79753 Mon Sep 17 00:00:00 2001 +From: Jozsef Kadlecsik +Date: Tue, 25 Aug 2015 11:17:51 +0200 +Subject: netfilter: ipset: Out of bound access in hash:net* types fixed + +From: Jozsef Kadlecsik + +commit 6fe7ccfd77415a6ba250c10c580eb3f9acf79753 upstream. + +Dave Jones reported that KASan detected out of bounds access in hash:net* +types: + +[ 23.139532] ================================================================== +[ 23.146130] BUG: KASan: out of bounds access in hash_net4_add_cidr+0x1db/0x220 at addr ffff8800d4844b58 +[ 23.152937] Write of size 4 by task ipset/457 +[ 23.159742] ============================================================================= +[ 23.166672] BUG kmalloc-512 (Not tainted): kasan: bad access detected +[ 23.173641] ----------------------------------------------------------------------------- +[ 23.194668] INFO: Allocated in hash_net_create+0x16a/0x470 age=7 cpu=1 pid=456 +[ 23.201836] __slab_alloc.constprop.66+0x554/0x620 +[ 23.208994] __kmalloc+0x2f2/0x360 +[ 23.216105] hash_net_create+0x16a/0x470 +[ 23.223238] ip_set_create+0x3e6/0x740 +[ 23.230343] nfnetlink_rcv_msg+0x599/0x640 +[ 23.237454] netlink_rcv_skb+0x14f/0x190 +[ 23.244533] nfnetlink_rcv+0x3f6/0x790 +[ 23.251579] netlink_unicast+0x272/0x390 +[ 23.258573] netlink_sendmsg+0x5a1/0xa50 +[ 23.265485] SYSC_sendto+0x1da/0x2c0 +[ 23.272364] SyS_sendto+0xe/0x10 +[ 23.279168] entry_SYSCALL_64_fastpath+0x12/0x6f + +The bug is fixed in the patch and the testsuite is extended in ipset +to check cidr handling more thoroughly. + +Signed-off-by: Jozsef Kadlecsik +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/ipset/ip_set_hash_gen.h | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -152,9 +152,13 @@ htable_bits(u32 hashsize) + #define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) + + #ifdef IP_SET_HASH_WITH_NET0 ++/* cidr from 0 to SET_HOST_MASK() value and c = cidr + 1 */ + #define NLEN(family) (SET_HOST_MASK(family) + 1) ++#define CIDR_POS(c) ((c) - 1) + #else ++/* cidr from 1 to SET_HOST_MASK() value and c = cidr + 1 */ + #define NLEN(family) SET_HOST_MASK(family) ++#define CIDR_POS(c) ((c) - 2) + #endif + + #else +@@ -305,7 +309,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, + } else if (h->nets[i].cidr[n] < cidr) { + j = i; + } else if (h->nets[i].cidr[n] == cidr) { +- h->nets[cidr - 1].nets[n]++; ++ h->nets[CIDR_POS(cidr)].nets[n]++; + return; + } + } +@@ -314,7 +318,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, + h->nets[i].cidr[n] = h->nets[i - 1].cidr[n]; + } + h->nets[i].cidr[n] = cidr; +- h->nets[cidr - 1].nets[n] = 1; ++ h->nets[CIDR_POS(cidr)].nets[n] = 1; + } + + static void +@@ -325,8 +329,8 @@ mtype_del_cidr(struct htype *h, u8 cidr, + for (i = 0; i < nets_length; i++) { + if (h->nets[i].cidr[n] != cidr) + continue; +- h->nets[cidr - 1].nets[n]--; +- if (h->nets[cidr - 1].nets[n] > 0) ++ h->nets[CIDR_POS(cidr)].nets[n]--; ++ if (h->nets[CIDR_POS(cidr)].nets[n] > 0) + return; + for (j = i; j < net_end && h->nets[j].cidr[n]; j++) + h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; diff --git a/queue-4.2/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch b/queue-4.2/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch new file mode 100644 index 00000000000..b361b5a7706 --- /dev/null +++ b/queue-4.2/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch @@ -0,0 +1,47 @@ +From 205ee117d4dc4a11ac3bd9638bb9b2e839f4de9a Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 9 Sep 2015 02:57:21 +0200 +Subject: netfilter: nf_log: don't zap all loggers on unregister + +From: Florian Westphal + +commit 205ee117d4dc4a11ac3bd9638bb9b2e839f4de9a upstream. + +like nf_log_unset, nf_log_unregister must not reset the list of loggers. +Otherwise, a call to nf_log_unregister() will render loggers of other nf +protocols unusable: + +iptables -A INPUT -j LOG +modprobe nf_log_arp ; rmmod nf_log_arp +iptables -A INPUT -j LOG +iptables: No chain/target/match by that name + +Fixes: 30e0c6a6be ("netfilter: nf_log: prepare net namespace support for loggers") +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_log.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -107,11 +107,15 @@ EXPORT_SYMBOL(nf_log_register); + + void nf_log_unregister(struct nf_logger *logger) + { ++ const struct nf_logger *log; + int i; + + mutex_lock(&nf_log_mutex); +- for (i = 0; i < NFPROTO_NUMPROTO; i++) +- RCU_INIT_POINTER(loggers[i][logger->type], NULL); ++ for (i = 0; i < NFPROTO_NUMPROTO; i++) { ++ log = nft_log_dereference(loggers[i][logger->type]); ++ if (log == logger) ++ RCU_INIT_POINTER(loggers[i][logger->type], NULL); ++ } + mutex_unlock(&nf_log_mutex); + synchronize_rcu(); + } diff --git a/queue-4.2/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch b/queue-4.2/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch new file mode 100644 index 00000000000..c6d01bde518 --- /dev/null +++ b/queue-4.2/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch @@ -0,0 +1,30 @@ +From ad5001cc7cdf9aaee5eb213fdee657e4a3c94776 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Thu, 17 Sep 2015 13:37:00 +0200 +Subject: netfilter: nf_log: wait for rcu grace after logger unregistration + +From: Pablo Neira Ayuso + +commit ad5001cc7cdf9aaee5eb213fdee657e4a3c94776 upstream. + +The nf_log_unregister() function needs to call synchronize_rcu() to make sure +that the objects are not dereferenced anymore on module removal. + +Fixes: 5962815a6a56 ("netfilter: nf_log: use an array of loggers instead of list") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_log.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -113,6 +113,7 @@ void nf_log_unregister(struct nf_logger + for (i = 0; i < NFPROTO_NUMPROTO; i++) + RCU_INIT_POINTER(loggers[i][logger->type], NULL); + mutex_unlock(&nf_log_mutex); ++ synchronize_rcu(); + } + EXPORT_SYMBOL(nf_log_unregister); + diff --git a/queue-4.2/netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch b/queue-4.2/netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch new file mode 100644 index 00000000000..7662475bcdf --- /dev/null +++ b/queue-4.2/netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch @@ -0,0 +1,32 @@ +From bf798657eb5ba57552096843c315f096fdf9b715 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 12 Aug 2015 17:41:00 +0200 +Subject: netfilter: nf_tables: Use 32 bit addressing register from nft_type_to_reg() + +From: Pablo Neira Ayuso + +commit bf798657eb5ba57552096843c315f096fdf9b715 upstream. + +nft_type_to_reg() needs to return the register in the new 32 bit addressing, +otherwise we hit EINVAL when using mappings. + +Fixes: 49499c3 ("netfilter: nf_tables: switch registers to 32 bit addressing") +Reported-by: Andreas Schultz +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_tables.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -125,7 +125,7 @@ static inline enum nft_data_types nft_dr + + static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) + { +- return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1; ++ return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE; + } + + unsigned int nft_parse_register(const struct nlattr *attr); diff --git a/queue-4.2/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch b/queue-4.2/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch new file mode 100644 index 00000000000..e678a342abf --- /dev/null +++ b/queue-4.2/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch @@ -0,0 +1,54 @@ +From a9de9777d613500b089a7416f936bf3ae5f070d2 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Fri, 28 Aug 2015 21:01:43 +0200 +Subject: netfilter: nfnetlink: work around wrong endianess in res_id field + +From: Pablo Neira Ayuso + +commit a9de9777d613500b089a7416f936bf3ae5f070d2 upstream. + +The convention in nfnetlink is to use network byte order in every header field +as well as in the attribute payload. The initial version of the batching +infrastructure assumes that res_id comes in host byte order though. + +The only client of the batching infrastructure is nf_tables, so let's add a +workaround to address this inconsistency. We currently have 11 nfnetlink +subsystems according to NFNL_SUBSYS_COUNT, so we can assume that the subsystem +2560, ie. htons(10), will not be allocated anytime soon, so it can be an alias +of nf_tables from the nfnetlink batching path when interpreting the res_id +field. + +Based on original patch from Florian Westphal. + +Reported-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nfnetlink.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nfnetlink.c ++++ b/net/netfilter/nfnetlink.c +@@ -444,6 +444,7 @@ done: + static void nfnetlink_rcv(struct sk_buff *skb) + { + struct nlmsghdr *nlh = nlmsg_hdr(skb); ++ u_int16_t res_id; + int msglen; + + if (nlh->nlmsg_len < NLMSG_HDRLEN || +@@ -468,7 +469,12 @@ static void nfnetlink_rcv(struct sk_buff + + nfgenmsg = nlmsg_data(nlh); + skb_pull(skb, msglen); +- nfnetlink_rcv_batch(skb, nlh, nfgenmsg->res_id); ++ /* Work around old nft using host byte order */ ++ if (nfgenmsg->res_id == NFNL_SUBSYS_NFTABLES) ++ res_id = NFNL_SUBSYS_NFTABLES; ++ else ++ res_id = ntohs(nfgenmsg->res_id); ++ nfnetlink_rcv_batch(skb, nlh, res_id); + } else { + netlink_rcv_skb(skb, &nfnetlink_rcv_msg); + } diff --git a/queue-4.2/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch b/queue-4.2/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch new file mode 100644 index 00000000000..a047b1c29c8 --- /dev/null +++ b/queue-4.2/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch @@ -0,0 +1,96 @@ +From ba378ca9c04a5fc1b2cf0f0274a9d02eb3d1bad9 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Mon, 14 Sep 2015 18:04:09 +0200 +Subject: netfilter: nft_compat: skip family comparison in case of NFPROTO_UNSPEC + +From: Pablo Neira Ayuso + +commit ba378ca9c04a5fc1b2cf0f0274a9d02eb3d1bad9 upstream. + +Fix lookup of existing match/target structures in the corresponding list +by skipping the family check if NFPROTO_UNSPEC is used. + +This is resulting in the allocation and insertion of one match/target +structure for each use of them. So this not only bloats memory +consumption but also severely affects the time to reload the ruleset +from the iptables-compat utility. + +After this patch, iptables-compat-restore and iptables-compat take +almost the same time to reload large rulesets. + +Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_compat.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -619,6 +619,13 @@ struct nft_xt { + + static struct nft_expr_type nft_match_type; + ++static bool nft_match_cmp(const struct xt_match *match, ++ const char *name, u32 rev, u32 family) ++{ ++ return strcmp(match->name, name) == 0 && match->revision == rev && ++ (match->family == NFPROTO_UNSPEC || match->family == family); ++} ++ + static const struct nft_expr_ops * + nft_match_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) +@@ -626,7 +633,7 @@ nft_match_select_ops(const struct nft_ct + struct nft_xt *nft_match; + struct xt_match *match; + char *mt_name; +- __u32 rev, family; ++ u32 rev, family; + + if (tb[NFTA_MATCH_NAME] == NULL || + tb[NFTA_MATCH_REV] == NULL || +@@ -641,8 +648,7 @@ nft_match_select_ops(const struct nft_ct + list_for_each_entry(nft_match, &nft_match_list, head) { + struct xt_match *match = nft_match->ops.data; + +- if (strcmp(match->name, mt_name) == 0 && +- match->revision == rev && match->family == family) { ++ if (nft_match_cmp(match, mt_name, rev, family)) { + if (!try_module_get(match->me)) + return ERR_PTR(-ENOENT); + +@@ -693,6 +699,13 @@ static LIST_HEAD(nft_target_list); + + static struct nft_expr_type nft_target_type; + ++static bool nft_target_cmp(const struct xt_target *tg, ++ const char *name, u32 rev, u32 family) ++{ ++ return strcmp(tg->name, name) == 0 && tg->revision == rev && ++ (tg->family == NFPROTO_UNSPEC || tg->family == family); ++} ++ + static const struct nft_expr_ops * + nft_target_select_ops(const struct nft_ctx *ctx, + const struct nlattr * const tb[]) +@@ -700,7 +713,7 @@ nft_target_select_ops(const struct nft_c + struct nft_xt *nft_target; + struct xt_target *target; + char *tg_name; +- __u32 rev, family; ++ u32 rev, family; + + if (tb[NFTA_TARGET_NAME] == NULL || + tb[NFTA_TARGET_REV] == NULL || +@@ -715,8 +728,7 @@ nft_target_select_ops(const struct nft_c + list_for_each_entry(nft_target, &nft_target_list, head) { + struct xt_target *target = nft_target->ops.data; + +- if (strcmp(target->name, tg_name) == 0 && +- target->revision == rev && target->family == family) { ++ if (nft_target_cmp(target, tg_name, rev, family)) { + if (!try_module_get(target->me)) + return ERR_PTR(-ENOENT); + diff --git a/queue-4.2/series b/queue-4.2/series index c8003d66be2..ec2496a5831 100644 --- a/queue-4.2/series +++ b/queue-4.2/series @@ -116,3 +116,12 @@ usb-option-add-zte-pids.patch md-raid0-update-queue-parameter-in-a-safer-location.patch md-raid0-apply-base-queue-limits-before-disk_stack_limits.patch dm-raid-fix-round-up-of-default-region-size.patch +netfilter-bridge-fix-ipv6-packets-not-being-bridged-with-config_ipv6-n.patch +netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch +netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch +netfilter-ipset-out-of-bound-access-in-hash-net-types-fixed.patch +netfilter-ipset-fixing-unnamed-union-init.patch +netfilter-conntrack-use-nf_ct_tmpl_free-in-ct-synproxy-error-paths.patch +netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch +netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch +netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch