From patchwork Sat Sep 16 00:48:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1835321 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RnXbY09HTz1yhP for ; Sat, 16 Sep 2023 10:52:57 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qhJYE-0000gy-Q4; Sat, 16 Sep 2023 00:52:46 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qhJW4-0007Db-0O for kernel-team@lists.ubuntu.com; Sat, 16 Sep 2023 00:50:32 +0000 Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id C8EA73F627 for ; Sat, 16 Sep 2023 00:50:30 +0000 (UTC) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-1c0cfc2b995so24221235ad.2 for ; Fri, 15 Sep 2023 17:50:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694825429; x=1695430229; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nHPZTmQDl2xaC82VCIsUQRlcb7s5+AUsfzQY3A4N4Lc=; b=uJGJguVo0q8KAxqUTFAY5gCSFYIJjtlNCbBJYvRL60Mbq+ET8Sm/ednk67HL/QGmrA WGI33GcpYd8+AiAWVAlVhARIStg9WcFgedGHmvxRsDO9fY4oDPfgSf0USoQWaFZXZ6HY dlhVcIVzCrulCWmaRquw5DNuRT9A+/wMXxLzNpD5xMr3/5xWsK4W0mOTJbbBdNSTR/5t tmYVbBamRHQTr1iqANvBzZPpU9njNp4RryuVtDIaMuCK5LJ+9mfHGEIhChfOBWVVxWaR i193g5M/VOold4DBcf5tKaFkYiLQXukpDaiVVXkxt4oDo9r/7SzgeBhK3py6ddNc8dMu mFKw== X-Gm-Message-State: AOJu0YwYsDdwma/OHlvMNaQKtzBBA1yyRqAmmwLvrmZdM3AhsKFZX6bB ga4wl9AZZezNkJ8cx/cH6jxTQSv+dLBjMH3vD+I8xLJPTOCtSYsG2+OeQEr9rFLBel8hcJGcMCF urYF+E74FI9SeNt0tQ2Koe+L/Mmdv2pibPvdlud6VUjHYnH3I0fpD X-Received: by 2002:a17:903:610:b0:1bd:a22a:d409 with SMTP id kg16-20020a170903061000b001bda22ad409mr2851556plb.40.1694825429095; Fri, 15 Sep 2023 17:50:29 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHq6hEPcQK+zwpBZPp4Dp9Km+G3r+MPUL+1J+piHRcsLtJbVxJv/4oxvTPNv7dsuiySy/k/fA== X-Received: by 2002:a17:903:610:b0:1bd:a22a:d409 with SMTP id kg16-20020a170903061000b001bda22ad409mr2851550plb.40.1694825428756; Fri, 15 Sep 2023 17:50:28 -0700 (PDT) Received: from localhost (uk.sesame.canonical.com. [185.125.190.60]) by smtp.gmail.com with ESMTPSA id m7-20020a170902db0700b001b8a7e1b116sm4046162plx.191.2023.09.15.17.50.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 17:50:28 -0700 (PDT) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU OEM-6.0] netfilter: nft_set_rbtree: fix null deref on element insertion Date: Sat, 16 Sep 2023 03:48:25 +0300 Message-Id: <20230916004839.706452-16-cengiz.can@canonical.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230916004839.706452-1-cengiz.can@canonical.com> References: <20230916004839.706452-1-cengiz.can@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Florian Westphal 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 (cherry picked from commit 61ae320a29b0540c16931816299eb86bf2b66c08) CVE-2023-4244 [cengizcan: prerequisite commit] Signed-off-by: Cengiz Can --- 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 c9a6961fdb6e..a695bfed566a 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -221,7 +221,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); @@ -229,17 +229,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); @@ -268,7 +272,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; @@ -307,7 +311,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))