[Devel] [PATCH RH9 06/13] ve/sysfs: add dentries visibility filter

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Sep 21 19:04:24 MSK 2021


From: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

This patch adds sysfs_ve_perms_set set (stored on kerfs_super_info) and per-ve
sysfs_perms_key, allowing to set nodes permissions and hide sysfs entries or
change their access permissions.

This patch adds two attributes to VE cgroup to set sysfs dentries visibility:
  ve.default_sysfs_permissions
in root cgroup and
  ve.sysfs_permissions
in each nested cgroup.

Permissions in "ve.sysfs_permissions" overrides
"ve.default_sysfs_permissions".

An example of default config for sysfs:

/ rx
block rx
class rx
class/block rx
class/net rx
class/tty rx
class/mem rx
devices rx
devices/virtual rx
devices/virtual/tty rx
devices/virtual/tty/tty rx
devices/virtual/tty/tty/uevent rw
devices/virtual/tty/tty/dev r
devices/virtual/tty/console rx
devices/virtual/tty/console/uevent rw
devices/virtual/tty/console/dev r
devices/virtual/tty/ptmx rx
devices/virtual/tty/ptmx/uevent rw
devices/virtual/tty/ptmx/dev r
devices/virtual/tty/tty0 rx
devices/virtual/tty/tty0/uevent rw
devices/virtual/tty/tty0/dev r
devices/virtual/tty/tty1 rx
devices/virtual/tty/tty1/uevent rw
devices/virtual/tty/tty1/dev r
devices/virtual/tty/tty2 rx
devices/virtual/tty/tty2/uevent rw
devices/virtual/tty/tty2/dev r
devices/virtual/mem rx
devices/virtual/mem/null rx
devices/virtual/mem/null/uevent rw
devices/virtual/mem/null/dev r
devices/virtual/mem/zero rx
devices/virtual/mem/zero/uevent rw
devices/virtual/mem/zero/dev r
devices/virtual/mem/full rx
devices/virtual/mem/full/uevent rw
devices/virtual/mem/full/dev r
devices/virtual/mem/random rx
devices/virtual/mem/random/uevent rw
devices/virtual/mem/random/dev r
devices/virtual/mem/urandom rx
devices/virtual/mem/urandom/uevent rw
devices/virtual/mem/urandom/dev r
devices/virtual/net rx
devices/system rx
devices/system/cpu rx
devices/system/cpu/cpu0 rx
devices/system/cpu/cpu1 rx
dev rx
dev/block rx
dev/char rx
fs rx
fs/cgroup rx
kernel rx
kernel/uevent_seqnum r

Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

(cherry-picked from vz8 commit 3eab3da7b99f33b59495c6a765abdb882629330a)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 fs/sysfs/Makefile  |  1 +
 fs/sysfs/mount.c   | 10 ++++-
 fs/sysfs/sysfs.h   | 11 ++++++
 fs/sysfs/ve.c      | 96 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/ve.h |  3 ++
 kernel/ve/ve.c     |  5 +++
 6 files changed, 125 insertions(+), 1 deletion(-)
 create mode 100644 fs/sysfs/ve.c

diff --git a/fs/sysfs/Makefile b/fs/sysfs/Makefile
index 0906b9e522fe..1f9e0ca052a0 100644
--- a/fs/sysfs/Makefile
+++ b/fs/sysfs/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-y		:= file.o dir.o symlink.o mount.o group.o
+obj-$(CONFIG_VE) += ve.o
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index e747c135c1d1..7714e1c67fd1 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -32,8 +32,10 @@ static int sysfs_get_tree(struct fs_context *fc)
 	if (ret)
 		return ret;
 
-	if (kfc->new_sb_created)
+	if (kfc->new_sb_created) {
 		fc->root->d_sb->s_iflags |= SB_I_USERNS_VISIBLE;
+		sysfs_set_ve_perms(fc->root);
+	}
 	return 0;
 }
 
@@ -105,6 +107,12 @@ int __init sysfs_init(void)
 
 	sysfs_root_kn = sysfs_root->kn;
 
