Commit 03d7dc5c authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: conntrack: check netns when walking expect hash

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent cb39ad8b
...@@ -301,6 +301,9 @@ static int exp_seq_show(struct seq_file *s, void *v) ...@@ -301,6 +301,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
exp = hlist_entry(n, struct nf_conntrack_expect, hnode); exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
if (!net_eq(nf_ct_net(exp->master), seq_file_net(s)))
return 0;
if (exp->tuple.src.l3num != AF_INET) if (exp->tuple.src.l3num != AF_INET)
return 0; return 0;
......
...@@ -86,6 +86,17 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple ...@@ -86,6 +86,17 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
return reciprocal_scale(hash, nf_ct_expect_hsize); return reciprocal_scale(hash, nf_ct_expect_hsize);
} }
static bool
nf_ct_exp_equal(const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_expect *i,
const struct nf_conntrack_zone *zone,
const struct net *net)
{
return nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) &&
net_eq(net, nf_ct_net(i->master)) &&
nf_ct_zone_equal_any(i->master, zone);
}
struct nf_conntrack_expect * struct nf_conntrack_expect *
__nf_ct_expect_find(struct net *net, __nf_ct_expect_find(struct net *net,
const struct nf_conntrack_zone *zone, const struct nf_conntrack_zone *zone,
...@@ -99,8 +110,7 @@ __nf_ct_expect_find(struct net *net, ...@@ -99,8 +110,7 @@ __nf_ct_expect_find(struct net *net,
h = nf_ct_expect_dst_hash(tuple); h = nf_ct_expect_dst_hash(tuple);
hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) { hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) {
if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) && if (nf_ct_exp_equal(tuple, i, zone, net))
nf_ct_zone_equal_any(i->master, zone))
return i; return i;
} }
return NULL; return NULL;
...@@ -141,8 +151,7 @@ nf_ct_find_expectation(struct net *net, ...@@ -141,8 +151,7 @@ nf_ct_find_expectation(struct net *net,
h = nf_ct_expect_dst_hash(tuple); h = nf_ct_expect_dst_hash(tuple);
hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) { hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) {
if (!(i->flags & NF_CT_EXPECT_INACTIVE) && if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) && nf_ct_exp_equal(tuple, i, zone, net)) {
nf_ct_zone_equal_any(i->master, zone)) {
exp = i; exp = i;
break; break;
} }
...@@ -222,6 +231,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a, ...@@ -222,6 +231,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
} }
return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) && return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) &&
net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
} }
...@@ -231,6 +241,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a, ...@@ -231,6 +241,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
return a->master == b->master && a->class == b->class && return a->master == b->master && a->class == b->class &&
nf_ct_tuple_equal(&a->tuple, &b->tuple) && nf_ct_tuple_equal(&a->tuple, &b->tuple) &&
nf_ct_tuple_mask_equal(&a->mask, &b->mask) && nf_ct_tuple_mask_equal(&a->mask, &b->mask) &&
net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
} }
......
...@@ -2636,6 +2636,10 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -2636,6 +2636,10 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
hnode) { hnode) {
if (l3proto && exp->tuple.src.l3num != l3proto) if (l3proto && exp->tuple.src.l3num != l3proto)
continue; continue;
if (!net_eq(nf_ct_net(exp->master), net))
continue;
if (cb->args[1]) { if (cb->args[1]) {
if (exp != last) if (exp != last)
continue; continue;
...@@ -2888,6 +2892,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, ...@@ -2888,6 +2892,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
hlist_for_each_entry_safe(exp, next, hlist_for_each_entry_safe(exp, next,
&net->ct.expect_hash[i], &net->ct.expect_hash[i],
hnode) { hnode) {
if (!net_eq(nf_ct_exp_net(exp), net))
continue;
m_help = nfct_help(exp->master); m_help = nfct_help(exp->master);
if (!strcmp(m_help->helper->name, name) && if (!strcmp(m_help->helper->name, name) &&
del_timer(&exp->timeout)) { del_timer(&exp->timeout)) {
...@@ -2906,6 +2914,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl, ...@@ -2906,6 +2914,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
hlist_for_each_entry_safe(exp, next, hlist_for_each_entry_safe(exp, next,
&net->ct.expect_hash[i], &net->ct.expect_hash[i],
hnode) { hnode) {
if (!net_eq(nf_ct_exp_net(exp), net))
continue;
if (del_timer(&exp->timeout)) { if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect_report(exp, nf_ct_unlink_expect_report(exp,
NETLINK_CB(skb).portid, NETLINK_CB(skb).portid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment