From: Konstantin Khlebnikov <khlebni...@openvz.org> This patch patch adds lightweight virualization for sysctl entries:
with S_ISVTX without S_ISVTX init_pid_ns read-write read-write container read-write read-only https://jira.sw.ru/browse/PSBM-18022 Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org> +++ VE/PROC/SYSCTL: show real permissions in stat This patch calls ->permissions() callback from ->getattr() method, as result stat() for proc entries in /proc/sys will show real permissions. Also this patch hides sticky-bit (S_ISVTX). Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org> +++ ve/fs: Fix invalid dereference in proc_sys_getattr() grab_header() may return -ENOENT. In this case root in the below struct ctl_table_header *head = grab_header(inode); struct ctl_table_root *root = head->root; dereferences (void *)-ENOENT, that leads to page fault and crash. Fix that. https://jira.sw.ru/browse/PSBM-56704 Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> mFixes (to merge): ac555dd ("VE/PROC/SYSCTL: show real permissions in stat") + hunk from 95c9cb3 ("SYSCTL: fix compilation") +++ VE: use ve environtment for sysctl restrictions https://jira.sw.ru/browse/PSBM-18032 https://jira.sw.ru/browse/PSBM-18030 Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org> (cherry picked from commit 57c6f66050d2176f8a9847f8284cb3d345863a88) Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com> Moving root variable to make proc_sys_getattr code more solid. Note: sysctl_root_permissions check does not affect /proc/sys/user /proc/sys/net sysctls, they have their own ->permissions handlers. (cherry picked from vz8 commit bdc26f95dd3371b8b80fa943215065e0836f7fb5) Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com> --- fs/proc/proc_sysctl.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 5d66faecd4ef..f6415add610e 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -11,6 +11,7 @@ #include <linux/sched.h> #include <linux/cred.h> #include <linux/namei.h> +#include <linux/nsproxy.h> #include <linux/mm.h> #include <linux/uio.h> #include <linux/module.h> @@ -66,6 +67,16 @@ static struct ctl_table root_table[] = { }, { } }; + +static int sysctl_root_permissions(struct ctl_table_header *head, + struct ctl_table *table) +{ + if (ve_is_super(get_exec_env()) || (table->mode & S_ISVTX)) + return table->mode; + + return table->mode & ~S_IWUGO; +} + static struct ctl_table_root sysctl_table_root = { .default_set.dir.header = { {{.count = 1, @@ -75,6 +86,7 @@ static struct ctl_table_root sysctl_table_root = { .root = &sysctl_table_root, .set = &sysctl_table_root.default_set, }, + .permissions = sysctl_root_permissions, }; static DEFINE_SPINLOCK(sysctl_lock); @@ -452,7 +464,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, spin_unlock(&sysctl_lock); inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); - inode->i_mode = table->mode; + inode->i_mode = table->mode & S_IRWXUGO; if (!S_ISDIR(table->mode)) { inode->i_mode |= S_IFREG; inode->i_op = &proc_sys_inode_operations; @@ -839,8 +851,16 @@ static int proc_sys_getattr(struct user_namespace *mnt_userns, return PTR_ERR(head); generic_fillattr(&init_user_ns, inode, stat); - if (table) - stat->mode = (stat->mode & S_IFMT) | table->mode; + + if (table) { + struct ctl_table_root *root = head->root; + umode_t mode = table->mode; + + if (root->permissions) + mode = root->permissions(head, table); + + stat->mode = (stat->mode & S_IFMT) | (mode & S_IRWXUGO); + } sysctl_head_finish(head); return 0; @@ -1135,11 +1155,13 @@ static int sysctl_check_table(const char *path, struct ctl_table *table) err |= sysctl_err(path, table, "No maxlen"); else err |= sysctl_check_table_array(path, table); + if (table->mode & S_ISVTX) + err |= sysctl_err(path, table, "Unsafe v12n"); } if (!table->proc_handler) err |= sysctl_err(path, table, "No proc_handler"); - if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode) + if ((table->mode & (S_IRUGO|S_IWUGO|S_ISVTX)) != table->mode) err |= sysctl_err(path, table, "bogus .mode 0%o", table->mode); } -- 2.31.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel