aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2016-05-05 18:51:47 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2016-05-06 05:50:01 -0400
commit03d7dc5cdfe6fd4e5bd04cfc2be7ae259f956428 (patch)
tree154c3f3f33680d9294dd10c50eb5217f2ace6887
parentcb39ad8b8ef224c544074962780bf763077d6141 (diff)
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>
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c3
-rw-r--r--net/netfilter/nf_conntrack_expect.c19
-rw-r--r--net/netfilter/nf_conntrack_netlink.c12
3 files changed, 30 insertions, 4 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index f8fc7ab201c9..2b4c729fcf8d 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -301,6 +301,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
301 301
302 exp = hlist_entry(n, struct nf_conntrack_expect, hnode); 302 exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
303 303
304 if (!net_eq(nf_ct_net(exp->master), seq_file_net(s)))
305 return 0;
306
304 if (exp->tuple.src.l3num != AF_INET) 307 if (exp->tuple.src.l3num != AF_INET)
305 return 0; 308 return 0;
306 309
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index c2f7c4f475b1..da95d740e60b 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -86,6 +86,17 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
86 return reciprocal_scale(hash, nf_ct_expect_hsize); 86 return reciprocal_scale(hash, nf_ct_expect_hsize);
87} 87}
88 88
89static bool
90nf_ct_exp_equal(const struct nf_conntrack_tuple *tuple,
91 const struct nf_conntrack_expect *i,
92 const struct nf_conntrack_zone *zone,
93 const struct net *net)
94{
95 return nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) &&
96 net_eq(net, nf_ct_net(i->master)) &&
97 nf_ct_zone_equal_any(i->master, zone);
98}
99
89struct nf_conntrack_expect * 100struct nf_conntrack_expect *
90__nf_ct_expect_find(struct net *net, 101__nf_ct_expect_find(struct net *net,
91 const struct nf_conntrack_zone *zone, 102 const struct nf_conntrack_zone *zone,
@@ -99,8 +110,7 @@ __nf_ct_expect_find(struct net *net,
99 110
100 h = nf_ct_expect_dst_hash(tuple); 111 h = nf_ct_expect_dst_hash(tuple);
101 hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) { 112 hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) {
102 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) && 113 if (nf_ct_exp_equal(tuple, i, zone, net))
103 nf_ct_zone_equal_any(i->master, zone))
104 return i; 114 return i;
105 } 115 }
106 return NULL; 116 return NULL;
@@ -141,8 +151,7 @@ nf_ct_find_expectation(struct net *net,
141 h = nf_ct_expect_dst_hash(tuple); 151 h = nf_ct_expect_dst_hash(tuple);
142 hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) { 152 hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) {
143 if (!(i->flags & NF_CT_EXPECT_INACTIVE) && 153 if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
144 nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) && 154 nf_ct_exp_equal(tuple, i, zone, net)) {
145 nf_ct_zone_equal_any(i->master, zone)) {
146 exp = i; 155 exp = i;
147 break; 156 break;
148 } 157 }
@@ -222,6 +231,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
222 } 231 }
223 232
224 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) && 233 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask) &&
234 net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
225 nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); 235 nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
226} 236}
227 237
@@ -231,6 +241,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
231 return a->master == b->master && a->class == b->class && 241 return a->master == b->master && a->class == b->class &&
232 nf_ct_tuple_equal(&a->tuple, &b->tuple) && 242 nf_ct_tuple_equal(&a->tuple, &b->tuple) &&
233 nf_ct_tuple_mask_equal(&a->mask, &b->mask) && 243 nf_ct_tuple_mask_equal(&a->mask, &b->mask) &&
244 net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
234 nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); 245 nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master));
235} 246}
236 247
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index e00f178c48b0..5dfb84d86143 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2636,6 +2636,10 @@ restart:
2636 hnode) { 2636 hnode) {
2637 if (l3proto && exp->tuple.src.l3num != l3proto) 2637 if (l3proto && exp->tuple.src.l3num != l3proto)
2638 continue; 2638 continue;
2639
2640 if (!net_eq(nf_ct_net(exp->master), net))
2641 continue;
2642
2639 if (cb->args[1]) { 2643 if (cb->args[1]) {
2640 if (exp != last) 2644 if (exp != last)
2641 continue; 2645 continue;
@@ -2888,6 +2892,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
2888 hlist_for_each_entry_safe(exp, next, 2892 hlist_for_each_entry_safe(exp, next,
2889 &net->ct.expect_hash[i], 2893 &net->ct.expect_hash[i],
2890 hnode) { 2894 hnode) {
2895
2896 if (!net_eq(nf_ct_exp_net(exp), net))
2897 continue;
2898
2891 m_help = nfct_help(exp->master); 2899 m_help = nfct_help(exp->master);
2892 if (!strcmp(m_help->helper->name, name) && 2900 if (!strcmp(m_help->helper->name, name) &&
2893 del_timer(&exp->timeout)) { 2901 del_timer(&exp->timeout)) {
@@ -2906,6 +2914,10 @@ static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
2906 hlist_for_each_entry_safe(exp, next, 2914 hlist_for_each_entry_safe(exp, next,
2907 &net->ct.expect_hash[i], 2915 &net->ct.expect_hash[i],
2908 hnode) { 2916 hnode) {
2917
2918 if (!net_eq(nf_ct_exp_net(exp), net))
2919 continue;
2920
2909 if (del_timer(&exp->timeout)) { 2921 if (del_timer(&exp->timeout)) {
2910 nf_ct_unlink_expect_report(exp, 2922 nf_ct_unlink_expect_report(exp,
2911 NETLINK_CB(skb).portid, 2923 NETLINK_CB(skb).portid,