All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Mirian Shilakadze <mirian.shilakadze@virtuozzo.com>
To: khorenko@virtuozzo.com, ptikhomirov@virtuozzo.com
Cc: devel@openvz.org
Subject: [Devel] [PATCH vz10 v2 1/2] fs/kernfs, ve: hide entries from a VE without invalidating the dentry
Date: Wed, 26 Aug 2026 15:04:10 +0400	[thread overview]
Message-ID: <20260826110415.41119-2-mirian.shilakadze@virtuozzo.com> (raw)
In-Reply-To: <20260826110415.41119-1-mirian.shilakadze@virtuozzo.com>

kernfs_dop_revalidate() ends with a per VE visibility check and answers
it with the same "return 0" that the staleness checks above it use.
Those checks are properties of the kernfs node and hold for every
observer: the node was deactivated, moved, renamed, or retagged.
Visibility is a property of the calling task's VE, so one host dentry
answers "valid" to a ve0 task and "stale" to a task inside a Container.

The VFS reads 0 as a global fact and calls d_invalidate(), which walks
the subtree and hands every mountpoint it finds to __detach_mounts().
The mountpoint hash is not scoped to a mount namespace, and m_list holds
every mount attached at that dentry in any of them, so a Container's
lookup unmounts the host's mounts.

One lookup of /sys/fs/bpf from a task that only did setns() into a
Container's ve namespace, staying in the host mount namespace, both
hides the entry from the caller and destroys the host's bpffs.  A
Container start reaches the same path on its own: libvzctl stats every
mount point in the namespace to collect the mount flags of a bindmount
source, and does it after CLONE_NEWVE and before pivot_root, so the host
loses bpffs and tracefs on the way.  libvzctl needs bpffs for the cgroup
v2 device controller, so no Container on the node can be managed
afterwards, and the damage outlives the failed start.

Report the name as missing instead, except on a kernfs instance that
this VE created, where the dentry is dropped as before.  Everywhere else,
the host's sysfs above all, the caller that cannot see the entry is told
the name is missing, which is what the check is for, and the dentry stays
valid for everyone else.  No caller of ->d_revalidate() reaches
d_invalidate() with a negative return: lookup_dcache(), lookup_fast(),
__lookup_slow() and lookup_open() in fs/namei.c all gate it on exactly
0, ovl_revalidate_real() gates it the same way, and
ecryptfs_d_revalidate() hands the value back without invalidating
anything itself.  kernfs_iop_lookup() already answers this same
condition with a plain "not found".

Feature: kernfs: per-CT entries visibility and permissions configuration
https://virtuozzo.atlassian.net/browse/VSTOR-142552
Fixes: 3dd8c2499df6 ("ve/kernfs: hide forbidden entries in container")
Signed-off-by: Mirian Shilakadze <mirian.shilakadze@virtuozzo.com>
---
 fs/kernfs/dir.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index be680eb98ed4..4a5ee299a94e 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1199,8 +1199,21 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags)
 	    kernfs_info(dentry->d_sb)->ns != kn->ns)
 		goto out_bad;
 
-	if (!kernfs_d_visible(kn, kernfs_info(dentry->d_sb)))
-		goto out_bad;
+	if (!kernfs_d_visible(kn, kernfs_info(dentry->d_sb))) {
+		/*
+		 * On an instance this VE created, drop the dentry as before.
+		 * Anywhere else the node is fine and is only outside this
+		 * VE's view: returning 0 would tell the VFS that the dentry
+		 * is stale, and it answers that with d_invalidate(), which
+		 * detaches every mount on that dentry in every mount
+		 * namespace.  Report the name as missing to this caller
+		 * instead.
+		 */
+		if (kernfs_info(dentry->d_sb)->ve == get_exec_env())
+			goto out_bad;
+		up_read(&root->kernfs_rwsem);
+		return -ENOENT;
+	}
 
 	up_read(&root->kernfs_rwsem);
 	return 1;
-- 
2.43.0

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

  reply	other threads:[~2026-08-26 11:05 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 11:04 [Devel] [PATCH vz10 v2 0/2] fs/kernfs, ve: stop a container lookup unmounting host filesystems Mirian Shilakadze
2026-08-26 11:04 ` Mirian Shilakadze [this message]
2026-08-26 16:15   ` [Devel] [PATCH RHEL10 COMMIT] fs/kernfs, ve: hide entries from a VE without invalidating the dentry Konstantin Khorenko
2026-08-26 16:34   ` [Devel] [PATCH vz10 v2 1/2] " Konstantin Khorenko
2026-08-26 11:04 ` [Devel] [PATCH vz10 v2 2/2] selftests/ve: check that hiding an entry does not unmount it Mirian Shilakadze
2026-08-26 16:15   ` [Devel] [PATCH RHEL10 COMMIT] " Konstantin Khorenko
2026-08-26 11:12 ` [Devel] [PATCH vz10 v2 0/2] fs/kernfs, ve: stop a container lookup unmounting host filesystems Pavel Tikhomirov

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=20260826110415.41119-2-mirian.shilakadze@virtuozzo.com \
    --to=mirian.shilakadze@virtuozzo.com \
    --cc=devel@openvz.org \
    --cc=khorenko@virtuozzo.com \
    --cc=ptikhomirov@virtuozzo.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.