Backport netfilter panic fix (rhbz 1015989)
This commit is contained in:
parent
76620421ec
commit
07775e21b6
@ -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@fedoraproject.org>
|
||||
- Backport netfilter panic fix (rhbz 1015989)
|
||||
|
||||
* Sun Jun 29 2014 Peter Robinson <pbrobinson@fedoraproject.org>
|
||||
- Rebase ARM based BeagleBone and Utilite stable patches
|
||||
|
||||
|
98
netfilter-nf_nat-fix-oops-on-netns-removal.patch
Normal file
98
netfilter-nf_nat-fix-oops-on-netns-removal.patch
Normal file
@ -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@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@aberdeencloud.com>
|
||||
Debugged-by: Samu Kallio <samu.kallio@aberdeencloud.com>
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
Tested-by: Samu Kallio <samu.kallio@aberdeencloud.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@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
|
||||
|
Loading…
Reference in New Issue
Block a user