Message ID | 20221118114137.128088-1-arefev@swemel.ru |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp143745wrr; Fri, 18 Nov 2022 03:47:36 -0800 (PST) X-Google-Smtp-Source: AA0mqf5DiuUgPBNSG+DOTpkpf3eoZVeC+YrvSRB446W2KgiBuD642To6k9kysrSYJpiBwTI7OYCu X-Received: by 2002:a17:906:706:b0:7ac:2e16:eb05 with SMTP id y6-20020a170906070600b007ac2e16eb05mr5949481ejb.26.1668772055996; Fri, 18 Nov 2022 03:47:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668772055; cv=none; d=google.com; s=arc-20160816; b=cI1vLVs9m2RrfyuiFSMTIWgKp8Ml9hZ4WxfMr+vYnBbwegW1Bq4T961Iu8pIkxelqK StJxhxQFYzD8bz77BxiAtpVBIliQYy4RBgvgYwLBsrtaDlY4XGjLDEvT8X2E2pLeOnpi 31IJTxNSq49rhvvkxvZImTHAw6s0XETY+3vPqFloa0rml6TwFT/qquFoLr5lz6XonFMk vbU1PV5NEnLY74Fyyw4z+DefWCq09Gy3sYpuNLo2Jr1+iqW5I0NneEkkXFgUtkzO0tOG p7dDSpFl3lSDXEy4Q9UJTs7VwDQu3j8qS1P6uXy/mpkgjnIZnN8NNJYHpXFzzechoXx3 PxAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:dkim-signature:from; bh=SSD/8D3oxjxNO6XFSWDffwRmka85Uk/caIyP96y7PQk=; b=V8yLy3QI7+0KGYYeK4MPUp/c3zx5WiO52Xd+hzwtLOAvF3jp8BxKVzqGEGerV6zHFs 30nBiNOBteQH0/SGrLXgGH5h27sLhpkW4nYPpQB8JPBNRu8/Q8mxJdLCzFd7HIjb7gHc omEiHP57jJe8B08Cdkjvf8mrTg60eMekIwiQI7hfpcBZ7060PB78ZpFpqAeZrf1adMim 3PJObFaf7//Arv8MCVL8B7dFdtNv9XPsUDROimajNwpBST3szEZkO+z+/yWaMRrIx0xp 2BNdfilBLyzsqedzNdfcfad2CQeIqDA2nPjrBrvHu2MXr60XOwqP6uXNp1mmjNSjq5AD 90LA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@swemel.ru header.s=mail header.b="cl/J/kRe"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=swemel.ru Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z6-20020a056402274600b004488842d88esi3286395edd.13.2022.11.18.03.47.09; Fri, 18 Nov 2022 03:47:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@swemel.ru header.s=mail header.b="cl/J/kRe"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=swemel.ru Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241423AbiKRLll (ORCPT <rfc822;kkmonlee@gmail.com> + 99 others); Fri, 18 Nov 2022 06:41:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241100AbiKRLlk (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 18 Nov 2022 06:41:40 -0500 Received: from mx.swemel.ru (mx.swemel.ru [95.143.211.150]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA5E717430; Fri, 18 Nov 2022 03:41:39 -0800 (PST) From: Denis Arefev <arefev@swemel.ru> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=swemel.ru; s=mail; t=1668771697; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=SSD/8D3oxjxNO6XFSWDffwRmka85Uk/caIyP96y7PQk=; b=cl/J/kReOmnmtGqxIEY9x/uDHsYTje/wJhEd5YDc6K8CwBGEj6LD9pzQZbOjoQCGEsGRWi f7IiCj8XHMiEEILyZt+68o7mpukiEW3cdmLUUyrAGKQ+J0spkkstvwBxUXB1ayhgGbXcWd wJKEmJcdgQMEgL1iCzw6hT+PZh41Gd4= To: Alexander Viro <viro@zeniv.linux.org.uk> Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org, trufanov@swemel.ru, vfh@swemel.ru Subject: [PATCH v2] namespace: Added pointer check in copy_mnt_ns() Date: Fri, 18 Nov 2022 14:41:37 +0300 Message-Id: <20221118114137.128088-1-arefev@swemel.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749834327191504413?= X-GMAIL-MSGID: =?utf-8?q?1749834327191504413?= |
Series |
[v2] namespace: Added pointer check in copy_mnt_ns()
|
|
Commit Message
Denis Arefev
Nov. 18, 2022, 11:41 a.m. UTC
Return value of a function 'next_mnt' is dereferenced at
namespace.c:3377 without checking for null,
but it is usually checked for this function
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Denis Arefev <arefev@swemel.ru>
---
fs/namespace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Comments
On Fri, Nov 18, 2022 at 02:41:37PM +0300, Denis Arefev wrote: > Return value of a function 'next_mnt' is dereferenced at > namespace.c:3377 without checking for null, > but it is usually checked for this function > > Found by Linux Verification Center (linuxtesting.org) with SVACE. NAK. I see a bug in there, but it's not going to trigger a NULL pointer dereference and your patch doesn't fix it at all. That loop ought to be // skipped mntns binding? while (p->mnt.mnt_root != q->mnt.mnt_root) p = next_mnt(skip_mnt_tree(p), old); and I suspect that it'll confuse your tool even worse. What happens here is that new tree is congruent to the old one, with some subtrees skipped. Each node N in the new tree is a clone of some node (Origin(N)) in the old one. Copying preserves node order. We want to have p == Origin(q) on each iteration. What we really have (due to the real bug) is p is no later than Origin(q) in node ordering Initially it's trivially true (p points to root of the old tree, and the only way it would *not* be copied would be to somehow get mntns binding as root; in that case copy_tree() would've failed and we wouldn't get to that loop at all). Suppose it is true on some iteration. What happens on the next one? q hadn't been the last node in the new tree, or we would've found next_mnt(q, new) to be NULL and exited the loop. But that means that p "<=" Origin(q) "<" Origin(next_mnt(q, new)) ("<" and "<=" in the node ordering, that is). So p couldn't have been the last node in the old tree and next_mnt(p, old) "<=" Origin(next_mnt(q, new)) After the p = next_mnt(p, old); q = next_mnt(q, new); if (!q) break; we have p != NULL && p "<=" Origin(q) Cloning preserves ->mnt_root, so the subsequent loop while (p->mnt.mnt_root != q->mnt.mnt_root) p = next_mnt(p, old); could be rewritten as while (p->mnt.mnt_root != Origin(q)->mnt.mnt_root) p = next_mnt(p, old); and in that form it's really obvious that p will not advance past Origin(q), nevermind running out of nodes. So on the next iteration the property still holds. There's no way for your added checks to trigger. There *IS* a bug in that logics, though - mntns binding can have a file bound on top of it. In such case it is possible to have p behind the Origin(q) for a (short) while. It's not going to cause serious problems, but that's certainly a non-obvious behaviour and a comment needed to explain why it's not problem is certainly longer than the one-liner change eliminating the oddity. Note that running into mnt_root mismatch means that p is currently pointing to mntns binding we'd skipped when copying. So let's skip the subtree in the same way copy_tree() did... The bottom line: * your NULL pointer checks could never trigger; if you *do* have a reproducer, please post it. * there's a (pretty harmless) bug in that code, but it is not fixed by your patch. * see if your tool is any happier with the patch below; I would be rather surprised if it did, but... diff --git a/fs/namespace.c b/fs/namespace.c index df137ba19d37..c80f422084eb 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3515,8 +3515,9 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, q = next_mnt(q, new); if (!q) break; + // an mntns binding we'd skipped? while (p->mnt.mnt_root != q->mnt.mnt_root) - p = next_mnt(p, old); + p = next_mnt(skip_mnt_tree(p), old); } namespace_unlock();
diff --git a/fs/namespace.c b/fs/namespace.c index cebaa3e81794..06472a110257 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3348,9 +3348,9 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, } p = next_mnt(p, old); q = next_mnt(q, new); - if (!q) + if (!q || !p) break; - while (p->mnt.mnt_root != q->mnt.mnt_root) + while (p && (p->mnt.mnt_root != q->mnt.mnt_root)) p = next_mnt(p, old); } namespace_unlock();