[Devel] [PATCH RHEL COMMIT] ve/kernfs: hide forbidden entries in container
Konstantin Khorenko
khorenko at virtuozzo.com
Wed Sep 22 14:50:53 MSK 2021
The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit 78c8e4d3ddf37b781f1d2d199ad9817efafb6a02
Author: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
Date: Wed Sep 22 14:50:53 2021 +0300
ve/kernfs: hide forbidden entries in container
Hide kernfs entries if kernfs superblock instance owner has no permissions for
them.
Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
(cherry-picked from vz8 commit 7becc92d98d2e17a10a80b1781d1301be7beeb0f)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
fs/kernfs/dir.c | 11 +++++++++++
fs/kernfs/kernfs-ve.h | 7 +++++++
fs/kernfs/ve.c | 28 ++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index f77ca8e1a301..f576c5ba364b 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1064,6 +1064,9 @@ 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;
+
mutex_unlock(&kernfs_mutex);
return 1;
out_bad:
@@ -1099,6 +1102,11 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
goto out_unlock;
}
+ if(!kernfs_d_visible(kn, kernfs_info(dentry->d_sb))) {
+ ret = NULL;
+ goto out_unlock;
+ }
+
/* attach dentry and inode */
inode = kernfs_get_inode(dir->i_sb, kn);
if (!inode) {
@@ -1691,6 +1699,9 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
file->private_data = pos;
kernfs_get(pos);
+ if (!kernfs_d_visible(pos, kernfs_info(dentry->d_sb)))
+ continue;
+
mutex_unlock(&kernfs_mutex);
if (!dir_emit(ctx, name, len, ino, type))
return 0;
diff --git a/fs/kernfs/kernfs-ve.h b/fs/kernfs/kernfs-ve.h
index 2420af5d5091..116898829e07 100644
--- a/fs/kernfs/kernfs-ve.h
+++ b/fs/kernfs/kernfs-ve.h
@@ -23,6 +23,8 @@ int kernfs_ve_permission(struct kernfs_node *kn,
int kernfs_ve_allowed(struct kernfs_node *kn);
+bool kernfs_d_visible(struct kernfs_node *kn, struct kernfs_super_info *info);
+
#else // CONFIG_VE
void kernfs_get_ve_perms(struct kernfs_node *kn) { }
@@ -39,6 +41,11 @@ static inline int kernfs_ve_allowed(void)
return 1;
}
+bool kernfs_d_visible(struct kernfs_node *kn, struct kernfs_super_info *info)
+{
+ return true;
+}
+
#endif
#endif
diff --git a/fs/kernfs/ve.c b/fs/kernfs/ve.c
index 94cd5913ca3a..383724fb2dae 100644
--- a/fs/kernfs/ve.c
+++ b/fs/kernfs/ve.c
@@ -98,3 +98,31 @@ void kernfs_put_ve_perms(struct kernfs_node *kn)
if (kn->ve_perms_map)
kmapset_put(kn->ve_perms_map);
}
+
+bool kernfs_d_visible(struct kernfs_node *kn, struct kernfs_super_info *info)
+{
+ struct ve_struct *ve = info->ve;
+ struct kernfs_node *tmp_kn = kn;
+
+ /* Non-containerized fs */
+ if (!ve)
+ return true;
+
+ /* Host sees anything */
+ if (ve_is_super(ve))
+ return true;
+
+ /* Entries with namespace tag and their sub-entries always visible */
+ while (tmp_kn) {
+ if (tmp_kn->ns)
+ return true;
+ tmp_kn = tmp_kn->parent;
+ }
+
+ /* Symlinks are visible if target kn is visible */
+ if (kernfs_type(kn) == KERNFS_LINK)
+ kn = kn->symlink.target_kn;
+
+ return !!kmapset_get_value(kn->ve_perms_map,
+ kernfs_info_perms_key(info));
+}
More information about the Devel
mailing list