netfilter: conntrack: check netns when walking expect hash
Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
cb39ad8b8e
Коммит
03d7dc5cdf
|
@ -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
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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 @@ restart:
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче