summaryrefslogtreecommitdiff
path: root/security/commoncap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 08:06:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 08:06:39 -0700
commitbb2cbf5e9367d8598fecd0c48dead69560750223 (patch)
treefb2c620451b90f41a31726bdd82077813f941e39 /security/commoncap.c
parente7fda6c4c3c1a7d6996dd75fd84670fa0b5d448f (diff)
parent478d085524c57cf4283699f529d5a4c22188ea69 (diff)
downloadlinux-bb2cbf5e9367d8598fecd0c48dead69560750223.tar.gz
linux-bb2cbf5e9367d8598fecd0c48dead69560750223.tar.bz2
linux-bb2cbf5e9367d8598fecd0c48dead69560750223.zip
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris: "In this release: - PKCS#7 parser for the key management subsystem from David Howells - appoint Kees Cook as seccomp maintainer - bugfixes and general maintenance across the subsystem" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (94 commits) X.509: Need to export x509_request_asymmetric_key() netlabel: shorter names for the NetLabel catmap funcs/structs netlabel: fix the catmap walking functions netlabel: fix the horribly broken catmap functions netlabel: fix a problem when setting bits below the previously lowest bit PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1 tpm: simplify code by using %*phN specifier tpm: Provide a generic means to override the chip returned timeouts tpm: missing tpm_chip_put in tpm_get_random() tpm: Properly clean sysfs entries in error path tpm: Add missing tpm_do_selftest to ST33 I2C driver PKCS#7: Use x509_request_asymmetric_key() Revert "selinux: fix the default socket labeling in sock_graft()" X.509: x509_request_asymmetric_keys() doesn't need string length arguments PKCS#7: fix sparse non static symbol warning KEYS: revert encrypted key change ima: add support for measuring and appraising firmware firmware_class: perform new LSM checks security: introduce kernel_fw_from_file hook PKCS#7: Missing inclusion of linux/err.h ...
Diffstat (limited to 'security/commoncap.c')
-rw-r--r--security/commoncap.c75
1 files changed, 33 insertions, 42 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index b9d613e0ef14..bab0611afc1e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -421,6 +421,9 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable);
}
+ cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
+ cpu_caps->inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
+
return 0;
}
@@ -822,15 +825,20 @@ int cap_task_setnice(struct task_struct *p, int nice)
* Implement PR_CAPBSET_DROP. Attempt to remove the specified capability from
* the current task's bounding set. Returns 0 on success, -ve on error.
*/
-static long cap_prctl_drop(struct cred *new, unsigned long cap)
+static int cap_prctl_drop(unsigned long cap)
{
+ struct cred *new;
+
if (!ns_capable(current_user_ns(), CAP_SETPCAP))
return -EPERM;
if (!cap_valid(cap))
return -EINVAL;
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
cap_lower(new->cap_bset, cap);
- return 0;
+ return commit_creds(new);
}
/**
@@ -848,26 +856,17 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap)
int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
+ const struct cred *old = current_cred();
struct cred *new;
- long error = 0;
-
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
switch (option) {
case PR_CAPBSET_READ:
- error = -EINVAL;
if (!cap_valid(arg2))
- goto error;
- error = !!cap_raised(new->cap_bset, arg2);
- goto no_change;
+ return -EINVAL;
+ return !!cap_raised(old->cap_bset, arg2);
case PR_CAPBSET_DROP:
- error = cap_prctl_drop(new, arg2);
- if (error < 0)
- goto error;
- goto changed;
+ return cap_prctl_drop(arg2);
/*
* The next four prctl's remain to assist with transitioning a
@@ -889,10 +888,9 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
* capability-based-privilege environment.
*/
case PR_SET_SECUREBITS:
- error = -EPERM;
- if ((((new->securebits & SECURE_ALL_LOCKS) >> 1)
- & (new->securebits ^ arg2)) /*[1]*/
- || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
+ if ((((old->securebits & SECURE_ALL_LOCKS) >> 1)
+ & (old->securebits ^ arg2)) /*[1]*/
+ || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
|| (cap_capable(current_cred(),
current_cred()->user_ns, CAP_SETPCAP,
@@ -906,46 +904,39 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
*/
)
/* cannot change a locked bit */
- goto error;
+ return -EPERM;
+
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
new->securebits = arg2;
- goto changed;
+ return commit_creds(new);
case PR_GET_SECUREBITS:
- error = new->securebits;
- goto no_change;
+ return old->securebits;
case PR_GET_KEEPCAPS:
- if (issecure(SECURE_KEEP_CAPS))
- error = 1;
- goto no_change;
+ return !!issecure(SECURE_KEEP_CAPS);
case PR_SET_KEEPCAPS:
- error = -EINVAL;
if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */
- goto error;
- error = -EPERM;
+ return -EINVAL;
if (issecure(SECURE_KEEP_CAPS_LOCKED))
- goto error;
+ return -EPERM;
+
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
if (arg2)
new->securebits |= issecure_mask(SECURE_KEEP_CAPS);
else
new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
- goto changed;
+ return commit_creds(new);
default:
/* No functionality available - continue with default */
- error = -ENOSYS;
- goto error;
+ return -ENOSYS;
}
-
- /* Functionality provided */
-changed:
- return commit_creds(new);
-
-no_change:
-error:
- abort_creds(new);
- return error;
}
/**