aboutsummaryrefslogtreecommitdiffstats
path: root/security/commoncap.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2012-01-03 12:25:14 -0500
committerEric Paris <eparis@redhat.com>2012-01-05 18:52:53 -0500
commit6a9de49115d5ff9871d953af1a5c8249e1585731 (patch)
treeeee3700ccc2ce26c566bfe99129e646fac9f983e /security/commoncap.c
parent2653812e14f4e16688ec8247d7fd290bdbbc4747 (diff)
capabilities: remove the task from capable LSM hook entirely
The capabilities framework is based around credentials, not necessarily the current task. Yet we still passed the current task down into LSMs from the security_capable() LSM hook as if it was a meaningful portion of the security decision. This patch removes the 'generic' passing of current and instead forces individual LSMs to use current explicitly if they think it is appropriate. In our case those LSMs are SELinux and AppArmor. I believe the AppArmor use of current is incorrect, but that is wholely unrelated to this patch. This patch does not change what AppArmor does, it just makes it clear in the AppArmor code that it is doing it. The SELinux code still uses current in it's audit message, which may also be wrong and needs further investigation. Again this is NOT a change, it may have always been wrong, this patch just makes it clear what is happening. Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/commoncap.c')
-rw-r--r--security/commoncap.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index a93b3b733079..89f02ff66af9 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(cap_netlink_recv);
66 66
67/** 67/**
68 * cap_capable - Determine whether a task has a particular effective capability 68 * cap_capable - Determine whether a task has a particular effective capability
69 * @tsk: The task to query
70 * @cred: The credentials to use 69 * @cred: The credentials to use
71 * @ns: The user namespace in which we need the capability 70 * @ns: The user namespace in which we need the capability
72 * @cap: The capability to check for 71 * @cap: The capability to check for
@@ -80,8 +79,8 @@ EXPORT_SYMBOL(cap_netlink_recv);
80 * cap_has_capability() returns 0 when a task has a capability, but the 79 * cap_has_capability() returns 0 when a task has a capability, but the
81 * kernel's capable() and has_capability() returns 1 for this case. 80 * kernel's capable() and has_capability() returns 1 for this case.
82 */ 81 */
83int cap_capable(struct task_struct *tsk, const struct cred *cred, 82int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
84 struct user_namespace *targ_ns, int cap, int audit) 83 int cap, int audit)
85{ 84{
86 for (;;) { 85 for (;;) {
87 /* The creator of the user namespace has all caps. */ 86 /* The creator of the user namespace has all caps. */
@@ -222,9 +221,8 @@ static inline int cap_inh_is_capped(void)
222 /* they are so limited unless the current task has the CAP_SETPCAP 221 /* they are so limited unless the current task has the CAP_SETPCAP
223 * capability 222 * capability
224 */ 223 */
225 if (cap_capable(current, current_cred(), 224 if (cap_capable(current_cred(), current_cred()->user->user_ns,
226 current_cred()->user->user_ns, CAP_SETPCAP, 225 CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)
227 SECURITY_CAP_AUDIT) == 0)
228 return 0; 226 return 0;
229 return 1; 227 return 1;
230} 228}
@@ -870,7 +868,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
870 & (new->securebits ^ arg2)) /*[1]*/ 868 & (new->securebits ^ arg2)) /*[1]*/
871 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ 869 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
872 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 870 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
873 || (cap_capable(current, current_cred(), 871 || (cap_capable(current_cred(),
874 current_cred()->user->user_ns, CAP_SETPCAP, 872 current_cred()->user->user_ns, CAP_SETPCAP,
875 SECURITY_CAP_AUDIT) != 0) /*[4]*/ 873 SECURITY_CAP_AUDIT) != 0) /*[4]*/
876 /* 874 /*
@@ -936,7 +934,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
936{ 934{
937 int cap_sys_admin = 0; 935 int cap_sys_admin = 0;
938 936
939 if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN, 937 if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
940 SECURITY_CAP_NOAUDIT) == 0) 938 SECURITY_CAP_NOAUDIT) == 0)
941 cap_sys_admin = 1; 939 cap_sys_admin = 1;
942 return __vm_enough_memory(mm, pages, cap_sys_admin); 940 return __vm_enough_memory(mm, pages, cap_sys_admin);
@@ -963,7 +961,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,
963 int ret = 0; 961 int ret = 0;
964 962
965 if (addr < dac_mmap_min_addr) { 963 if (addr < dac_mmap_min_addr) {
966 ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO, 964 ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO,
967 SECURITY_CAP_AUDIT); 965 SECURITY_CAP_AUDIT);
968 /* set PF_SUPERPRIV if it turns out we allow the low mmap */ 966 /* set PF_SUPERPRIV if it turns out we allow the low mmap */
969 if (ret == 0) 967 if (ret == 0)