From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794061445; b=VlE194/GaKHSGFVUS/OEXmeFZDeJmcPdYR5dFFvG1EmJtfzthmbsEUStLqJuo8/sXkkU VXqu2wH7CG07O4JP0xOYxWPMd4q3OW7FBiFv9lQTOgPhhoWIo3D2ql0eB4oHIbPSXwDZV tLM7DMqo+I5OJ6nxLLOtwxXd3dxXyZIvfMPji41T7Uf5QCw1XT6sx0ygLQS+8HNwSp961 mZWWBkQxTxr4PVVoxHsW5/Mcl1q2Wfhio9X6xW/PsphkxGtTSnRp4sihmqB7B7vDTQi38 bHfH7JNccpc9WcZ9obIeXHoallCeIXthATomISJKH/Iqw8JPUEl0z6NZIbrlHosvLnw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794061445; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=H/uo7u7m45L+4CesUHY5hGIPREpelUcfL0Bh9eu3rIU=; b=xFexIsNIPUp91gg8Yao+ObAe8ytmQbxSw6Aa2fEiQGbeAS7jcCp7fRoZQUP9FNVl5CLf pzRmVvJtMQHfLMSpWrs3uaLof08BdoOtC/9FKsn4serlrItNg2MDAwi8DTfdFAfYHhSke NrwdNItaX7GU86EDCWZGMxsn41J5ApOFRu7OJCBv+ZI7NgrPOz194cBqaCPF+pYaYRqQL m9HJgHVtjrHTsFgQUZtEDs5SD4IMFYdoXsvJNdq063+DLordtLJUAWghZ+FzMQUJpkxFq nVn+BBg5kZTvGynxDS0rQZEyO+WNqjiLq9jcwZdTaFwCOqGpiQGRIZsUgenEfNha3kw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Fp+f3Mgk; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C276606A326; Sat, 7 Nov 2026 14:24:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=Fp+f3Mgk Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC2AF1F0089F; Sat, 7 Nov 2026 14:24:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794061445; bh=H/uo7u7m45L+4CesUHY5hGIPREpelUcfL0Bh9eu3rIU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Fp+f3MgkH6sbHY/J+ID5TligBN4bdFA8tHWhZwh7d0QdD8/m2mpdCKMM3FHF122wz h9zYVk6EOc9MCIRzWUQy4K1osWcsPLSeF6xsnb9eJYgNW7nKYC6ULhgVtEJRA0EYPs AACXUTTc+4u9BZGZt8EsZ72gqCp+bfyKLNIOAPdA= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, "Christian Brauner (Amutable)" , Sasha Levin Subject: [PATCH 6.12 0552/1536] namespace: never expire a locked mount Date: Sat, 7 Nov 2026 08:42:48 -0500 Message-ID: <20261107135013.104756359@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134957.653319350@linuxfoundation.org> References: <20261107134957.653319350@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Christian Brauner [ Upstream commit f78ddcc872248c7aa1d7e904928441a0be4c6d5d ] Locked mounts are special. They protect the underlying files and directories from being revealed. do_umount() refuses to unmount locked mounts but shrink_submounts() doesn't. A shrinkable mount can become locked once the owner of a user namespace puts it beneath a locked mount with MOVE_MOUNT_BENEATH. The locked property now moves to the mount at the bottom making it possible to unmount the top mount. So umount() of an unlocked ancestor now expires the bottom mount first and the covered directory is revealed: move_mount(c -> x/hidden, MOVE_MOUNT_BENEATH) = 0 the cover after the lock moved: umount2(x/hidden) = 0 the holder of the lock: umount2(x/hidden) = EINVAL the root of the copy, busy: umount2(x) = EBUSY reads x/hidden/secret: "covered-by-root" So leave a locked mount alone as it dies together with its parent. A plain umount() of an unlocked mount with a locked one below it is EBUSY from now on. It's the same for any other locked child. A lazy umount still takes the whole tree. mark_mounts_for_expiry() never sees a locked mount. lock_mnt_tree() leaves a mount on an expiry list alone and nothing else puts a locked one on such a list. Add an assert for this. Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users") Fixes: c62a4766937e ("move_mount: transfer MNT_LOCKED") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-8-dd44b89d44ce@kernel.org Signed-off-by: Christian Brauner (Amutable) [ sashal: Dropped the missing is_mounted() context lines and replaced VFS_WARN_ON_ONCE() with WARN_ON_ONCE(), since the former macro doesn't exist here. ] Signed-off-by: Sasha Levin --- fs/namespace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index ebdc223c142e0..d02a4bbb75d37 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3710,6 +3710,8 @@ void mark_mounts_for_expiry(struct list_head *mounts) * cleared by mntput()) */ list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { + /* lock_mnt_tree() leaves expirable mounts alone */ + WARN_ON_ONCE(IS_MNT_LOCKED(mnt)); if (!xchg(&mnt->mnt_expiry_mark, 1) || propagate_mount_busy(mnt, 1)) continue; @@ -3738,7 +3740,8 @@ EXPORT_SYMBOL_GPL(mark_mounts_for_expiry); */ static bool shrink_submount(struct mount *mnt) { - if (propagate_mount_busy(mnt, 1)) + /* not the kernel's to remove either */ + if (IS_MNT_LOCKED(mnt) || propagate_mount_busy(mnt, 1)) return false; touch_mnt_namespace(mnt->mnt_ns); umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC); -- 2.53.0