]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.9/netfilter-nf_conntrack-fix-memory-corruption-with-multiple-namespaces.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.9 / netfilter-nf_conntrack-fix-memory-corruption-with-multiple-namespaces.patch
CommitLineData
739e1c91
GKH
1From 9edd7ca0a3e3999c260642c92fa008892d82ca6e Mon Sep 17 00:00:00 2001
2From: Patrick McHardy <kaber@trash.net>
3Date: Mon, 8 Feb 2010 11:16:26 -0800
4Subject: netfilter: nf_conntrack: fix memory corruption with multiple namespaces
5
6From: Patrick McHardy <kaber@trash.net>
7
8commit 9edd7ca0a3e3999c260642c92fa008892d82ca6e upstream.
9
10As discovered by Jon Masters <jonathan@jonmasters.org>, the "untracked"
11conntrack, which is located in the data section, might be accidentally
12freed when a new namespace is instantiated while the untracked conntrack
13is attached to a skb because the reference count it re-initialized.
14
15The best fix would be to use a seperate untracked conntrack per
16namespace since it includes a namespace pointer. Unfortunately this is
17not possible without larger changes since the namespace is not easily
18available everywhere we need it. For now move the untracked conntrack
19initialization to the init_net setup function to make sure the reference
20count is not re-initialized and handle cleanup in the init_net cleanup
21function to make sure namespaces can exit properly while the untracked
22conntrack is in use in other namespaces.
23
24Signed-off-by: Patrick McHardy <kaber@trash.net>
25Signed-off-by: David S. Miller <davem@davemloft.net>
26Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
27
28---
29 net/netfilter/nf_conntrack_core.c | 24 ++++++++++++------------
30 1 file changed, 12 insertions(+), 12 deletions(-)
31
32--- a/net/netfilter/nf_conntrack_core.c
33+++ b/net/netfilter/nf_conntrack_core.c
34@@ -1107,6 +1107,10 @@ static void nf_ct_release_dying_list(str
35
36 static void nf_conntrack_cleanup_init_net(void)
37 {
38+ /* wait until all references to nf_conntrack_untracked are dropped */
39+ while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
40+ schedule();
41+
42 nf_conntrack_helper_fini();
43 nf_conntrack_proto_fini();
44 kmem_cache_destroy(nf_conntrack_cachep);
45@@ -1121,9 +1125,6 @@ static void nf_conntrack_cleanup_net(str
46 schedule();
47 goto i_see_dead_people;
48 }
49- /* wait until all references to nf_conntrack_untracked are dropped */
50- while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
51- schedule();
52
53 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
54 nf_conntrack_htable_size);
55@@ -1282,6 +1283,14 @@ static int nf_conntrack_init_init_net(vo
56 if (ret < 0)
57 goto err_helper;
58
59+ /* Set up fake conntrack: to never be deleted, not in any hashes */
60+#ifdef CONFIG_NET_NS
61+ nf_conntrack_untracked.ct_net = &init_net;
62+#endif
63+ atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
64+ /* - and look it like as a confirmed connection */
65+ set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
66+
67 return 0;
68
69 err_helper:
70@@ -1327,15 +1336,6 @@ static int nf_conntrack_init_net(struct
71 if (ret < 0)
72 goto err_ecache;
73
74- /* Set up fake conntrack:
75- - to never be deleted, not in any hashes */
76-#ifdef CONFIG_NET_NS
77- nf_conntrack_untracked.ct_net = &init_net;
78-#endif
79- atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
80- /* - and look it like as a confirmed connection */
81- set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
82-
83 return 0;
84
85 err_ecache: