selinux: support 64-bit capabilities
Fix SELinux to handle 64-bit capabilities correctly, and to catch
future extensions of capabilities beyond 64 bits to ensure that SELinux
is properly updated.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e5ed075..44f16d9 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1272,12 +1272,18 @@
SECCLASS_PROCESS, perms, NULL);
}
+#if CAP_LAST_CAP > 63
+#error Fix SELinux to handle capabilities > 63.
+#endif
+
/* Check whether a task is allowed to use a capability. */
static int task_has_capability(struct task_struct *tsk,
int cap)
{
struct task_security_struct *tsec;
struct avc_audit_data ad;
+ u16 sclass;
+ u32 av = CAP_TO_MASK(cap);
tsec = tsk->security;
@@ -1285,8 +1291,19 @@
ad.tsk = tsk;
ad.u.cap = cap;
- return avc_has_perm(tsec->sid, tsec->sid,
- SECCLASS_CAPABILITY, CAP_TO_MASK(cap), &ad);
+ switch (CAP_TO_INDEX(cap)) {
+ case 0:
+ sclass = SECCLASS_CAPABILITY;
+ break;
+ case 1:
+ sclass = SECCLASS_CAPABILITY2;
+ break;
+ default:
+ printk(KERN_ERR
+ "SELinux: out of range capability %d\n", cap);
+ BUG();
+ }
+ return avc_has_perm(tsec->sid, tsec->sid, sclass, av, &ad);
}
/* Check whether a task is allowed to use a system operation. */