[kernel/stabilization] Backport netfilter panic fix (rhbz 1015989)

Josh Boyer jwboyer at fedoraproject.org
Mon Jun 30 19:21:02 UTC 2014


commit 07775e21b6d0c7b9c2251deb8cb5ef3052a38c6e
Author: Josh Boyer <jwboyer at fedoraproject.org>
Date:   Mon Jun 30 15:21:06 2014 -0400

    Backport netfilter panic fix (rhbz 1015989)

 kernel.spec                                      |    9 ++
 netfilter-nf_nat-fix-oops-on-netns-removal.patch |   98 ++++++++++++++++++++++
 2 files changed, 107 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 09674a1..b64eb4e 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -752,6 +752,9 @@ Patch25109: revert-input-wacom-testing-result-shows-get_report-is-unnecessary.pa
 #rhbz 1021036, submitted upstream
 Patch25110: 0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch
 
+#rhbz 1015989
+Patch25111: netfilter-nf_nat-fix-oops-on-netns-removal.patch
+
 # END OF PATCH DEFINITIONS
 
 %endif
@@ -1472,6 +1475,9 @@ ApplyPatch revert-input-wacom-testing-result-shows-get_report-is-unnecessary.pat
 #rhbz 1021036, submitted upstream
 ApplyPatch 0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch
 
+#rhbz 1015989
+ApplyPatch netfilter-nf_nat-fix-oops-on-netns-removal.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2284,6 +2290,9 @@ fi
 #                                    ||----w |
 #                                    ||     ||
 %changelog
+* Mon Jun 30 2014 Josh Boyer <jwboyer at fedoraproject.org>
+- Backport netfilter panic fix (rhbz 1015989)
+
 * Sun Jun 29 2014 Peter Robinson <pbrobinson at fedoraproject.org>
 - Rebase ARM based BeagleBone and Utilite stable patches
 
diff --git a/netfilter-nf_nat-fix-oops-on-netns-removal.patch b/netfilter-nf_nat-fix-oops-on-netns-removal.patch
new file mode 100644
index 0000000..4cd5218
--- /dev/null
+++ b/netfilter-nf_nat-fix-oops-on-netns-removal.patch
@@ -0,0 +1,98 @@
+Bugzilla: 1015989
+Upstream-status: 3.16-rc3 and queued for stable
+
+From 945b2b2d259d1a4364a2799e80e8ff32f8c6ee6f Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw at strlen.de>
+Date: Sat, 7 Jun 2014 21:17:04 +0200
+Subject: [PATCH] netfilter: nf_nat: fix oops on netns removal
+
+Quoting Samu Kallio:
+
+ Basically what's happening is, during netns cleanup,
+ nf_nat_net_exit gets called before ipv4_net_exit. As I understand
+ it, nf_nat_net_exit is supposed to kill any conntrack entries which
+ have NAT context (through nf_ct_iterate_cleanup), but for some
+ reason this doesn't happen (perhaps something else is still holding
+ refs to those entries?).
+
+ When ipv4_net_exit is called, conntrack entries (including those
+ with NAT context) are cleaned up, but the
+ nat_bysource hashtable is long gone - freed in nf_nat_net_exit. The
+ bug happens when attempting to free a conntrack entry whose NAT hash
+ 'prev' field points to a slot in the freed hash table (head for that
+ bin).
+
+We ignore conntracks with null nat bindings.  But this is wrong,
+as these are in bysource hash table as well.
+
+Restore nat-cleaning for the netns-is-being-removed case.
+
+bug:
+https://bugzilla.kernel.org/show_bug.cgi?id=65191
+
+Fixes: c2d421e1718 ('netfilter: nf_nat: fix race when unloading protocol modules')
+Reported-by: Samu Kallio <samu.kallio at aberdeencloud.com>
+Debugged-by: Samu Kallio <samu.kallio at aberdeencloud.com>
+Signed-off-by: Florian Westphal <fw at strlen.de>
+Tested-by: Samu Kallio <samu.kallio at aberdeencloud.com>
+Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
+---
+ net/netfilter/nf_nat_core.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index 09096a670c45..a49907b1dabc 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -525,6 +525,39 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data)
+ 	return i->status & IPS_NAT_MASK ? 1 : 0;
+ }
+ 
++static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
++{
++	struct nf_conn_nat *nat = nfct_nat(ct);
++
++	if (nf_nat_proto_remove(ct, data))
++		return 1;
++
++	if (!nat || !nat->ct)
++		return 0;
++
++	/* This netns is being destroyed, and conntrack has nat null binding.
++	 * Remove it from bysource hash, as the table will be freed soon.
++	 *
++	 * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
++	 * will delete entry from already-freed table.
++	 */
++	if (!del_timer(&ct->timeout))
++		return 1;
++
++	spin_lock_bh(&nf_nat_lock);
++	hlist_del_rcu(&nat->bysource);
++	ct->status &= ~IPS_NAT_DONE_MASK;
++	nat->ct = NULL;
++	spin_unlock_bh(&nf_nat_lock);
++
++	add_timer(&ct->timeout);
++
++	/* don't delete conntrack.  Although that would make things a lot
++	 * simpler, we'd end up flushing all conntracks on nat rmmod.
++	 */
++	return 0;
++}
++
+ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
+ {
+ 	struct nf_nat_proto_clean clean = {
+@@ -795,7 +828,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
+ {
+ 	struct nf_nat_proto_clean clean = {};
+ 
+-	nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
++	nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
+ 	synchronize_rcu();
+ 	nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
+ }
+-- 
+1.9.3
+


More information about the scm-commits mailing list