aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2008-11-11 06:02:50 -0500
committerJames Morris <jmorris@namei.org>2008-11-11 06:02:50 -0500
commit06112163f5fd9e491a7f810443d81efa9d88e247 (patch)
tree48039f7488abbec36c0982a57405b57d47311dd6
parent637d32dc720897616e8a1a4f9e9609e29d431800 (diff)
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>
-rw-r--r--include/linux/capability.h3
-rw-r--r--include/linux/security.h16
-rw-r--r--security/commoncap.c8
-rw-r--r--security/security.c7
-rw-r--r--security/selinux/hooks.c20
5 files changed, 39 insertions, 15 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 0f1950181102..b313ba1dd5d1 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -521,6 +521,8 @@ extern const kernel_cap_t __cap_init_eff_set;
521 521
522kernel_cap_t cap_set_effective(const kernel_cap_t pE_new); 522kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
523 523
524extern int security_capable(struct task_struct *t, int cap);
525extern int security_capable_noaudit(struct task_struct *t, int cap);
524/** 526/**
525 * has_capability - Determine if a task has a superior capability available 527 * has_capability - Determine if a task has a superior capability available
526 * @t: The task in question 528 * @t: The task in question
@@ -532,6 +534,7 @@ kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
532 * Note that this does not set PF_SUPERPRIV on the task. 534 * Note that this does not set PF_SUPERPRIV on the task.
533 */ 535 */
534#define has_capability(t, cap) (security_capable((t), (cap)) == 0) 536#define has_capability(t, cap) (security_capable((t), (cap)) == 0)
537#define has_capability_noaudit(t, cap) (security_capable_noaudit((t), (cap)) == 0)
535 538
536extern int capable(int cap); 539extern int capable(int cap);
537 540
diff --git a/include/linux/security.h b/include/linux/security.h
index c13f1cec9abb..5fe28a671cd3 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -37,6 +37,10 @@
37/* Maximum number of letters for an LSM name string */ 37/* Maximum number of letters for an LSM name string */
38#define SECURITY_NAME_MAX 10 38#define SECURITY_NAME_MAX 10
39 39
40/* If capable should audit the security request */
41#define SECURITY_CAP_NOAUDIT 0
42#define SECURITY_CAP_AUDIT 1
43
40struct ctl_table; 44struct ctl_table;
41struct audit_krule; 45struct audit_krule;
42 46
@@ -44,7 +48,7 @@ struct audit_krule;
44 * These functions are in security/capability.c and are used 48 * These functions are in security/capability.c and are used
45 * as the default capabilities functions 49 * as the default capabilities functions
46 */ 50 */
47extern int cap_capable(struct task_struct *tsk, int cap); 51extern int cap_capable(struct task_struct *tsk, int cap, int audit);
48extern int cap_settime(struct timespec *ts, struct timezone *tz); 52extern int cap_settime(struct timespec *ts, struct timezone *tz);
49extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); 53extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode);
50extern int cap_ptrace_traceme(struct task_struct *parent); 54extern int cap_ptrace_traceme(struct task_struct *parent);
@@ -1307,7 +1311,7 @@ struct security_operations {
1307 kernel_cap_t *effective, 1311 kernel_cap_t *effective,
1308 kernel_cap_t *inheritable, 1312 kernel_cap_t *inheritable,
1309 kernel_cap_t *permitted); 1313 kernel_cap_t *permitted);
1310 int (*capable) (struct task_struct *tsk, int cap); 1314 int (*capable) (struct task_struct *tsk, int cap, int audit);
1311 int (*acct) (struct file *file); 1315 int (*acct) (struct file *file);
1312 int (*sysctl) (struct ctl_table *table, int op); 1316 int (*sysctl) (struct ctl_table *table, int op);
1313 int (*quotactl) (int cmds, int type, int id, struct super_block *sb); 1317 int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
@@ -1577,6 +1581,7 @@ void security_capset_set(struct task_struct *target,
1577 kernel_cap_t *inheritable, 1581 kernel_cap_t *inheritable,
1578 kernel_cap_t *permitted); 1582 kernel_cap_t *permitted);
1579int security_capable(struct task_struct *tsk, int cap); 1583int security_capable(struct task_struct *tsk, int cap);
1584int security_capable_noaudit(struct task_struct *tsk, int cap);
1580int security_acct(struct file *file); 1585int security_acct(struct file *file);
1581int security_sysctl(struct ctl_table *table, int op); 1586int security_sysctl(struct ctl_table *table, int op);
1582int security_quotactl(int cmds, int type, int id, struct super_block *sb); 1587int security_quotactl(int cmds, int type, int id, struct super_block *sb);
@@ -1782,7 +1787,12 @@ static inline void security_capset_set(struct task_struct *target,
1782 1787
1783static inline int security_capable(struct task_struct *tsk, int cap) 1788static inline int security_capable(struct task_struct *tsk, int cap)
1784{ 1789{
1785 return cap_capable(tsk, cap); 1790 return cap_capable(tsk, cap, SECURITY_CAP_AUDIT);
1791}
1792
1793static inline int security_capable_noaudit(struct task_struct *tsk, int cap)
1794{
1795 return cap_capable(tsk, cap, SECURITY_CAP_NOAUDIT);
1786} 1796}
1787 1797
1788static inline int security_acct(struct file *file) 1798static inline int security_acct(struct file *file)
diff --git a/security/commoncap.c b/security/commoncap.c
index d45393380997..dc06c0086b55 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
49 * returns 0 when a task has a capability, but the kernel's capable() 49 * returns 0 when a task has a capability, but the kernel's capable()
50 * returns 1 for this case. 50 * returns 1 for this case.
51 */ 51 */
52int cap_capable (struct task_struct *tsk, int cap) 52int cap_capable(struct task_struct *tsk, int cap, int audit)
53{ 53{
54 /* Derived from include/linux/sched.h:capable. */ 54 /* Derived from include/linux/sched.h:capable. */
55 if (cap_raised(tsk->cap_effective, cap)) 55 if (cap_raised(tsk->cap_effective, cap))
@@ -112,7 +112,7 @@ static inline int cap_inh_is_capped(void)
112 * to the old permitted set. That is, if the current task 112 * to the old permitted set. That is, if the current task
113 * does *not* possess the CAP_SETPCAP capability. 113 * does *not* possess the CAP_SETPCAP capability.
114 */ 114 */
115 return (cap_capable(current, CAP_SETPCAP) != 0); 115 return (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0);
116} 116}
117 117
118static inline int cap_limit_ptraced_target(void) { return 1; } 118static 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,
677 || ((current->securebits & SECURE_ALL_LOCKS 677 || ((current->securebits & SECURE_ALL_LOCKS
678 & ~arg2)) /*[2]*/ 678 & ~arg2)) /*[2]*/
679 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 679 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
680 || (cap_capable(current, CAP_SETPCAP) != 0)) { /*[4]*/ 680 || (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0)) { /*[4]*/
681 /* 681 /*
682 * [1] no changing of bits that are locked 682 * [1] no changing of bits that are locked
683 * [2] no unlocking of locks 683 * [2] no unlocking of locks
@@ -742,7 +742,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
742{ 742{
743 int cap_sys_admin = 0; 743 int cap_sys_admin = 0;
744 744
745 if (cap_capable(current, CAP_SYS_ADMIN) == 0) 745 if (cap_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0)
746 cap_sys_admin = 1; 746 cap_sys_admin = 1;
747 return __vm_enough_memory(mm, pages, cap_sys_admin); 747 return __vm_enough_memory(mm, pages, cap_sys_admin);
748} 748}
diff --git a/security/security.c b/security/security.c
index c0acfa7177e5..346f21e0ec2c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -163,7 +163,12 @@ void security_capset_set(struct task_struct *target,
163 163
164int security_capable(struct task_struct *tsk, int cap) 164int security_capable(struct task_struct *tsk, int cap)
165{ 165{
166 return security_ops->capable(tsk, cap); 166 return security_ops->capable(tsk, cap, SECURITY_CAP_AUDIT);
167}
168
169int security_capable_noaudit(struct task_struct *tsk, int cap)
170{
171 return security_ops->capable(tsk, cap, SECURITY_CAP_NOAUDIT);
167} 172}
168 173
169int security_acct(struct file *file) 174int security_acct(struct file *file)
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,
1365 1365
1366/* Check whether a task is allowed to use a capability. */ 1366/* Check whether a task is allowed to use a capability. */
1367static int task_has_capability(struct task_struct *tsk, 1367static int task_has_capability(struct task_struct *tsk,
1368 int cap) 1368 int cap, int audit)
1369{ 1369{
1370 struct task_security_struct *tsec; 1370 struct task_security_struct *tsec;
1371 struct avc_audit_data ad; 1371 struct avc_audit_data ad;
1372 struct av_decision avd;
1372 u16 sclass; 1373 u16 sclass;
1373 u32 av = CAP_TO_MASK(cap); 1374 u32 av = CAP_TO_MASK(cap);
1375 int rc;
1374 1376
1375 tsec = tsk->security; 1377 tsec = tsk->security;
1376 1378
@@ -1390,7 +1392,11 @@ static int task_has_capability(struct task_struct *tsk,
1390 "SELinux: out of range capability %d\n", cap); 1392 "SELinux: out of range capability %d\n", cap);
1391 BUG(); 1393 BUG();
1392 } 1394 }
1393 return avc_has_perm(tsec->sid, tsec->sid, sclass, av, &ad); 1395
1396 rc = avc_has_perm_noaudit(tsec->sid, tsec->sid, sclass, av, 0, &avd);
1397 if (audit == SECURITY_CAP_AUDIT)
1398 avc_audit(tsec->sid, tsec->sid, sclass, av, &avd, rc, &ad);
1399 return rc;
1394} 1400}
1395 1401
1396/* Check whether a task is allowed to use a system operation. */ 1402/* 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
1802 secondary_ops->capset_set(target, effective, inheritable, permitted); 1808 secondary_ops->capset_set(target, effective, inheritable, permitted);
1803} 1809}
1804 1810
1805static int selinux_capable(struct task_struct *tsk, int cap) 1811static int selinux_capable(struct task_struct *tsk, int cap, int audit)
1806{ 1812{
1807 int rc; 1813 int rc;
1808 1814
1809 rc = secondary_ops->capable(tsk, cap); 1815 rc = secondary_ops->capable(tsk, cap, audit);
1810 if (rc) 1816 if (rc)
1811 return rc; 1817 return rc;
1812 1818
1813 return task_has_capability(tsk, cap); 1819 return task_has_capability(tsk, cap, audit);
1814} 1820}
1815 1821
1816static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) 1822static 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)
1975 int rc, cap_sys_admin = 0; 1981 int rc, cap_sys_admin = 0;
1976 struct task_security_struct *tsec = current->security; 1982 struct task_security_struct *tsec = current->security;
1977 1983
1978 rc = secondary_ops->capable(current, CAP_SYS_ADMIN); 1984 rc = secondary_ops->capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT);
1979 if (rc == 0) 1985 if (rc == 0)
1980 rc = avc_has_perm_noaudit(tsec->sid, tsec->sid, 1986 rc = avc_has_perm_noaudit(tsec->sid, tsec->sid,
1981 SECCLASS_CAPABILITY, 1987 SECCLASS_CAPABILITY,
@@ -2829,7 +2835,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
2829 * and lack of permission just means that we fall back to the 2835 * and lack of permission just means that we fall back to the
2830 * in-core context value, not a denial. 2836 * in-core context value, not a denial.
2831 */ 2837 */
2832 error = secondary_ops->capable(current, CAP_MAC_ADMIN); 2838 error = secondary_ops->capable(current, CAP_MAC_ADMIN, SECURITY_CAP_NOAUDIT);
2833 if (!error) 2839 if (!error)
2834 error = avc_has_perm_noaudit(tsec->sid, tsec->sid, 2840 error = avc_has_perm_noaudit(tsec->sid, tsec->sid,
2835 SECCLASS_CAPABILITY2, 2841 SECCLASS_CAPABILITY2,