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 <[email protected]>
---
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)
--
2.47.1
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel