From patchwork Sat Sep 16 00:48:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cengiz Can X-Patchwork-Id: 1835322 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 4RnXbl3rkKz1yhP for ; Sat, 16 Sep 2023 10:53:07 +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 1qhJYJ-0000p0-OV; Sat, 16 Sep 2023 00:52:54 +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 1qhJWA-0007Mq-CW for kernel-team@lists.ubuntu.com; Sat, 16 Sep 2023 00:50:44 +0000 Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) (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 C250D3F627 for ; Sat, 16 Sep 2023 00:50:37 +0000 (UTC) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-274a28033b2so868154a91.2 for ; Fri, 15 Sep 2023 17:50:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694825436; x=1695430236; 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=XE8BXPpnaWgKv5eEgTfq78vYYdL8wVkV26YlbJxuQSw=; b=DEJaPh7ZKUvHDNZTULf2T6cyCvtMHpXqK4C6ptnBqDSWVYLk1yeN4trOaDQfvJF3kx fx2evptIw5xcby+hfs3NSO/SnhccGWSHHQyRqB3PJGn8gT91sV9mrBdg+3nWsTKP9rBE KgqTAbBaelmhSTvCDSSFPbrd2f7VlP7HaHFxMrw/7nuZjc7A8e5i7cBJZEfGM8spZyBp qI6uU8Uw88QUkqwB7AS39/wcbvMYtfq4YjslYn4lXjh8aSlMICzNzTT/kU1fLA4kEnAa iS9uEv/sVmUUtAraqd96eQcoLGdLk5SvfKgM8c1JNk6Pp76rNZ/krh5ktZDcO1ZDWUUC 18LA== X-Gm-Message-State: AOJu0YwSl7dDaG5VjoD8hq1oqhvpwXmLMRhxb5uivp0Lr+UJKeq00rzX TSRkYqM/jGKnRa+GOMhGsym28Vfdhg+AOgVC/jmDDodyXfH9G49o4QsZlDr4zyHdBrNw8qS/5O2 XHAe8y9Cl3ZiomOfaKkqLDFkAH7vymqEkRmJ8GvgBq2qfwrvbVRaJ X-Received: by 2002:a17:90a:e285:b0:268:7ec:51ae with SMTP id d5-20020a17090ae28500b0026807ec51aemr2958745pjz.41.1694825436085; Fri, 15 Sep 2023 17:50:36 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHqfBnoJF+nt2y0T3K37GiQG8FAlSZHSQIM5c4WiaCCFE4k8rut7t2Owk4TxinV8E9seBfHSw== X-Received: by 2002:a17:90a:e285:b0:268:7ec:51ae with SMTP id d5-20020a17090ae28500b0026807ec51aemr2958737pjz.41.1694825435736; Fri, 15 Sep 2023 17:50:35 -0700 (PDT) Received: from localhost (uk.sesame.canonical.com. [185.125.190.60]) by smtp.gmail.com with ESMTPSA id x34-20020a17090a6c2500b002684b837d88sm3892720pjj.14.2023.09.15.17.50.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 17:50:35 -0700 (PDT) From: Cengiz Can To: kernel-team@lists.ubuntu.com Subject: [SRU OEM-6.0, Lunar] netfilter: nft_set_rbtree: fix overlap expiration walk Date: Sat, 16 Sep 2023 03:48:26 +0300 Message-Id: <20230916004839.706452-17-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 The lazy gc on insert that should remove timed-out entries fails to release the other half of the interval, if any. Can be reproduced with tests/shell/testcases/sets/0044interval_overlap_0 in nftables.git and kmemleak enabled kernel. Second bug is the use of rbe_prev vs. prev pointer. If rbe_prev() returns NULL after at least one iteration, rbe_prev points to element that is not an end interval, hence it should not be removed. Lastly, check the genmask of the end interval if this is active in the current generation. Fixes: c9e6978e2725 ("netfilter: nft_set_rbtree: Switch to node list walk for overlap detection") Signed-off-by: Florian Westphal (cherry picked from commit f718863aca469a109895cb855e6b81fff4827d71) CVE-2023-4244 [cengizcan: prerequisite commit] Signed-off-by: Cengiz Can --- net/netfilter/nft_set_rbtree.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index a695bfed566a..a8379fe42d27 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -217,29 +217,37 @@ 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) + struct nft_rbtree_elem *rbe, + u8 genmask) { struct nft_set *set = (struct nft_set *)__set; struct rb_node *prev = rb_prev(&rbe->node); - struct nft_rbtree_elem *rbe_prev = NULL; + struct nft_rbtree_elem *rbe_prev; struct nft_set_gc_batch *gcb; gcb = nft_set_gc_batch_check(set, NULL, GFP_ATOMIC); if (!gcb) return -ENOMEM; - /* search for expired end interval coming before this element. */ + /* search for end interval coming before this element. + * end intervals don't carry a timeout extension, they + * are coupled with the interval start element. + */ while (prev) { rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); - if (nft_rbtree_interval_end(rbe_prev)) + if (nft_rbtree_interval_end(rbe_prev) && + nft_set_elem_active(&rbe_prev->ext, genmask)) break; prev = rb_prev(prev); } - if (rbe_prev) { + if (prev) { + rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); + rb_erase(&rbe_prev->node, &priv->root); atomic_dec(&set->nelems); + nft_set_gc_batch_add(gcb, rbe_prev); } rb_erase(&rbe->node, &priv->root); @@ -321,7 +329,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); + err = nft_rbtree_gc_elem(set, priv, rbe, genmask); if (err < 0) return err;