[Devel] [PATCH vz10 4/7] fs/kernfs, ve: take rcu_read_lock around the ve_perms kmapset lookup
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Jun 30 13:44:42 MSK 2026
On 6/28/26 11:26, Mirian Shilakadze wrote:
> kernfs_perms_shown() tests a node's ve_perms_map with kmapset_lookup(),
> which walks an rcu hlist (map->links). That walk must run inside an rcu
> read-side critical section, but the seq read holds only kernfs_rwsem and
> the caller's perms mutex, neither of which is one.
>
> kmapset frees links with kfree_rcu() from kmapset_unlink() (called by
> ve_destroy()) and kmapset_del_value(), under the kmapset set lock, a
> different lock from the ones the reader holds. So a concurrent VE teardown
> can free a link the lookup is walking, a use-after-free.
>
> Take rcu_read_lock() around the lookup. kernfs_perms_show() reaches the
> same list walk through kmapset_get_value(), which already takes
> rcu_read_lock() itself, so only kernfs_perms_shown() needs the wrapper.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-136480
> Fixes: 008aa8b6ff0b ("ve/kernfs: add new interface to control per-VE nodes visibility")
> Signed-off-by: Mirian Shilakadze <mirian.shilakadze at virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
> fs/kernfs/ve.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/fs/kernfs/ve.c b/fs/kernfs/ve.c
> index 2858b7e97f6e..66bb4b534f48 100644
> --- a/fs/kernfs/ve.c
> +++ b/fs/kernfs/ve.c
> @@ -146,11 +146,17 @@ static struct kernfs_node *kernfs_next_recursive(struct kernfs_node *kn)
> static bool kernfs_perms_shown(struct ve_struct *ve, struct kernfs_node *kn,
> struct kmapset_key *key)
> {
> + bool ret;
> +
> if (!kn->ve_perms_map)
> return false;
> if (ve_is_super(ve))
> return kn->ve_perms_map->default_value != 0;
> - return kmapset_lookup(kn->ve_perms_map, key) != NULL;
> + /* kmapset_lookup() walks an rcu list, so keep the section to the lookup. */
> + rcu_read_lock();
> + ret = kmapset_lookup(kn->ve_perms_map, key) != NULL;
> + rcu_read_unlock();
> + return ret;
> }
>
> void *kernfs_perms_start(struct seq_file *m, loff_t *ppos,
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list