diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-12-10 23:07:42 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-12-16 17:44:12 -0500 |
commit | 252b3e8c1bc0c2b20348ae87d67efcd0a8209f72 (patch) | |
tree | 369400efc56df50e5fa1467ffd84fbe43f264f40 /net | |
parent | 0c36b48b36dc84d4215dc9d1cde1bda829214ba6 (diff) |
netfilter: xt_CT: fix crash while destroy ct templates
In (d871bef netfilter: ctnetlink: dump entries from the dying and
unconfirmed lists), we assume that all conntrack objects are
inserted in any of the existing lists. However, template conntrack
objects were not. This results in hitting BUG_ON in the
destroy_conntrack path while removing a rule that uses the CT target.
This patch fixes the situation by adding the template lists, which
is where template conntrack objects reside now.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_CT.c | 8 |
2 files changed, 10 insertions, 0 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 08cdc71d8e87..016d95ead930 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1526,6 +1526,7 @@ err_extend: | |||
1526 | */ | 1526 | */ |
1527 | #define UNCONFIRMED_NULLS_VAL ((1<<30)+0) | 1527 | #define UNCONFIRMED_NULLS_VAL ((1<<30)+0) |
1528 | #define DYING_NULLS_VAL ((1<<30)+1) | 1528 | #define DYING_NULLS_VAL ((1<<30)+1) |
1529 | #define TEMPLATE_NULLS_VAL ((1<<30)+2) | ||
1529 | 1530 | ||
1530 | static int nf_conntrack_init_net(struct net *net) | 1531 | static int nf_conntrack_init_net(struct net *net) |
1531 | { | 1532 | { |
@@ -1534,6 +1535,7 @@ static int nf_conntrack_init_net(struct net *net) | |||
1534 | atomic_set(&net->ct.count, 0); | 1535 | atomic_set(&net->ct.count, 0); |
1535 | INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL); | 1536 | INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL); |
1536 | INIT_HLIST_NULLS_HEAD(&net->ct.dying, DYING_NULLS_VAL); | 1537 | INIT_HLIST_NULLS_HEAD(&net->ct.dying, DYING_NULLS_VAL); |
1538 | INIT_HLIST_NULLS_HEAD(&net->ct.tmpl, TEMPLATE_NULLS_VAL); | ||
1537 | net->ct.stat = alloc_percpu(struct ip_conntrack_stat); | 1539 | net->ct.stat = alloc_percpu(struct ip_conntrack_stat); |
1538 | if (!net->ct.stat) { | 1540 | if (!net->ct.stat) { |
1539 | ret = -ENOMEM; | 1541 | ret = -ENOMEM; |
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index ae7f5daeee43..1668f41acc6e 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
@@ -149,6 +149,10 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) | |||
149 | 149 | ||
150 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); | 150 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); |
151 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); | 151 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); |
152 | |||
153 | /* Overload tuple linked list to put us in template list. */ | ||
154 | hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
155 | &par->net->ct.tmpl); | ||
152 | out: | 156 | out: |
153 | info->ct = ct; | 157 | info->ct = ct; |
154 | return 0; | 158 | return 0; |
@@ -289,6 +293,10 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
289 | 293 | ||
290 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); | 294 | __set_bit(IPS_TEMPLATE_BIT, &ct->status); |
291 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); | 295 | __set_bit(IPS_CONFIRMED_BIT, &ct->status); |
296 | |||
297 | /* Overload tuple linked list to put us in template list. */ | ||
298 | hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode, | ||
299 | &par->net->ct.tmpl); | ||
292 | out: | 300 | out: |
293 | info->ct = ct; | 301 | info->ct = ct; |
294 | return 0; | 302 | return 0; |