[Devel] [PATCH vz10 09/24] kernfs: rcu_read_lock() when walking parents in ve visibility checks

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Thu Jul 23 17:36:42 MSK 2026


This is similar to "fs/kernfs, ve: fix ve_perms_map use-after-free,
annotate it __rcu" (which is even a bit stronger version, and I
already merged it).

So this can be dropped.

On 7/6/26 12:59, Konstantin Khorenko wrote:
> kernfs_ve_permission() and kernfs_d_visible() walk the parent chain with
> kernfs_parent(), which is rcu_dereference_check(kn->__parent, ...) and
> requires the kernfs rwsem/rename_lock, a zero refcount, or an RCU
> read-side critical section. They are called from the permission/lookup
> path holding only kernfs_iattr_rwsem, so on a lockdep kernel this trips:
> 
>   WARNING: suspicious RCU usage
>   fs/kernfs/kernfs-internal.h:131 suspicious rcu_dereference_check() usage!
>   kernfs_ve_permission <- kernfs_iop_permission <- inode_permission
> 
> Wrap the parent walks in rcu_read_lock(); kernfs nodes are RCU-freed so
> this is both correct (guards against concurrent reparent/free) and
> silences the splat.
> 
> Fixes: cd9dd4ead86a ("ve/kernfs: implement ve-based permissions")
> Feature: sysfs: per-CT entries visibility and permissions configuration
> https://virtuozzo.atlassian.net/browse/VSTOR-137234
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
> ---
>  fs/kernfs/ve.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/kernfs/ve.c b/fs/kernfs/ve.c
> index beaa278b014e..e83ee5bec3bf 100644
> --- a/fs/kernfs/ve.c
> +++ b/fs/kernfs/ve.c
> @@ -64,11 +64,15 @@ int kernfs_ve_permission(struct kernfs_node *kn,
>  		return 0;
>  
>  	/* Entries with namespace tag and their sub-entries always visible */
> +	rcu_read_lock();
>  	while (tmp_kn) {
> -		if (tmp_kn->ns)
> +		if (tmp_kn->ns) {
> +			rcu_read_unlock();
>  			return 0;
> +		}
>  		tmp_kn = kernfs_parent(tmp_kn);
>  	}
> +	rcu_read_unlock();
>  
>  	if (kernfs_type(kn) == KERNFS_LINK)
>  		kn = kn->symlink.target_kn;
> @@ -108,11 +112,15 @@ bool kernfs_d_visible(struct kernfs_node *kn, struct kernfs_super_info *info)
>  		return true;
>  
>  	/* Entries with namespace tag and their sub-entries always visible */
> +	rcu_read_lock();
>  	while (tmp_kn) {
> -		if (tmp_kn->ns)
> +		if (tmp_kn->ns) {
> +			rcu_read_unlock();
>  			return true;
> +		}
>  		tmp_kn = kernfs_parent(tmp_kn);
>  	}
> +	rcu_read_unlock();
>  
>  	/* Symlinks are visible if target kn is visible */
>  	if (kernfs_type(kn) == KERNFS_LINK)

-- 
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.



More information about the Devel mailing list