From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: gregkh@linuxfoundation.org, sashal@kernel.org, stable@vger.kernel.org
Subject: [PATCH -stable,4.19.x 07/40] netfilter: nft_set_rbtree: fix null deref on element insertion
Date: Thu, 13 Jun 2024 03:01:36 +0200 [thread overview]
Message-ID: <20240613010209.104423-8-pablo@netfilter.org> (raw)
In-Reply-To: <20240613010209.104423-1-pablo@netfilter.org>
commit 61ae320a29b0540c16931816299eb86bf2b66c08 upstream.
There is no guarantee that rb_prev() will not return NULL in nft_rbtree_gc_elem():
general protection fault, probably for non-canonical address 0xdffffc0000000003: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
nft_add_set_elem+0x14b0/0x2990
nf_tables_newsetelem+0x528/0xb30
Furthermore, there is a possible use-after-free while iterating,
'node' can be free'd so we need to cache the next value to use.
Fixes: c9e6978e2725 ("netfilter: nft_set_rbtree: Switch to node list walk for overlap detection")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_set_rbtree.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index f8d98547df7a..188cb227f31a 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -223,7 +223,7 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
{
struct nft_set *set = (struct nft_set *)__set;
struct rb_node *prev = rb_prev(&rbe->node);
- struct nft_rbtree_elem *rbe_prev;
+ struct nft_rbtree_elem *rbe_prev = NULL;
struct nft_set_gc_batch *gcb;
gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC);
@@ -231,17 +231,21 @@ static int nft_rbtree_gc_elem(const struct nft_set *__set,
return -ENOMEM;
/* search for expired end interval coming before this element. */
- do {
+ while (prev) {
rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node);
if (nft_rbtree_interval_end(rbe_prev))
break;
prev = rb_prev(prev);
- } while (prev != NULL);
+ }
+
+ if (rbe_prev) {
+ rb_erase(&rbe_prev->node, &priv->root);
+ atomic_dec(&set->nelems);
+ }
- rb_erase(&rbe_prev->node, &priv->root);
rb_erase(&rbe->node, &priv->root);
- atomic_sub(2, &set->nelems);
+ atomic_dec(&set->nelems);
nft_set_gc_batch_add(gcb, rbe);
nft_set_gc_batch_complete(gcb);
@@ -270,7 +274,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
struct nft_set_ext **ext)
{
struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL;
- struct rb_node *node, *parent, **p, *first = NULL;
+ struct rb_node *node, *next, *parent, **p, *first = NULL;
struct nft_rbtree *priv = nft_set_priv(set);
u8 genmask = nft_genmask_next(net);
int d, err;
@@ -309,7 +313,9 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
* Values stored in the tree are in reversed order, starting from
* highest to lowest value.
*/
- for (node = first; node != NULL; node = rb_next(node)) {
+ for (node = first; node != NULL; node = next) {
+ next = rb_next(node);
+
rbe = rb_entry(node, struct nft_rbtree_elem, node);
if (!nft_set_elem_active(&rbe->ext, genmask))
--
2.30.2
next prev parent reply other threads:[~2024-06-13 1:02 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-13 1:01 [PATCH -stable,4.19.x 00/40] Netfilter fixes for -stable Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 01/40] netfilter: nf_tables: pass context to nft_set_destroy() Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 02/40] netfilter: nftables: rename set element data activation/deactivation functions Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 03/40] netfilter: nf_tables: drop map element references from preparation phase Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 04/40] netfilter: nft_set_rbtree: allow loose matching of closing element in interval Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 05/40] netfilter: nft_set_rbtree: Add missing expired checks Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 06/40] netfilter: nft_set_rbtree: Switch to node list walk for overlap detection Pablo Neira Ayuso
2024-06-13 1:01 ` Pablo Neira Ayuso [this message]
2024-06-13 1:01 ` [PATCH -stable,4.19.x 08/40] netfilter: nft_set_rbtree: fix overlap expiration walk Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 09/40] netfilter: nf_tables: don't skip expired elements during walk Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 10/40] netfilter: nf_tables: GC transaction API to avoid race with control plane Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 11/40] netfilter: nf_tables: adapt set backend to use GC transaction API Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 12/40] netfilter: nf_tables: remove busy mark and gc batch API Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 13/40] netfilter: nf_tables: fix GC transaction races with netns and netlink event exit path Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 14/40] netfilter: nf_tables: GC transaction race with netns dismantle Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 15/40] netfilter: nf_tables: GC transaction race with abort path Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 16/40] netfilter: nf_tables: defer gc run if previous batch is still pending Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 17/40] netfilter: nft_set_rbtree: skip sync GC for new elements in this transaction Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 18/40] netfilter: nft_set_rbtree: use read spinlock to avoid datapath contention Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 19/40] netfilter: nft_set_hash: try later when GC hits EAGAIN on iteration Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 20/40] netfilter: nf_tables: fix memleak when more than 255 elements expired Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 21/40] netfilter: nf_tables: unregister flowtable hooks on netns exit Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 22/40] netfilter: nf_tables: double hook unregistration in netns path Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 23/40] netfilter: nftables: update table flags from the commit phase Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 24/40] netfilter: nf_tables: fix table flag updates Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 25/40] netfilter: nf_tables: disable toggling dormant table state more than once Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 26/40] netfilter: nf_tables: bogus EBUSY when deleting flowtable after flush (for 4.19) Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 27/40] netfilter: nft_dynset: fix timeouts later than 23 days Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 28/40] netfilter: nftables: exthdr: fix 4-byte stack OOB write Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 29/40] netfilter: nft_dynset: report EOPNOTSUPP on missing set feature Pablo Neira Ayuso
2024-06-13 1:01 ` [PATCH -stable,4.19.x 30/40] netfilter: nft_dynset: relax superfluous check on set updates Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 31/40] netfilter: nf_tables: mark newset as dead on transaction abort Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 32/40] netfilter: nf_tables: skip dead set elements in netlink dump Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 33/40] netfilter: nf_tables: validate NFPROTO_* family Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 34/40] netfilter: nft_set_rbtree: skip end interval element from gc Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 35/40] netfilter: nf_tables: set dormant flag on hook register failure Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 36/40] netfilter: nf_tables: allow NFPROTO_INET in nft_(match/target)_validate() Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 37/40] netfilter: nf_tables: do not compare internal table flags on updates Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 38/40] netfilter: nf_tables: mark set as dead when unbinding anonymous set with timeout Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 39/40] netfilter: nf_tables: reject new basechain after table flag update Pablo Neira Ayuso
2024-06-13 1:02 ` [PATCH -stable,4.19.x 40/40] netfilter: nf_tables: discard table flag update with pending basechain deletion Pablo Neira Ayuso
2024-06-13 6:43 ` [PATCH -stable,4.19.x 00/40] Netfilter fixes for -stable Greg KH
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=20240613010209.104423-8-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=gregkh@linuxfoundation.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=sashal@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).