From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Stefano Brivio <sbrivio@redhat.com>,
Pablo Neira Ayuso <pablo@netfilter.org>,
Sasha Levin <sashal@kernel.org>,
netfilter-devel@vger.kernel.org, coreteam@netfilter.org,
netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 5.5 29/35] netfilter: nft_set_rbtree: Detect partial overlaps on insertion
Date: Mon, 6 Apr 2020 20:00:51 -0400 [thread overview]
Message-ID: <20200407000058.16423-29-sashal@kernel.org> (raw)
In-Reply-To: <20200407000058.16423-1-sashal@kernel.org>
From: Stefano Brivio <sbrivio@redhat.com>
[ Upstream commit 7c84d41416d836ef7e533bd4d64ccbdf40c5ac70 ]
...and return -ENOTEMPTY to the front-end in this case, instead of
proceeding. Currently, nft takes care of checking for these cases
and not sending them to the kernel, but if we drop the set_overlap()
call in nft we can end up in situations like:
# nft add table t
# nft add set t s '{ type inet_service ; flags interval ; }'
# nft add element t s '{ 1 - 5 }'
# nft add element t s '{ 6 - 10 }'
# nft add element t s '{ 4 - 7 }'
# nft list set t s
table ip t {
set s {
type inet_service
flags interval
elements = { 1-3, 4-5, 6-7 }
}
}
This change has the primary purpose of making the behaviour
consistent with nft_set_pipapo, but is also functional to avoid
inconsistent behaviour if userspace sends overlapping elements for
any reason.
v2: When we meet the same key data in the tree, as start element while
inserting an end element, or as end element while inserting a start
element, actually check that the existing element is active, before
resetting the overlap flag (Pablo Neira Ayuso)
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_set_rbtree.c | 70 ++++++++++++++++++++++++++++++++--
1 file changed, 67 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 95fcba34bfd35..996fd9dc6160c 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -213,8 +213,43 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
u8 genmask = nft_genmask_next(net);
struct nft_rbtree_elem *rbe;
struct rb_node *parent, **p;
+ bool overlap = false;
int d;
+ /* Detect overlaps as we descend the tree. Set the flag in these cases:
+ *
+ * a1. |__ _ _? >|__ _ _ (insert start after existing start)
+ * a2. _ _ __>| ?_ _ __| (insert end before existing end)
+ * a3. _ _ ___| ?_ _ _>| (insert end after existing end)
+ * a4. >|__ _ _ _ _ __| (insert start before existing end)
+ *
+ * and clear it later on, as we eventually reach the points indicated by
+ * '?' above, in the cases described below. We'll always meet these
+ * later, locally, due to tree ordering, and overlaps for the intervals
+ * that are the closest together are always evaluated last.
+ *
+ * b1. |__ _ _! >|__ _ _ (insert start after existing end)
+ * b2. _ _ __>| !_ _ __| (insert end before existing start)
+ * b3. !_____>| (insert end after existing start)
+ *
+ * Case a4. resolves to b1.:
+ * - if the inserted start element is the leftmost, because the '0'
+ * element in the tree serves as end element
+ * - otherwise, if an existing end is found. Note that end elements are
+ * always inserted after corresponding start elements.
+ *
+ * For a new, rightmost pair of elements, we'll hit cases b1. and b3.,
+ * in that order.
+ *
+ * The flag is also cleared in two special cases:
+ *
+ * b4. |__ _ _!|<_ _ _ (insert start right before existing end)
+ * b5. |__ _ >|!__ _ _ (insert end right after existing start)
+ *
+ * which always happen as last step and imply that no further
+ * overlapping is possible.
+ */
+
parent = NULL;
p = &priv->root.rb_node;
while (*p != NULL) {
@@ -223,17 +258,42 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
d = memcmp(nft_set_ext_key(&rbe->ext),
nft_set_ext_key(&new->ext),
set->klen);
- if (d < 0)
+ if (d < 0) {
p = &parent->rb_left;
- else if (d > 0)
+
+ if (nft_rbtree_interval_start(new)) {
+ overlap = nft_rbtree_interval_start(rbe) &&
+ nft_set_elem_active(&rbe->ext,
+ genmask);
+ } else {
+ overlap = nft_rbtree_interval_end(rbe) &&
+ nft_set_elem_active(&rbe->ext,
+ genmask);
+ }
+ } else if (d > 0) {
p = &parent->rb_right;
- else {
+
+ if (nft_rbtree_interval_end(new)) {
+ overlap = nft_rbtree_interval_end(rbe) &&
+ nft_set_elem_active(&rbe->ext,
+ genmask);
+ } else if (nft_rbtree_interval_end(rbe) &&
+ nft_set_elem_active(&rbe->ext, genmask)) {
+ overlap = true;
+ }
+ } else {
if (nft_rbtree_interval_end(rbe) &&
nft_rbtree_interval_start(new)) {
p = &parent->rb_left;
+
+ if (nft_set_elem_active(&rbe->ext, genmask))
+ overlap = false;
} else if (nft_rbtree_interval_start(rbe) &&
nft_rbtree_interval_end(new)) {
p = &parent->rb_right;
+
+ if (nft_set_elem_active(&rbe->ext, genmask))
+ overlap = false;
} else if (nft_set_elem_active(&rbe->ext, genmask)) {
*ext = &rbe->ext;
return -EEXIST;
@@ -242,6 +302,10 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
}
}
}
+
+ if (overlap)
+ return -ENOTEMPTY;
+
rb_link_node_rcu(&new->node, parent, p);
rb_insert_color(&new->node, &priv->root);
return 0;
--
2.20.1
next prev parent reply other threads:[~2020-04-07 0:07 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-07 0:00 [PATCH AUTOSEL 5.5 01/35] ARM: dts: sun8i-a83t-tbs-a711: HM5065 doesn't like such a high voltage Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 02/35] bus: sunxi-rsb: Return correct data when mixing 16-bit and 8-bit reads Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 03/35] ARM: dts: Fix dm814x Ethernet by changing to use rgmii-id mode Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 04/35] bpf: Fix deadlock with rq_lock in bpf_send_signal() Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 05/35] net/mlx5e: kTLS, Fix wrong value in record tracker enum Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 06/35] iwlwifi: mvm: take the required lock when clearing time event data Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 07/35] iwlwifi: consider HE capability when setting LDPC Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 08/35] iwlwifi: yoyo: don't add TLV offset when reading FIFOs Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 09/35] iwlwifi: dbg: don't abort if sending DBGC_SUSPEND_RESUME fails Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 10/35] iwlwifi: mvm: Fix rate scale NSS configuration Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 11/35] Input: tm2-touchkey - add support for Coreriver TC360 variant Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 12/35] soc: fsl: dpio: register dpio irq handlers after dpio create Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 13/35] rxrpc: Abstract out the calculation of whether there's Tx space Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 14/35] rxrpc: Fix call interruptibility handling Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 15/35] rxrpc: Fix sendmsg(MSG_WAITALL) handling Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 16/35] net: stmmac: platform: Fix misleading interrupt error msg Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 17/35] net: vxge: fix wrong __VA_ARGS__ usage Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 18/35] ARM: dts: omap4-droid4: Fix lost touchscreen interrupts Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 19/35] riscv: uaccess should be used in nommu mode Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 20/35] hinic: fix a bug of waitting for IO stopped Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 21/35] hinic: fix the bug of clearing event queue Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 22/35] hinic: fix out-of-order excution in arm cpu Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 23/35] hinic: fix wrong para of wait_for_completion_timeout Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 24/35] hinic: fix wrong value of MIN_SKB_LEN Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 25/35] selftests/net: add definition for SOL_DCCP to fix compilation errors for old libc Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 26/35] IB/hfi1: Ensure pq is not left on waitlist Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 27/35] netfilter: nf_tables: Allow set back-ends to report partial overlaps on insertion Sasha Levin
2020-04-07 0:18 ` Stefano Brivio
2020-04-13 16:39 ` Sasha Levin
2020-04-13 20:38 ` Stefano Brivio
2020-04-14 15:08 ` Sasha Levin
2020-04-21 11:32 ` Pablo Neira Ayuso
2020-04-21 13:14 ` Greg KH
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 28/35] netfilter: nft_set_rbtree: Introduce and use nft_rbtree_interval_start() Sasha Levin
2020-04-07 0:00 ` Sasha Levin [this message]
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 30/35] cxgb4/ptp: pass the sign of offset delta in FW CMD Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 31/35] drm/scheduler: fix rare NULL ptr race Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 32/35] cfg80211: Do not warn on same channel at the end of CSA Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 33/35] qlcnic: Fix bad kzalloc null test Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 34/35] i2c: st: fix missing struct parameter description Sasha Levin
2020-04-07 0:00 ` Sasha Levin
2020-04-07 0:00 ` [PATCH AUTOSEL 5.5 35/35] i2c: pca-platform: Use platform_irq_get_optional Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200407000058.16423-29-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=coreteam@netfilter.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=sbrivio@redhat.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.