From 4ab7f0e85e69b47eea0cda372c53b9fbb7ef7eb9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 17 Oct 2015 12:48:45 -0700 Subject: [PATCH] 4.1-stable patches added patches: netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch netfilter-nf_conntrack-support-expectations-in-different-zones.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_qeueue-drop-queue-entries-on-nf_unregister_hook.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 netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.patch --- ...nces-to-master-ct-and-expect-objects.patch | 35 ++++ ...port-expectations-in-different-zones.patch | 36 ++++ ...-don-t-zap-all-loggers-on-unregister.patch | 47 +++++ ...cu-grace-after-logger-unregistration.patch | 30 +++ ...-queue-entries-on-nf_unregister_hook.patch | 172 ++++++++++++++++++ ...essing-register-from-nft_type_to_reg.patch | 32 ++++ ...ound-wrong-endianess-in-res_id-field.patch | 54 ++++++ ...comparison-in-case-of-nfproto_unspec.patch | 96 ++++++++++ ...hains-in-the-wrong-network-namespace.patch | 48 +++++ queue-4.1/series | 9 + 10 files changed, 559 insertions(+) create mode 100644 queue-4.1/netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch create mode 100644 queue-4.1/netfilter-nf_conntrack-support-expectations-in-different-zones.patch create mode 100644 queue-4.1/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch create mode 100644 queue-4.1/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch create mode 100644 queue-4.1/netfilter-nf_qeueue-drop-queue-entries-on-nf_unregister_hook.patch create mode 100644 queue-4.1/netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch create mode 100644 queue-4.1/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch create mode 100644 queue-4.1/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch create mode 100644 queue-4.1/netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.patch diff --git a/queue-4.1/netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch b/queue-4.1/netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch new file mode 100644 index 00000000000..7ac864d7ff3 --- /dev/null +++ b/queue-4.1/netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch @@ -0,0 +1,35 @@ +From 95dd8653de658143770cb0e55a58d2aab97c79d2 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Thu, 9 Jul 2015 22:56:00 +0200 +Subject: netfilter: ctnetlink: put back references to master ct and expect objects + +From: Pablo Neira Ayuso + +commit 95dd8653de658143770cb0e55a58d2aab97c79d2 upstream. + +We have to put back the references to the master conntrack and the expectation +that we just created, otherwise we'll leak them. + +Fixes: 0ef71ee1a5b9 ("netfilter: ctnetlink: refactor ctnetlink_create_expect") +Reported-by: Tim Wiess +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_conntrack_netlink.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -2995,11 +2995,6 @@ ctnetlink_create_expect(struct net *net, + } + + err = nf_ct_expect_related_report(exp, portid, report); +- if (err < 0) +- goto err_exp; +- +- return 0; +-err_exp: + nf_ct_expect_put(exp); + err_ct: + nf_ct_put(ct); diff --git a/queue-4.1/netfilter-nf_conntrack-support-expectations-in-different-zones.patch b/queue-4.1/netfilter-nf_conntrack-support-expectations-in-different-zones.patch new file mode 100644 index 00000000000..d7aa7838c4f --- /dev/null +++ b/queue-4.1/netfilter-nf_conntrack-support-expectations-in-different-zones.patch @@ -0,0 +1,36 @@ +From 4b31814d20cbe5cd4ccf18089751e77a04afe4f2 Mon Sep 17 00:00:00 2001 +From: Joe Stringer +Date: Tue, 21 Jul 2015 21:37:31 -0700 +Subject: netfilter: nf_conntrack: Support expectations in different zones + +From: Joe Stringer + +commit 4b31814d20cbe5cd4ccf18089751e77a04afe4f2 upstream. + +When zones were originally introduced, the expectation functions were +all extended to perform lookup using the zone. However, insertion was +not modified to check the zone. This means that two expectations which +are intended to apply for different connections that have the same tuple +but exist in different zones cannot both be tracked. + +Fixes: 5d0aa2ccd4 (netfilter: nf_conntrack: add support for "conntrack zones") +Signed-off-by: Joe Stringer +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_conntrack_expect.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nf_conntrack_expect.c ++++ b/net/netfilter/nf_conntrack_expect.c +@@ -219,7 +219,8 @@ static inline int expect_clash(const str + a->mask.src.u3.all[count] & b->mask.src.u3.all[count]; + } + +- return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask); ++ return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) && ++ nf_ct_zone(a->master) == nf_ct_zone(b->master); + } + + static inline int expect_matches(const struct nf_conntrack_expect *a, diff --git a/queue-4.1/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch b/queue-4.1/netfilter-nf_log-don-t-zap-all-loggers-on-unregister.patch new file mode 100644 index 00000000000..b361b5a7706 --- /dev/null +++ b/queue-4.1/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.1/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch b/queue-4.1/netfilter-nf_log-wait-for-rcu-grace-after-logger-unregistration.patch new file mode 100644 index 00000000000..c6d01bde518 --- /dev/null +++ b/queue-4.1/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.1/netfilter-nf_qeueue-drop-queue-entries-on-nf_unregister_hook.patch b/queue-4.1/netfilter-nf_qeueue-drop-queue-entries-on-nf_unregister_hook.patch new file mode 100644 index 00000000000..33ced38ad92 --- /dev/null +++ b/queue-4.1/netfilter-nf_qeueue-drop-queue-entries-on-nf_unregister_hook.patch @@ -0,0 +1,172 @@ +From 8405a8fff3f8545c888a872d6e3c0c8eecd4d348 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 19 Jun 2015 14:03:39 -0500 +Subject: netfilter: nf_qeueue: Drop queue entries on nf_unregister_hook + +From: "Eric W. Biederman" + +commit 8405a8fff3f8545c888a872d6e3c0c8eecd4d348 upstream. + +Add code to nf_unregister_hook to flush the nf_queue when a hook is +unregistered. This guarantees that the pointer that the nf_queue code +retains into the nf_hook list will remain valid while a packet is +queued. + +I tested what would happen if we do not flush queued packets and was +trivially able to obtain the oops below. All that was required was +to stop the nf_queue listening process, to delete all of the nf_tables, +and to awaken the nf_queue listening process. + +> BUG: unable to handle kernel paging request at 0000000100000001 +> IP: [<0000000100000001>] 0x100000001 +> PGD b9c35067 PUD 0 +> Oops: 0010 [#1] SMP +> Modules linked in: +> CPU: 0 PID: 519 Comm: lt-nfqnl_test Not tainted +> task: ffff8800b9c8c050 ti: ffff8800ba9d8000 task.ti: ffff8800ba9d8000 +> RIP: 0010:[<0000000100000001>] [<0000000100000001>] 0x100000001 +> RSP: 0018:ffff8800ba9dba40 EFLAGS: 00010a16 +> RAX: ffff8800bab48a00 RBX: ffff8800ba9dba90 RCX: ffff8800ba9dba90 +> RDX: ffff8800b9c10128 RSI: ffff8800ba940900 RDI: ffff8800bab48a00 +> RBP: ffff8800b9c10128 R08: ffffffff82976660 R09: ffff8800ba9dbb28 +> R10: dead000000100100 R11: dead000000200200 R12: ffff8800ba940900 +> R13: ffffffff8313fd50 R14: ffff8800b9c95200 R15: 0000000000000000 +> FS: 00007fb91fc34700(0000) GS:ffff8800bfa00000(0000) knlGS:0000000000000000 +> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +> CR2: 0000000100000001 CR3: 00000000babfb000 CR4: 00000000000007f0 +> Stack: +> ffffffff8206ab0f ffffffff82982240 ffff8800bab48a00 ffff8800b9c100a8 +> ffff8800b9c10100 0000000000000001 ffff8800ba940900 ffff8800b9c10128 +> ffffffff8206bd65 ffff8800bfb0d5e0 ffff8800bab48a00 0000000000014dc0 +> Call Trace: +> [] ? nf_iterate+0x4f/0xa0 +> [] ? nf_reinject+0x125/0x190 +> [] ? nfqnl_recv_verdict+0x255/0x360 +> [] ? nla_parse+0x80/0xf0 +> [] ? nfnetlink_rcv_msg+0x13c/0x240 +> [] ? __memcg_kmem_get_cache+0x4c/0x150 +> [] ? nfnl_lock+0x20/0x20 +> [] ? netlink_rcv_skb+0xa9/0xc0 +> [] ? netlink_unicast+0x12f/0x1c0 +> [] ? netlink_sendmsg+0x28e/0x650 +> [] ? sock_sendmsg+0x44/0x50 +> [] ? ___sys_sendmsg+0x2ab/0x2c0 +> [] ? __wake_up+0x43/0x70 +> [] ? tty_write+0x1c4/0x2a0 +> [] ? __sys_sendmsg+0x44/0x80 +> [] ? system_call_fastpath+0x12/0x6a +> Code: Bad RIP value. +> RIP [<0000000100000001>] 0x100000001 +> RSP +> CR2: 0000000100000001 +> ---[ end trace 08eb65d42362793f ]--- + +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_queue.h | 2 ++ + net/netfilter/core.c | 1 + + net/netfilter/nf_internals.h | 1 + + net/netfilter/nf_queue.c | 17 +++++++++++++++++ + net/netfilter/nfnetlink_queue_core.c | 24 +++++++++++++++++++++++- + 5 files changed, 44 insertions(+), 1 deletion(-) + +--- a/include/net/netfilter/nf_queue.h ++++ b/include/net/netfilter/nf_queue.h +@@ -24,6 +24,8 @@ struct nf_queue_entry { + struct nf_queue_handler { + int (*outfn)(struct nf_queue_entry *entry, + unsigned int queuenum); ++ void (*nf_hook_drop)(struct net *net, ++ struct nf_hook_ops *ops); + }; + + void nf_register_queue_handler(const struct nf_queue_handler *qh); +--- a/net/netfilter/core.c ++++ b/net/netfilter/core.c +@@ -89,6 +89,7 @@ void nf_unregister_hook(struct nf_hook_o + static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); + #endif + synchronize_net(); ++ nf_queue_nf_hook_drop(reg); + } + EXPORT_SYMBOL(nf_unregister_hook); + +--- a/net/netfilter/nf_internals.h ++++ b/net/netfilter/nf_internals.h +@@ -19,6 +19,7 @@ unsigned int nf_iterate(struct list_head + /* nf_queue.c */ + int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem, + struct nf_hook_state *state, unsigned int queuenum); ++void nf_queue_nf_hook_drop(struct nf_hook_ops *ops); + int __init netfilter_queue_init(void); + + /* nf_log.c */ +--- a/net/netfilter/nf_queue.c ++++ b/net/netfilter/nf_queue.c +@@ -105,6 +105,23 @@ bool nf_queue_entry_get_refs(struct nf_q + } + EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs); + ++void nf_queue_nf_hook_drop(struct nf_hook_ops *ops) ++{ ++ const struct nf_queue_handler *qh; ++ struct net *net; ++ ++ rtnl_lock(); ++ rcu_read_lock(); ++ qh = rcu_dereference(queue_handler); ++ if (qh) { ++ for_each_net(net) { ++ qh->nf_hook_drop(net, ops); ++ } ++ } ++ rcu_read_unlock(); ++ rtnl_unlock(); ++} ++ + /* + * Any packet that leaves via this function must come back + * through nf_reinject(). +--- a/net/netfilter/nfnetlink_queue_core.c ++++ b/net/netfilter/nfnetlink_queue_core.c +@@ -824,6 +824,27 @@ static struct notifier_block nfqnl_dev_n + .notifier_call = nfqnl_rcv_dev_event, + }; + ++static int nf_hook_cmp(struct nf_queue_entry *entry, unsigned long ops_ptr) ++{ ++ return entry->elem == (struct nf_hook_ops *)ops_ptr; ++} ++ ++static void nfqnl_nf_hook_drop(struct net *net, struct nf_hook_ops *hook) ++{ ++ struct nfnl_queue_net *q = nfnl_queue_pernet(net); ++ int i; ++ ++ rcu_read_lock(); ++ for (i = 0; i < INSTANCE_BUCKETS; i++) { ++ struct nfqnl_instance *inst; ++ struct hlist_head *head = &q->instance_table[i]; ++ ++ hlist_for_each_entry_rcu(inst, head, hlist) ++ nfqnl_flush(inst, nf_hook_cmp, (unsigned long)hook); ++ } ++ rcu_read_unlock(); ++} ++ + static int + nfqnl_rcv_nl_event(struct notifier_block *this, + unsigned long event, void *ptr) +@@ -1031,7 +1052,8 @@ static const struct nla_policy nfqa_cfg_ + }; + + static const struct nf_queue_handler nfqh = { +- .outfn = &nfqnl_enqueue_packet, ++ .outfn = &nfqnl_enqueue_packet, ++ .nf_hook_drop = &nfqnl_nf_hook_drop, + }; + + static int diff --git a/queue-4.1/netfilter-nf_tables-use-32-bit-addressing-register-from-nft_type_to_reg.patch b/queue-4.1/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.1/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.1/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch b/queue-4.1/netfilter-nfnetlink-work-around-wrong-endianess-in-res_id-field.patch new file mode 100644 index 00000000000..9fe323fd725 --- /dev/null +++ b/queue-4.1/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 +@@ -432,6 +432,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 || +@@ -456,7 +457,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.1/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch b/queue-4.1/netfilter-nft_compat-skip-family-comparison-in-case-of-nfproto_unspec.patch new file mode 100644 index 00000000000..39b3273f51f --- /dev/null +++ b/queue-4.1/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 +@@ -617,6 +617,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[]) +@@ -624,7 +631,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 || +@@ -639,8 +646,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); + +@@ -691,6 +697,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[]) +@@ -698,7 +711,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 || +@@ -713,8 +726,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.1/netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.patch b/queue-4.1/netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.patch new file mode 100644 index 00000000000..1d55b9acb54 --- /dev/null +++ b/queue-4.1/netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.patch @@ -0,0 +1,48 @@ +From fdab6a4cbd8933092155449ca7253eba973ada14 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 19 Jun 2015 10:41:21 -0500 +Subject: netfilter: nftables: Do not run chains in the wrong network namespace + +From: "Eric W. Biederman" + +commit fdab6a4cbd8933092155449ca7253eba973ada14 upstream. + +Currenlty nf_tables chains added in one network namespace are being +run in all network namespace. The issues are myriad with the simplest +being an unprivileged user can cause any network packets to be dropped. + +Address this by simply not running nf_tables chains in the wrong +network namespace. + +Signed-off-by: "Eric W. Biederman" +Acked-by: Pablo Neira Ayuso +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_core.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nf_tables_core.c ++++ b/net/netfilter/nf_tables_core.c +@@ -114,7 +114,8 @@ unsigned int + nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) + { + const struct nft_chain *chain = ops->priv, *basechain = chain; +- const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet); ++ const struct net *chain_net = read_pnet(&nft_base_chain(basechain)->pnet); ++ const struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); + const struct nft_rule *rule; + const struct nft_expr *expr, *last; + struct nft_regs regs; +@@ -124,6 +125,10 @@ nft_do_chain(struct nft_pktinfo *pkt, co + int rulenum; + unsigned int gencursor = nft_genmask_cur(net); + ++ /* Ignore chains that are not for the current network namespace */ ++ if (!net_eq(net, chain_net)) ++ return NF_ACCEPT; ++ + do_chain: + rulenum = 0; + rule = list_entry(&chain->rules, struct nft_rule, list); diff --git a/queue-4.1/series b/queue-4.1/series index 29a7b5addd7..2eba4c60630 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -83,3 +83,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-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-nf_conntrack-support-expectations-in-different-zones.patch +netfilter-ctnetlink-put-back-references-to-master-ct-and-expect-objects.patch +netfilter-nf_qeueue-drop-queue-entries-on-nf_unregister_hook.patch +netfilter-nftables-do-not-run-chains-in-the-wrong-network-namespace.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 -- 2.47.2