aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-10-01 07:27:32 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2018-10-11 05:29:14 -0400
commit3b18d5eba491b2328b31efa4235724a2354af010 (patch)
tree566212c7112cb126d124e57634e3b88386d71b93
parent9a4890bd6d6325a1c88564a20ab310b2d56f6094 (diff)
netfilter: nft_set_rbtree: allow loose matching of closing element in interval
Allow to find closest matching for the right side of an interval (end flag set on) so we allow lookups in inner ranges, eg. 10-20 in 5-25. Fixes: ba0e4d9917b4 ("netfilter: nf_tables: get set elements via netlink") Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nft_set_rbtree.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 0e5ec126f6ad..fa61208371f8 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -135,9 +135,12 @@ static bool __nft_rbtree_get(const struct net *net, const struct nft_set *set,
135 d = memcmp(this, key, set->klen); 135 d = memcmp(this, key, set->klen);
136 if (d < 0) { 136 if (d < 0) {
137 parent = rcu_dereference_raw(parent->rb_left); 137 parent = rcu_dereference_raw(parent->rb_left);
138 interval = rbe; 138 if (!(flags & NFT_SET_ELEM_INTERVAL_END))
139 interval = rbe;
139 } else if (d > 0) { 140 } else if (d > 0) {
140 parent = rcu_dereference_raw(parent->rb_right); 141 parent = rcu_dereference_raw(parent->rb_right);
142 if (flags & NFT_SET_ELEM_INTERVAL_END)
143 interval = rbe;
141 } else { 144 } else {
142 if (!nft_set_elem_active(&rbe->ext, genmask)) 145 if (!nft_set_elem_active(&rbe->ext, genmask))
143 parent = rcu_dereference_raw(parent->rb_left); 146 parent = rcu_dereference_raw(parent->rb_left);
@@ -154,7 +157,10 @@ static bool __nft_rbtree_get(const struct net *net, const struct nft_set *set,
154 157
155 if (set->flags & NFT_SET_INTERVAL && interval != NULL && 158 if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
156 nft_set_elem_active(&interval->ext, genmask) && 159 nft_set_elem_active(&interval->ext, genmask) &&
157 !nft_rbtree_interval_end(interval)) { 160 ((!nft_rbtree_interval_end(interval) &&
161 !(flags & NFT_SET_ELEM_INTERVAL_END)) ||
162 (nft_rbtree_interval_end(interval) &&
163 (flags & NFT_SET_ELEM_INTERVAL_END)))) {
158 *elem = interval; 164 *elem = interval;
159 return true; 165 return true;
160 } 166 }