From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Mirian Shilakadze <mirian.shilakadze@virtuozzo.com>
Cc: devel@openvz.org
Subject: [Devel] [PATCH vz10] fs/kernfs, ve: pin the VE that mounted a kernfs instance
Date: Mon, 28 Sep 2026 18:41:25 +0200 [thread overview]
Message-ID: <20260928-prep-kh-vstor-142552-kernfs-pin-ve-v1-1-7297e159e813@virtuozzo.com> (raw)
kernfs_get_tree() stores a bare get_exec_env() pointer in
kernfs_super_info, and since commit 8d1abf587552 ("fs/kernfs, ve:
hide entries from a VE without invalidating the dentry")
kernfs_dop_revalidate() compares it against the caller's VE to decide
between dropping the dentry and answering -ENOENT. Nothing backs that
pointer with a reference: if the mount is pinned from outside - the
host bind-mounted a Container's sysfs, or holds an fd inside it - the
superblock outlives the Container, info->ve dangles, and a later
Container whose ve_struct is allocated at the same address is mistaken
for the creator of the instance. Its lookups then take the
d_invalidate() path on the dead instance and detach the mounts placed
on top of it.
Take a css reference on the VE for the lifetime of the superblock, so
the comparison always names the VE that really created the instance.
The assignment in kernfs_set_ve_perms() is dropped instead of
converted: it runs right after kernfs_get_tree() in the same mount
context, so it always rewrites the field with the same value.
Fixes: 8d1abf587552 ("fs/kernfs, ve: hide entries from a VE without invalidating the dentry")
https://virtuozzo.atlassian.net/browse/VSTOR-142552
Feature: kernfs: per-CT entries visibility and permissions configuration
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
kernfs_get_tree() stores a bare get_exec_env() pointer in
kernfs_super_info, and since commit 8d1abf587552 ("fs/kernfs, ve:
hide entries from a VE without invalidating the dentry")
kernfs_dop_revalidate() compares it against the caller's VE to decide
between dropping the dentry and answering -ENOENT. Nothing backs that
pointer with a reference: if the mount is pinned from outside - the
host bind-mounted a Container's sysfs, or holds an fd inside it - the
superblock outlives the Container, info->ve dangles, and a later
Container whose ve_struct is allocated at the same address is mistaken
for the creator of the instance. Its lookups then take the
d_invalidate() path on the dead instance and detach the mounts placed
on top of it.
Take a css reference on the VE for the lifetime of the superblock, so
the comparison always names the VE that really created the instance.
The assignment in kernfs_set_ve_perms() is dropped instead of
converted: it runs right after kernfs_get_tree() in the same mount
context, so it always rewrites the field with the same value.
Fixes: 8d1abf587552 ("fs/kernfs, ve: hide entries from a VE without invalidating the dentry")
https://virtuozzo.atlassian.net/browse/VSTOR-142552
---
fs/kernfs/mount.c | 13 ++++++++++---
fs/kernfs/ve.c | 1 -
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
index 14a08ba6ae57d..d4bf659b5f8fe 100644
--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -18,6 +18,7 @@
#include <linux/exportfs.h>
#include <linux/uuid.h>
#include <linux/statfs.h>
+#include <linux/ve.h>
#include "kernfs-internal.h"
#include "kernfs-ve.h"
@@ -362,7 +363,7 @@ int kernfs_get_tree(struct fs_context *fc)
info->root = kfc->root;
info->ns = kfc->ns_tag;
INIT_LIST_HEAD(&info->node);
- info->ve = get_exec_env();
+ info->ve = get_ve(get_exec_env());
fc->s_fs_info = info;
sb = sget_fc(fc, kernfs_test_super, kernfs_set_super);
@@ -397,9 +398,14 @@ int kernfs_get_tree(struct fs_context *fc)
void kernfs_free_fs_context(struct fs_context *fc)
{
+ struct kernfs_super_info *info = fc->s_fs_info;
+
/* Note that we don't deal with kfc->ns_tag here. */
- kfree(fc->s_fs_info);
- fc->s_fs_info = NULL;
+ if (info) {
+ put_ve(info->ve);
+ kfree(info);
+ fc->s_fs_info = NULL;
+ }
}
/**
@@ -424,6 +430,7 @@ void kernfs_kill_sb(struct super_block *sb)
* so we can't find it, before freeing kernfs_super_info.
*/
kill_anon_super(sb);
+ put_ve(info->ve);
kfree(info);
}
diff --git a/fs/kernfs/ve.c b/fs/kernfs/ve.c
index 630ea34d1ccab..1097fd30598e3 100644
--- a/fs/kernfs/ve.c
+++ b/fs/kernfs/ve.c
@@ -28,7 +28,6 @@ void kernfs_set_ve_perms(struct dentry *root, off_t key_off)
struct kernfs_super_info *info = kernfs_info(root->d_sb);
info->ve_perms_off = key_off;
- info->ve = get_exec_env();
}
int kernfs_init_ve_perms(struct kernfs_root *root,
---
base-commit: 0679f0d70523972eec3a0643565521d93e26eb9c
change-id: 20260928-prep-kh-vstor-142552-kernfs-pin-ve-db8e7eb89201
Best regards,
--
Konstantin Khorenko <khorenko@virtuozzo.com>
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel
next reply other threads:[~2026-09-28 16:42 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 16:41 Konstantin Khorenko [this message]
2026-09-29 9:06 ` Pavel Tikhomirov
2026-09-29 11:21 ` Mirian Shilakadze
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=20260928-prep-kh-vstor-142552-kernfs-pin-ve-v1-1-7297e159e813@virtuozzo.com \
--to=khorenko@virtuozzo.com \
--cc=devel@openvz.org \
--cc=mirian.shilakadze@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.