summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2008-11-11 12:02:50 +0100
committerJames Morris <jmorris@namei.org>2008-11-11 12:02:50 +0100
commit06112163f5fd9e491a7f810443d81efa9d88e247 (patch)
tree48039f7488abbec36c0982a57405b57d47311dd6 /security/selinux
parentCapabilities: BUG when an invalid capability is requested (diff)
downloadlinux-06112163f5fd9e491a7f810443d81efa9d88e247.tar.xz
linux-06112163f5fd9e491a7f810443d81efa9d88e247.zip
Add a new capable interface that will be used by systems that use audit to
make an A or B type decision instead of a security decision. Currently this is the case at least for filesystems when deciding if a process can use the reserved 'root' blocks and for the case of things like the oom algorithm determining if processes are root processes and should be less likely to be killed. These types of security system requests should not be audited or logged since they are not really security decisions. It would be possible to solve this problem like the vm_enough_memory security check did by creating a new LSM interface and moving all of the policy into that interface but proves the needlessly bloat the LSM and provide complex indirection. This merely allows those decisions to be made where they belong and to not flood logs or printk with denials for thing that are not security decisions. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7fd4de46b2a9..88a3ee33068a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1365,12 +1365,14 @@ static int task_has_perm(struct task_struct *tsk1,
/* Check whether a task is allowed to use a capability. */
static int task_has_capability(struct task_struct *tsk,
- int cap)
+ int cap, int audit)
{
struct task_security_struct *tsec;
struct avc_audit_data ad;
+ struct av_decision avd;
u16 sclass;
u32 av = CAP_TO_MASK(cap);
+ int rc;
tsec = tsk->security;
@@ -1390,7 +1392,11 @@ static int task_has_capability(struct task_struct *tsk,
"SELinux: out of range capability %d\n", cap);
BUG();
}
- return avc_has_perm(tsec->sid, tsec->sid, sclass, av, &ad);
+
+ rc = avc_has_perm_noaudit(tsec->sid, tsec->sid, sclass, av, 0, &avd);
+ if (audit == SECURITY_CAP_AUDIT)
+ avc_audit(tsec->sid, tsec->sid, sclass, av, &avd, rc, &ad);
+ return rc;
}
/* Check whether a task is allowed to use a system operation. */
@@ -1802,15 +1808,15 @@ static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effecti
secondary_ops->capset_set(target, effective, inheritable, permitted);
}
-static int selinux_capable(struct task_struct *tsk, int cap)
+static int selinux_capable(struct task_struct *tsk, int cap, int audit)
{
int rc;
- rc = secondary_ops->capable(tsk, cap);
+ rc = secondary_ops->capable(tsk, cap, audit);
if (rc)
return rc;
- return task_has_capability(tsk, cap);
+ return task_has_capability(tsk, cap, audit);
}
static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
@@ -1975,7 +1981,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
int rc, cap_sys_admin = 0;
struct task_security_struct *tsec = current->security;
- rc = secondary_ops->capable(current, CAP_SYS_ADMIN);
+ rc = secondary_ops->capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT);
if (rc == 0)
rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
SECCLASS_CAPABILITY,
@@ -2829,7 +2835,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
* and lack of permission just means that we fall back to the
* in-core context value, not a denial.
*/
- error = secondary_ops->capable(current, CAP_MAC_ADMIN);
+ error = secondary_ops->capable(current, CAP_MAC_ADMIN, SECURITY_CAP_NOAUDIT);
if (!error)
error = avc_has_perm_noaudit(tsec->sid, tsec->sid,
SECCLASS_CAPABILITY2,