From 6a9de49115d5ff9871d953af1a5c8249e1585731 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 3 Jan 2012 12:25:14 -0500 Subject: 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 --- security/commoncap.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'security/commoncap.c') 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); /** * cap_capable - Determine whether a task has a particular effective capability - * @tsk: The task to query * @cred: The credentials to use * @ns: The user namespace in which we need the capability * @cap: The capability to check for @@ -80,8 +79,8 @@ EXPORT_SYMBOL(cap_netlink_recv); * cap_has_capability() returns 0 when a task has a capability, but the * kernel's capable() and has_capability() returns 1 for this case. */ -int cap_capable(struct task_struct *tsk, const struct cred *cred, - struct user_namespace *targ_ns, int cap, int audit) +int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, + int cap, int audit) { for (;;) { /* The creator of the user namespace has all caps. */ @@ -222,9 +221,8 @@ static inline int cap_inh_is_capped(void) /* they are so limited unless the current task has the CAP_SETPCAP * capability */ - if (cap_capable(current, current_cred(), - current_cred()->user->user_ns, CAP_SETPCAP, - SECURITY_CAP_AUDIT) == 0) + if (cap_capable(current_cred(), current_cred()->user->user_ns, + CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) return 0; return 1; } @@ -870,7 +868,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, & (new->securebits ^ arg2)) /*[1]*/ || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ - || (cap_capable(current, current_cred(), + || (cap_capable(current_cred(), current_cred()->user->user_ns, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0) /*[4]*/ /* @@ -936,7 +934,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) { int cap_sys_admin = 0; - if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN, + if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0) cap_sys_admin = 1; return __vm_enough_memory(mm, pages, cap_sys_admin); @@ -963,7 +961,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot, int ret = 0; if (addr < dac_mmap_min_addr) { - ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO, + ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO, SECURITY_CAP_AUDIT); /* set PF_SUPERPRIV if it turns out we allow the low mmap */ if (ret == 0) -- cgit v1.2.2 From fd778461524849afd035679030ae8e8873c72b81 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Tue, 3 Jan 2012 12:25:16 -0500 Subject: security: remove the security_netlink_recv hook as it is equivalent to capable() Once upon a time netlink was not sync and we had to get the effective capabilities from the skb that was being received. Today we instead get the capabilities from the current task. This has rendered the entire purpose of the hook moot as it is now functionally equivalent to the capable() call. Signed-off-by: Eric Paris --- security/commoncap.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'security/commoncap.c') diff --git a/security/commoncap.c b/security/commoncap.c index 89f02ff66af9..7817a763444d 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -56,14 +56,6 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) return 0; } -int cap_netlink_recv(struct sk_buff *skb, int cap) -{ - if (!cap_raised(current_cap(), cap)) - return -EPERM; - return 0; -} -EXPORT_SYMBOL(cap_netlink_recv); - /** * cap_capable - Determine whether a task has a particular effective capability * @cred: The credentials to use -- cgit v1.2.2