diff options
-rw-r--r-- | include/linux/capability.h | 3 | ||||
-rw-r--r-- | include/linux/security.h | 16 | ||||
-rw-r--r-- | security/commoncap.c | 8 | ||||
-rw-r--r-- | security/security.c | 7 | ||||
-rw-r--r-- | security/selinux/hooks.c | 20 |
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 | ||
522 | kernel_cap_t cap_set_effective(const kernel_cap_t pE_new); | 522 | kernel_cap_t cap_set_effective(const kernel_cap_t pE_new); |
523 | 523 | ||
524 | extern int security_capable(struct task_struct *t, int cap); | ||
525 | extern 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 | ||
536 | extern int capable(int cap); | 539 | extern 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 | |||
40 | struct ctl_table; | 44 | struct ctl_table; |
41 | struct audit_krule; | 45 | struct 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 | */ |
47 | extern int cap_capable(struct task_struct *tsk, int cap); | 51 | extern int cap_capable(struct task_struct *tsk, int cap, int audit); |
48 | extern int cap_settime(struct timespec *ts, struct timezone *tz); | 52 | extern int cap_settime(struct timespec *ts, struct timezone *tz); |
49 | extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); | 53 | extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); |
50 | extern int cap_ptrace_traceme(struct task_struct *parent); | 54 | extern 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); |
1579 | int security_capable(struct task_struct *tsk, int cap); | 1583 | int security_capable(struct task_struct *tsk, int cap); |
1584 | int security_capable_noaudit(struct task_struct *tsk, int cap); | ||
1580 | int security_acct(struct file *file); | 1585 | int security_acct(struct file *file); |
1581 | int security_sysctl(struct ctl_table *table, int op); | 1586 | int security_sysctl(struct ctl_table *table, int op); |
1582 | int security_quotactl(int cmds, int type, int id, struct super_block *sb); | 1587 | int 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 | ||
1783 | static inline int security_capable(struct task_struct *tsk, int cap) | 1788 | static 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 | |||
1793 | static 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 | ||
1788 | static inline int security_acct(struct file *file) | 1798 | static 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 | */ |
52 | int cap_capable (struct task_struct *tsk, int cap) | 52 | int 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 | ||
118 | static inline int cap_limit_ptraced_target(void) { return 1; } | 118 | 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, | |||
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 | ||
164 | int security_capable(struct task_struct *tsk, int cap) | 164 | int 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 | |||
169 | int security_capable_noaudit(struct task_struct *tsk, int cap) | ||
170 | { | ||
171 | return security_ops->capable(tsk, cap, SECURITY_CAP_NOAUDIT); | ||
167 | } | 172 | } |
168 | 173 | ||
169 | int security_acct(struct file *file) | 174 | int 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. */ |
1367 | static int task_has_capability(struct task_struct *tsk, | 1367 | static 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 | ||
1805 | static int selinux_capable(struct task_struct *tsk, int cap) | 1811 | static 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 | ||
1816 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | 1822 | 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) | |||
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, |