The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.8.x-ovz" and will appear 
at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.6.8
------>
commit 9c0a32ed2a39800f298cf96308530c805a9188fd
Author: Andrew Vagin <ava...@openvz.org>
Date:   Tue Sep 8 12:45:07 2015 +0400

    cred: add ve_capable to check capabilities relative to the current VE (v2)
    
    We want to allow a few operations in VE. Currently we use nsown_capable,
    but it's wrong, because in this case we allow these operations in any
    user namespace.
    
    v2: take ve0->cred if the currect ve isn't running
    
    https://jira.sw.ru/browse/PSBM-39077
    
    Signed-off-by: Andrew Vagin <ava...@virtuozzo.com>
    Reviewed-by: Vladimir Davydov <vdavy...@virtuozzo.com>
---
 fs/autofs4/root.c          |  6 ++----
 fs/ioprio.c                |  2 +-
 fs/namei.c                 |  2 +-
 include/linux/capability.h |  1 +
 kernel/capability.c        | 20 ++++++++++++++++++++
 kernel/printk.c            |  5 ++---
 net/ipv6/sit.c             |  2 +-
 net/netfilter/nf_sockopt.c |  2 +-
 security/commoncap.c       |  4 ++--
 security/device_cgroup.c   |  4 ++--
 10 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 68e3edb..1462d8b 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -588,8 +588,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct 
dentry *dentry)
        struct autofs_info *p_ino;
        
        /* This allows root to remove symlinks */
-       if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) &&
-           !capable(CAP_VE_SYS_ADMIN))
+       if (!autofs4_oz_mode(sbi) && !ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        if (atomic_dec_and_test(&ino->count)) {
@@ -837,8 +836,7 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, 
struct file *filp,
             _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
                return -ENOTTY;
        
-       if (!autofs4_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) &&
-           !capable(CAP_VE_SYS_ADMIN))
+       if (!autofs4_oz_mode(sbi) && !ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
        
        switch(cmd) {
diff --git a/fs/ioprio.c b/fs/ioprio.c
index c876fad..f9d9187 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -75,7 +75,7 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
 
                switch (class) {
                        case IOPRIO_CLASS_RT:
-                               if (!capable(CAP_VE_ADMIN))
+                               if (!ve_capable(CAP_SYS_ADMIN))
                                        return -EPERM;
                                class = IOPRIO_CLASS_BE;
                                data = 0;
diff --git a/fs/namei.c b/fs/namei.c
index 8e29a44..e7d9f54 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3397,7 +3397,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, 
umode_t mode, dev_t dev)
        if (error)
                return error;
 
-       if ((S_ISCHR(mode) || S_ISBLK(mode)) && !nsown_capable(CAP_MKNOD))
+       if ((S_ISCHR(mode) || S_ISBLK(mode)) && !ve_capable(CAP_MKNOD))
                return -EPERM;
 
        if (!dir->i_op->mknod)
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 2b77384..b1131e3 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -217,6 +217,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
 extern bool nsown_capable(int cap);
+extern bool ve_capable(int cap);
 extern bool inode_capable(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace 
*ns, int cap);
 
diff --git a/kernel/capability.c b/kernel/capability.c
index 0a843d5..4a73381 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -16,6 +16,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/user_namespace.h>
 #include <asm/uaccess.h>
+#include <linux/ve.h>
 
 /*
  * Leveraged for setting/resetting capabilities
@@ -396,6 +397,25 @@ bool ns_capable(struct user_namespace *ns, int cap)
 }
 EXPORT_SYMBOL(ns_capable);
 
+#if CONFIG_VE
+bool ve_capable(int cap)
+{
+       struct cred *cred = get_exec_env()->init_cred;
+
+       if (cred == NULL) /* ve isn't running */
+               cred = ve0.init_cred;
+
+       return ns_capable(cred->user_ns, cap);
+}
+#else
+bool ve_capable(int cap)
+{
+       return capable(cap);
+}
+#endif
+
+EXPORT_SYMBOL_GPL(ve_capable);
+
 /**
  * file_ns_capable - Determine if the file's opener had a capability in effect
  * @file:  The file we want to check
diff --git a/kernel/printk.c b/kernel/printk.c
index 44b3783..91766fc 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -468,14 +468,13 @@ static int check_syslog_permissions(int type, bool 
from_file)
                return 0;
 
        if (syslog_action_restricted(type)) {
-               if (nsown_capable(CAP_SYSLOG))
+               if (ve_capable(CAP_SYSLOG))
                        return 0;
                /*
                 * For historical reasons, accept CAP_SYS_ADMIN too, with
                 * a warning.
                 */
-               if (nsown_capable(CAP_SYS_ADMIN) ||
-                   nsown_capable(CAP_VE_ADMIN)) {
+               if (ve_capable(CAP_SYS_ADMIN)) {
                        pr_warn_once("%s (%d): Attempt to access syslog with "
                                     "CAP_SYS_ADMIN but no CAP_SYSLOG "
                                     "(deprecated).\n",
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 8f4c52d..0cbb2b2 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -309,7 +309,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
        /* For simple GET or for root users,
         * we try harder to allocate.
         */
-       kp = (cmax <= 1 || capable(CAP_NET_ADMIN) || capable(CAP_VE_NET_ADMIN)) 
?
+       kp = (cmax <= 1 || ve_capable(CAP_NET_ADMIN)) ?
                kcalloc(cmax, sizeof(*kp), GFP_KERNEL) :
                NULL;
 
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 84dfd09..951a11b 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -115,7 +115,7 @@ static int ve0_load_sockopt_module(struct net *net, u8 pf, 
int val, int get)
        const char *name;
        int ret = -EPERM;
 
-       if (!capable(CAP_VE_NET_ADMIN))
+       if (!ve_capable(CAP_NET_ADMIN))
                goto out;
 
        if (sockopt_module_fits(pf, val, get, PF_INET,
diff --git a/security/commoncap.c b/security/commoncap.c
index 59ff538..9d0a2b6 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -654,7 +654,7 @@ int cap_inode_setxattr(struct dentry *dentry, const char 
*name,
 
        if (!strncmp(name, XATTR_SECURITY_PREFIX,
                     sizeof(XATTR_SECURITY_PREFIX) - 1) &&
-           !capable(CAP_SYS_ADMIN) && !capable(CAP_VE_ADMIN))
+           !ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
        return 0;
 }
@@ -680,7 +680,7 @@ int cap_inode_removexattr(struct dentry *dentry, const char 
*name)
 
        if (!strncmp(name, XATTR_SECURITY_PREFIX,
                     sizeof(XATTR_SECURITY_PREFIX) - 1) &&
-           !capable(CAP_SYS_ADMIN) && !capable(CAP_VE_ADMIN))
+           !ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
        return 0;
 }
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 375711e..531e40c 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -83,7 +83,7 @@ static int devcgroup_can_attach(struct cgroup *new_cgrp,
 {
        struct task_struct *task = cgroup_taskset_first(set);
 
-       if (current != task && !capable(CAP_SYS_ADMIN) && 
!capable(CAP_VE_SYS_ADMIN))
+       if (current != task && !ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
        return 0;
 }
@@ -673,7 +673,7 @@ static int devcgroup_update_access(struct dev_cgroup 
*devcgroup,
        struct cgroup *p = devcgroup->css.cgroup;
        struct dev_cgroup *parent = NULL;
 
-       if (!capable(CAP_SYS_ADMIN) && !capable(CAP_VE_SYS_ADMIN))
+       if (!ve_capable(CAP_SYS_ADMIN))
                return -EPERM;
 
        if (p->parent)
_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to