Commit b429df81 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by Dong Chenchen
Browse files

netfilter: nft_set_rbtree: skip end interval element from gc

stable inclusion
from stable-v5.10.209
commit 4cee42fcf54fec46b344681e7cc4f234bb22f85a
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I92HII
CVE: CVE-2024-26581

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4cee42fcf54fec46b344681e7cc4f234bb22f85a



--------------------------------

commit 60c0c230c6f046da536d3df8b39a20b9a9fd6af0 upstream.

rbtree lazy gc on insert might collect an end interval element that has
been just added in this transactions, skip end interval elements that
are not yet active.

Fixes: f718863a ("netfilter: nft_set_rbtree: fix overlap expiration walk")
Cc: stable@vger.kernel.org
Reported-by: default avatarlonial con <kongln9170@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarDong Chenchen <dongchenchen2@huawei.com>
parent e0a00cd6
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -216,8 +216,7 @@ static void *nft_rbtree_get(const struct net *net, const struct nft_set *set,

static int nft_rbtree_gc_elem(const struct nft_set *__set,
			      struct nft_rbtree *priv,
			      struct nft_rbtree_elem *rbe,
			      u8 genmask)
			      struct nft_rbtree_elem *rbe)
{
	struct nft_set *set = (struct nft_set *)__set;
	struct rb_node *prev = rb_prev(&rbe->node);
@@ -235,7 +234,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
	while (prev) {
		rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
		if (nft_rbtree_interval_end(rbe_prev) &&
		    nft_set_elem_active(&rbe_prev->ext, genmask))
		    nft_set_elem_active(&rbe_prev->ext, NFT_GENMASK_ANY))
			break;

		prev = rb_prev(prev);
@@ -328,7 +327,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,

		/* perform garbage collection to avoid bogus overlap reports. */
		if (nft_set_elem_expired(&rbe->ext)) {
			err = nft_rbtree_gc_elem(set, priv, rbe, genmask);
			err = nft_rbtree_gc_elem(set, priv, rbe);
			if (err < 0)
				return err;