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>
This commit is contained in:
Eric Paris 2008-11-11 22:02:50 +11:00 committed by James Morris
parent 637d32dc72
commit 06112163f5
5 changed files with 39 additions and 15 deletions

View file

@ -49,7 +49,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
* returns 0 when a task has a capability, but the kernel's capable()
* returns 1 for this case.
*/
int cap_capable (struct task_struct *tsk, int cap)
int cap_capable(struct task_struct *tsk, int cap, int audit)
{
/* Derived from include/linux/sched.h:capable. */
if (cap_raised(tsk->cap_effective, cap))
@ -112,7 +112,7 @@ static inline int cap_inh_is_capped(void)
* to the old permitted set. That is, if the current task
* does *not* possess the CAP_SETPCAP capability.
*/
return (cap_capable(current, CAP_SETPCAP) != 0);
return (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0);
}
static inline int cap_limit_ptraced_target(void) { return 1; }
@ -677,7 +677,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
|| ((current->securebits & SECURE_ALL_LOCKS
& ~arg2)) /*[2]*/
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
|| (cap_capable(current, CAP_SETPCAP) != 0)) { /*[4]*/
|| (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0)) { /*[4]*/
/*
* [1] no changing of bits that are locked
* [2] no unlocking of locks
@ -742,7 +742,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
{
int cap_sys_admin = 0;
if (cap_capable(current, CAP_SYS_ADMIN) == 0)
if (cap_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0)
cap_sys_admin = 1;
return __vm_enough_memory(mm, pages, cap_sys_admin);
}