[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