[Devel] [PATCH RH9 02/16] ve/sysctl: implement virtualized methods

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Sep 28 15:40:52 MSK 2021


From: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

add new helpers for sysctl virtualization:
proc_dointvec_virtual() (it maps data pointer from ve0 to current exec env,
			 will be extedned to work with other nemspaces/cgroups)
proc_dointvec_immutable() (ignores writes from container)
proc_dostring_immutable()

Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>

+++
VE: use ve environtment for sysctl restrictions

https://jira.sw.ru/browse/PSBM-18032
https://jira.sw.ru/browse/PSBM-18030
https://jira.sw.ru/browse/PSBM-29017
https://jira.sw.ru/browse/PSBM-43596

Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
Signed-off-by: Andrey Ryabinin <aryabinin at odin.com>
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>

(cherry picked from commit 9d020b764ccc1872bae8241228c13265bf1d5c33)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>

(cherry-picked from vz8 commit cf90b2bfb592e389c3704842d7043a52313377ae)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 include/linux/sysctl.h | 11 +++++++++
 kernel/sysctl.c        | 55 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index d99ca99837de..4c9efe69e435 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -67,6 +67,17 @@ int proc_do_large_bitmap(struct ctl_table *, int, void *, size_t *, loff_t *);
 int proc_do_static_key(struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 
+extern int proc_dointvec_virtual(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
+extern int proc_doulongvec_minmax_virtual(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
+extern int proc_dointvec_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
+extern int proc_dostring_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
+extern int proc_dointvec_minmax_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
+
 /*
  * Register a set of sysctl names by calling register_sysctl_table
  * with an initialised array of struct ctl_table's.  An entry with 
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 081e42171745..1b203142e645 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -155,6 +155,17 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
 #include <linux/fanotify.h>
 #endif
 
+static bool virtual_ptr(void **ptr, void *base, size_t size, void *cur);
+#define sysctl_virtual(sysctl)							\
+int sysctl ## _virtual(struct ctl_table *table, int write,			\
+		        void __user *buffer, size_t *lenp, loff_t *ppos)	\
+{										\
+	struct ctl_table tmp = *table;						\
+	if (virtual_ptr(&tmp.data, &ve0, sizeof(ve0), get_exec_env()))		\
+		return sysctl(&tmp, write, buffer, lenp, ppos);			\
+	return -EINVAL;								\
+}
+
 #ifdef CONFIG_PROC_SYSCTL
 
 /**
@@ -1628,6 +1639,50 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 	return err;
 }
 
+static bool virtual_ptr(void **ptr, void *base, size_t size, void *cur)
+{
+	unsigned long addr = (unsigned long)*ptr;
+	unsigned long base_addr = (unsigned long)base;
+
+	if (addr >= base_addr && addr < base_addr + size) {
+		*ptr = (char *)cur + (addr - base_addr);
+		return true;
+	}
+	return false;
+}
+
+sysctl_virtual(proc_dointvec);
+sysctl_virtual(proc_doulongvec_minmax);
+
+static inline bool sysctl_in_container(void)
+{
+	return !ve_is_super(get_exec_env());
+}
+
+int proc_dointvec_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	if (write && sysctl_in_container())
+		return 0;
+	return proc_dointvec(table, write, buffer, lenp, ppos);
+}
+
+int proc_dostring_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	if (write && sysctl_in_container())
+		return 0;
+	return proc_dostring(table, write, buffer, lenp, ppos);
+}
+
+int proc_dointvec_minmax_immutable(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	if (write && sysctl_in_container())
+		return 0;
+	return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+}
+
 #else /* CONFIG_PROC_SYSCTL */
 
 int proc_dostring(struct ctl_table *table, int write,
-- 
2.31.1



More information about the Devel mailing list