From cec3b544d120f6243198e6698513db628586f2fb Mon Sep 17 00:00:00 2001 From: Zhi Li Date: Thu, 11 Aug 2011 13:27:50 +0800 Subject: [PATCH] --- yaml --- r: 264498 b: refs/heads/master c: 4d49f6710bfbd2271feab074f8c1053387e5d9fe h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/security/commoncap.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index ac0a587fcf88..6d6374dcf6af 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f995e74087402c482c55c29bf11da8bcf631245a +refs/heads/master: 4d49f6710bfbd2271feab074f8c1053387e5d9fe diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index a93b3b733079..0f620c564fa8 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -332,7 +332,8 @@ int cap_inode_killpriv(struct dentry *dentry) */ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, struct linux_binprm *bprm, - bool *effective) + bool *effective, + bool *has_cap) { struct cred *new = bprm->cred; unsigned i; @@ -341,6 +342,9 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, if (caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE) *effective = true; + if (caps->magic_etc & VFS_CAP_REVISION_MASK) + *has_cap = true; + CAP_FOR_EACH_U32(i) { __u32 permitted = caps->permitted.cap[i]; __u32 inheritable = caps->inheritable.cap[i]; @@ -424,7 +428,7 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data * its xattrs and, if present, apply them to the proposed credentials being * constructed by execve(). */ -static int get_file_caps(struct linux_binprm *bprm, bool *effective) +static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap) { struct dentry *dentry; int rc = 0; @@ -450,7 +454,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective) goto out; } - rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective); + rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap); if (rc == -EINVAL) printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n", __func__, rc, bprm->filename); @@ -475,11 +479,11 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) { const struct cred *old = current_cred(); struct cred *new = bprm->cred; - bool effective; + bool effective, has_cap; int ret; effective = false; - ret = get_file_caps(bprm, &effective); + ret = get_file_caps(bprm, &effective, &has_cap); if (ret < 0) return ret; @@ -489,7 +493,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) * for a setuid root binary run by a non-root user. Do set it * for a root user just to cause least surprise to an admin. */ - if (effective && new->uid != 0 && new->euid == 0) { + if (has_cap && new->uid != 0 && new->euid == 0) { warn_setuid_and_fcaps_mixed(bprm->filename); goto skip; }