+	err = sysfs_init_ve_perms(sysfs_root);
+	if (err) {
+		kernfs_destroy_root(sysfs_root);
+		return err;
+	}
+
 	err = register_filesystem(&sysfs_fs_type);
 	if (err) {
 		kernfs_destroy_root(sysfs_root);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 0050cc0c0236..170504664b57 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -38,4 +38,15 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
 int sysfs_create_link_sd(struct kernfs_node *kn, struct kobject *target,
 			 const char *name);
 
+#ifdef CONFIG_VE
+void sysfs_set_ve_perms(struct dentry *root);
+int sysfs_init_ve_perms(struct kernfs_root *root);
+#else
+static inline void sysfs_set_ve_perms(struct dentry *root) { }
+static inline int sysfs_init_ve_perms(struct kernfs_root *root)
+{
+	return 0;
+}
+#endif
+
 #endif	/* __SYSFS_INTERNAL_H */
diff --git a/fs/sysfs/ve.c b/fs/sysfs/ve.c
new file mode 100644
index 000000000000..4b1f5d54f14d
--- /dev/null
+++ b/fs/sysfs/ve.c
@@ -0,0 +1,96 @@
+/*
+ *  fs/sysfs/ve.c
+ *
+ *  Copyright (c) 2018-2021 Virtuozzo International GmbH. All rights reserved.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/ve.h>
+#include "sysfs.h"
+
+#include "linux/kernfs-ve.h"
+
+struct kmapset_set sysfs_ve_perms_set;
+
+static DEFINE_MUTEX(sysfs_perms_mutex);
+
+void sysfs_set_ve_perms(struct dentry *root)
+{
+	kernfs_set_ve_perms(root, offsetof(struct ve_struct,
+					   sysfs_perms_key));
+}
+
+int sysfs_init_ve_perms(struct kernfs_root *root)
+{
+	return kernfs_init_ve_perms(root, &sysfs_ve_perms_set);
+}
+
+static void *sysfs_perms_start(struct seq_file *m, loff_t *ppos)
+{
+	struct ve_struct *ve = css_to_ve(seq_css(m));
+
+	mutex_lock(&sysfs_perms_mutex);
+	return kernfs_perms_start(m, ppos, sysfs_root_kn, &ve->sysfs_perms_key);
+}
+
+static void *sysfs_perms_next(struct seq_file *m, void *v, loff_t *ppos)
+{
+	struct ve_struct *ve = css_to_ve(seq_css(m));
+
+	return kernfs_perms_next(m, v, ppos, &ve->sysfs_perms_key);
+}
+
+static void sysfs_perms_stop(struct seq_file *m, void *v)
+{
+	kernfs_perms_stop(m, v);
+	mutex_unlock(&sysfs_perms_mutex);
+}
+
+static int sysfs_perms_show(struct seq_file *m, void *v)
+{
+	struct ve_struct *ve = css_to_ve(seq_css(m));
+
+	return kernfs_perms_show(m, v, &ve->sysfs_perms_key);
+}
+
+static ssize_t sysfs_perms_write(struct kernfs_open_file *of,
+				 char *buf, size_t nbytes, loff_t off)
+{
+	struct ve_struct *ve = css_to_ve(of_css(of));
+	ssize_t ret;
+
+	mutex_lock(&sysfs_perms_mutex);
+	ret = kernfs_perms_write(of, buf, nbytes, off,
+				 sysfs_root_kn, &ve->sysfs_perms_key);
+	mutex_unlock(&sysfs_perms_mutex);
+	return ret;
+}
+
+static struct cftype sysfs_ve_cftypes[] = {
+	{
+		.name = "default_sysfs_permissions",
+		.flags = CFTYPE_ONLY_ON_ROOT,
+		.seq_start = sysfs_perms_start,
+		.seq_next = sysfs_perms_next,
+		.seq_stop = sysfs_perms_stop,
+		.seq_show = sysfs_perms_show,
+		.write = sysfs_perms_write,
+	},
+	{
+		.name = "sysfs_permissions",
+		.flags = CFTYPE_NOT_ON_ROOT,
+		.seq_start = sysfs_perms_start,
+		.seq_next = sysfs_perms_next,
+		.seq_stop = sysfs_perms_stop,
+		.seq_show = sysfs_perms_show,
+		.write = sysfs_perms_write,
+	},
+	{ },
+};
+
+static int init_sysfve_perms(void)
+{
+	return cgroup_add_legacy_cftypes(&ve_cgrp_subsys, sysfs_ve_cftypes);
+}
+module_init(init_sysfve_perms);
diff --git a/include/linux/ve.h b/include/linux/ve.h
index 2c9ef05ffcb7..92daafbd9e44 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/ve_proto.h>
 #include <linux/cgroup.h>
+#include <linux/kmapset.h>
 
 struct nsproxy;
 struct veip_struct;
@@ -45,6 +46,8 @@ struct ve_struct {
 
 	/* see vzcalluser.h for VE_FEATURE_XXX definitions */
 	__u64			features;
+
+	struct kmapset_key	sysfs_perms_key;
 };
 
 extern int nr_ve;
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 3d7293895478..e9148116a019 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -18,10 +18,13 @@
 #include <linux/rcupdate.h>
 #include <linux/init_task.h>
 #include <linux/mutex.h>
+#include <linux/kmapset.h>
 #include <uapi/linux/vzcalluser.h>
 
 #include "../cgroup/cgroup-internal.h" /* For cgroup_task_count() */
 
+extern struct kmapset_set sysfs_ve_perms_set;
+
 static struct kmem_cache *ve_cachep;
 
 struct ve_struct ve0 = {
@@ -309,6 +312,7 @@ static struct cgroup_subsys_state *ve_create(struct cgroup_subsys_state *parent_
 do_init:
 	init_rwsem(&ve->op_sem);
 	INIT_LIST_HEAD(&ve->ve_list);
+	kmapset_init_key(&ve->sysfs_perms_key);
 	return &ve->css;
 
 err_ve:
@@ -349,6 +353,7 @@ static void ve_destroy(struct cgroup_subsys_state *css)
 {
 	struct ve_struct *ve = css_to_ve(css);
 
+	kmapset_unlink(&ve->sysfs_perms_key, &sysfs_ve_perms_set);
 	kmem_cache_free(ve_cachep, ve);
 }
 
-- 
2.31.1



More information about the Devel mailing list