diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 6 | ||||
-rw-r--r-- | security/selinux/Makefile | 2 | ||||
-rw-r--r-- | security/selinux/avc.c | 13 | ||||
-rw-r--r-- | security/selinux/exports.c | 74 | ||||
-rw-r--r-- | security/selinux/hooks.c | 11 | ||||
-rw-r--r-- | security/selinux/include/security.h | 5 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 30 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 235 |
9 files changed, 351 insertions, 29 deletions
diff --git a/security/dummy.c b/security/dummy.c index fd99429278e9..8ccccccc12ac 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -563,11 +563,6 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) | |||
563 | return 0; | 563 | return 0; |
564 | } | 564 | } |
565 | 565 | ||
566 | static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
567 | { | ||
568 | return -EOPNOTSUPP; | ||
569 | } | ||
570 | |||
571 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) | 566 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) |
572 | { | 567 | { |
573 | return 0; | 568 | return 0; |
@@ -976,7 +971,6 @@ void security_fixup_ops (struct security_operations *ops) | |||
976 | set_to_dummy_if_null(ops, task_reparent_to_init); | 971 | set_to_dummy_if_null(ops, task_reparent_to_init); |
977 | set_to_dummy_if_null(ops, task_to_inode); | 972 | set_to_dummy_if_null(ops, task_to_inode); |
978 | set_to_dummy_if_null(ops, ipc_permission); | 973 | set_to_dummy_if_null(ops, ipc_permission); |
979 | set_to_dummy_if_null(ops, ipc_getsecurity); | ||
980 | set_to_dummy_if_null(ops, msg_msg_alloc_security); | 974 | set_to_dummy_if_null(ops, msg_msg_alloc_security); |
981 | set_to_dummy_if_null(ops, msg_msg_free_security); | 975 | set_to_dummy_if_null(ops, msg_msg_free_security); |
982 | set_to_dummy_if_null(ops, msg_queue_alloc_security); | 976 | set_to_dummy_if_null(ops, msg_queue_alloc_security); |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 688c0a267b62..faf2e02e4410 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ | 5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ |
6 | 6 | ||
7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o | 7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o |
8 | 8 | ||
9 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | 9 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o |
10 | 10 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ac5d69bb3377..a300702da527 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -800,7 +800,7 @@ out: | |||
800 | int avc_ss_reset(u32 seqno) | 800 | int avc_ss_reset(u32 seqno) |
801 | { | 801 | { |
802 | struct avc_callback_node *c; | 802 | struct avc_callback_node *c; |
803 | int i, rc = 0; | 803 | int i, rc = 0, tmprc; |
804 | unsigned long flag; | 804 | unsigned long flag; |
805 | struct avc_node *node; | 805 | struct avc_node *node; |
806 | 806 | ||
@@ -813,15 +813,16 @@ int avc_ss_reset(u32 seqno) | |||
813 | 813 | ||
814 | for (c = avc_callbacks; c; c = c->next) { | 814 | for (c = avc_callbacks; c; c = c->next) { |
815 | if (c->events & AVC_CALLBACK_RESET) { | 815 | if (c->events & AVC_CALLBACK_RESET) { |
816 | rc = c->callback(AVC_CALLBACK_RESET, | 816 | tmprc = c->callback(AVC_CALLBACK_RESET, |
817 | 0, 0, 0, 0, NULL); | 817 | 0, 0, 0, 0, NULL); |
818 | if (rc) | 818 | /* save the first error encountered for the return |
819 | goto out; | 819 | value and continue processing the callbacks */ |
820 | if (!rc) | ||
821 | rc = tmprc; | ||
820 | } | 822 | } |
821 | } | 823 | } |
822 | 824 | ||
823 | avc_latest_notif_update(seqno, 0); | 825 | avc_latest_notif_update(seqno, 0); |
824 | out: | ||
825 | return rc; | 826 | return rc; |
826 | } | 827 | } |
827 | 828 | ||
diff --git a/security/selinux/exports.c b/security/selinux/exports.c new file mode 100644 index 000000000000..ae4c73eb3085 --- /dev/null +++ b/security/selinux/exports.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * SELinux services exported to the rest of the kernel. | ||
3 | * | ||
4 | * Author: James Morris <jmorris@redhat.com> | ||
5 | * | ||
6 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | ||
7 | * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | ||
8 | * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2, | ||
12 | * as published by the Free Software Foundation. | ||
13 | */ | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/selinux.h> | ||
18 | #include <linux/fs.h> | ||
19 | #include <linux/ipc.h> | ||
20 | |||
21 | #include "security.h" | ||
22 | #include "objsec.h" | ||
23 | |||
24 | void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) | ||
25 | { | ||
26 | struct task_security_struct *tsec = tsk->security; | ||
27 | if (selinux_enabled) | ||
28 | *ctxid = tsec->sid; | ||
29 | else | ||
30 | *ctxid = 0; | ||
31 | } | ||
32 | |||
33 | int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) | ||
34 | { | ||
35 | if (selinux_enabled) | ||
36 | return security_sid_to_context(ctxid, ctx, ctxlen); | ||
37 | else { | ||
38 | *ctx = NULL; | ||
39 | *ctxlen = 0; | ||
40 | } | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | ||
46 | { | ||
47 | if (selinux_enabled) { | ||
48 | struct inode_security_struct *isec = inode->i_security; | ||
49 | *sid = isec->sid; | ||
50 | return; | ||
51 | } | ||
52 | *sid = 0; | ||
53 | } | ||
54 | |||
55 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
56 | { | ||
57 | if (selinux_enabled) { | ||
58 | struct ipc_security_struct *isec = ipcp->security; | ||
59 | *sid = isec->sid; | ||
60 | return; | ||
61 | } | ||
62 | *sid = 0; | ||
63 | } | ||
64 | |||
65 | void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) | ||
66 | { | ||
67 | if (selinux_enabled) { | ||
68 | struct task_security_struct *tsec = tsk->security; | ||
69 | *sid = tsec->sid; | ||
70 | return; | ||
71 | } | ||
72 | *sid = 0; | ||
73 | } | ||
74 | |||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b61b9554bc27..d987048d3f33 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -101,6 +101,8 @@ static int __init selinux_enabled_setup(char *str) | |||
101 | return 1; | 101 | return 1; |
102 | } | 102 | } |
103 | __setup("selinux=", selinux_enabled_setup); | 103 | __setup("selinux=", selinux_enabled_setup); |
104 | #else | ||
105 | int selinux_enabled = 1; | ||
104 | #endif | 106 | #endif |
105 | 107 | ||
106 | /* Original (dummy) security module. */ | 108 | /* Original (dummy) security module. */ |
@@ -4052,13 +4054,6 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
4052 | return ipc_has_perm(ipcp, av); | 4054 | return ipc_has_perm(ipcp, av); |
4053 | } | 4055 | } |
4054 | 4056 | ||
4055 | static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
4056 | { | ||
4057 | struct ipc_security_struct *isec = ipcp->security; | ||
4058 | |||
4059 | return selinux_getsecurity(isec->sid, buffer, size); | ||
4060 | } | ||
4061 | |||
4062 | /* module stacking operations */ | 4057 | /* module stacking operations */ |
4063 | static int selinux_register_security (const char *name, struct security_operations *ops) | 4058 | static int selinux_register_security (const char *name, struct security_operations *ops) |
4064 | { | 4059 | { |
@@ -4321,7 +4316,6 @@ static struct security_operations selinux_ops = { | |||
4321 | .task_to_inode = selinux_task_to_inode, | 4316 | .task_to_inode = selinux_task_to_inode, |
4322 | 4317 | ||
4323 | .ipc_permission = selinux_ipc_permission, | 4318 | .ipc_permission = selinux_ipc_permission, |
4324 | .ipc_getsecurity = selinux_ipc_getsecurity, | ||
4325 | 4319 | ||
4326 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 4320 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
4327 | .msg_msg_free_security = selinux_msg_msg_free_security, | 4321 | .msg_msg_free_security = selinux_msg_msg_free_security, |
@@ -4543,6 +4537,7 @@ int selinux_disable(void) | |||
4543 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); | 4537 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); |
4544 | 4538 | ||
4545 | selinux_disabled = 1; | 4539 | selinux_disabled = 1; |
4540 | selinux_enabled = 0; | ||
4546 | 4541 | ||
4547 | /* Reset security_ops to the secondary module, dummy or capability. */ | 4542 | /* Reset security_ops to the secondary module, dummy or capability. */ |
4548 | security_ops = secondary_ops; | 4543 | security_ops = secondary_ops; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 5f016c98056f..063af47bb231 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -29,12 +29,7 @@ | |||
29 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 29 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
30 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB | 30 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB |
31 | 31 | ||
32 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | ||
33 | extern int selinux_enabled; | 32 | extern int selinux_enabled; |
34 | #else | ||
35 | #define selinux_enabled 1 | ||
36 | #endif | ||
37 | |||
38 | extern int selinux_mls_enabled; | 33 | extern int selinux_mls_enabled; |
39 | 34 | ||
40 | int security_load_policy(void * data, size_t len); | 35 | int security_load_policy(void * data, size_t len); |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 84047f69f9c1..7bc5b6440f70 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
10 | * | 10 | * |
11 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
@@ -385,6 +385,34 @@ out: | |||
385 | } | 385 | } |
386 | 386 | ||
387 | /* | 387 | /* |
388 | * Set the MLS fields in the security context structure | ||
389 | * `context' based on the string representation in | ||
390 | * the string `str'. This function will allocate temporary memory with the | ||
391 | * given constraints of gfp_mask. | ||
392 | */ | ||
393 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) | ||
394 | { | ||
395 | char *tmpstr, *freestr; | ||
396 | int rc; | ||
397 | |||
398 | if (!selinux_mls_enabled) | ||
399 | return -EINVAL; | ||
400 | |||
401 | /* we need freestr because mls_context_to_sid will change | ||
402 | the value of tmpstr */ | ||
403 | tmpstr = freestr = kstrdup(str, gfp_mask); | ||
404 | if (!tmpstr) { | ||
405 | rc = -ENOMEM; | ||
406 | } else { | ||
407 | rc = mls_context_to_sid(':', &tmpstr, context, | ||
408 | NULL, SECSID_NULL); | ||
409 | kfree(freestr); | ||
410 | } | ||
411 | |||
412 | return rc; | ||
413 | } | ||
414 | |||
415 | /* | ||
388 | * Copies the effective MLS range from `src' into `dst'. | 416 | * Copies the effective MLS range from `src' into `dst'. |
389 | */ | 417 | */ |
390 | static inline int mls_scopy_context(struct context *dst, | 418 | static inline int mls_scopy_context(struct context *dst, |
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 03de697c8058..fbb42f07dd7c 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
10 | * | 10 | * |
11 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #ifndef _SS_MLS_H_ | 14 | #ifndef _SS_MLS_H_ |
@@ -27,6 +27,8 @@ int mls_context_to_sid(char oldc, | |||
27 | struct sidtab *s, | 27 | struct sidtab *s, |
28 | u32 def_sid); | 28 | u32 def_sid); |
29 | 29 | ||
30 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); | ||
31 | |||
30 | int mls_convert_context(struct policydb *oldp, | 32 | int mls_convert_context(struct policydb *oldp, |
31 | struct policydb *newp, | 33 | struct policydb *newp, |
32 | struct context *context); | 34 | struct context *context); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 61492485de84..7177e98df7f3 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -7,12 +7,13 @@ | |||
7 | * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | 7 | * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> |
8 | * | 8 | * |
9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
10 | * Support for context based audit filters. | ||
10 | * | 11 | * |
11 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> | 12 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> |
12 | * | 13 | * |
13 | * Added conditional policy language extensions | 14 | * Added conditional policy language extensions |
14 | * | 15 | * |
15 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 16 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
16 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC | 17 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC |
17 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 18 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
18 | * This program is free software; you can redistribute it and/or modify | 19 | * This program is free software; you can redistribute it and/or modify |
@@ -1811,3 +1812,235 @@ out: | |||
1811 | POLICY_RDUNLOCK; | 1812 | POLICY_RDUNLOCK; |
1812 | return rc; | 1813 | return rc; |
1813 | } | 1814 | } |
1815 | |||
1816 | struct selinux_audit_rule { | ||
1817 | u32 au_seqno; | ||
1818 | struct context au_ctxt; | ||
1819 | }; | ||
1820 | |||
1821 | void selinux_audit_rule_free(struct selinux_audit_rule *rule) | ||
1822 | { | ||
1823 | if (rule) { | ||
1824 | context_destroy(&rule->au_ctxt); | ||
1825 | kfree(rule); | ||
1826 | } | ||
1827 | } | ||
1828 | |||
1829 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
1830 | struct selinux_audit_rule **rule) | ||
1831 | { | ||
1832 | struct selinux_audit_rule *tmprule; | ||
1833 | struct role_datum *roledatum; | ||
1834 | struct type_datum *typedatum; | ||
1835 | struct user_datum *userdatum; | ||
1836 | int rc = 0; | ||
1837 | |||
1838 | *rule = NULL; | ||
1839 | |||
1840 | if (!ss_initialized) | ||
1841 | return -ENOTSUPP; | ||
1842 | |||
1843 | switch (field) { | ||
1844 | case AUDIT_SE_USER: | ||
1845 | case AUDIT_SE_ROLE: | ||
1846 | case AUDIT_SE_TYPE: | ||
1847 | /* only 'equals' and 'not equals' fit user, role, and type */ | ||
1848 | if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) | ||
1849 | return -EINVAL; | ||
1850 | break; | ||
1851 | case AUDIT_SE_SEN: | ||
1852 | case AUDIT_SE_CLR: | ||
1853 | /* we do not allow a range, indicated by the presense of '-' */ | ||
1854 | if (strchr(rulestr, '-')) | ||
1855 | return -EINVAL; | ||
1856 | break; | ||
1857 | default: | ||
1858 | /* only the above fields are valid */ | ||
1859 | return -EINVAL; | ||
1860 | } | ||
1861 | |||
1862 | tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); | ||
1863 | if (!tmprule) | ||
1864 | return -ENOMEM; | ||
1865 | |||
1866 | context_init(&tmprule->au_ctxt); | ||
1867 | |||
1868 | POLICY_RDLOCK; | ||
1869 | |||
1870 | tmprule->au_seqno = latest_granting; | ||
1871 | |||
1872 | switch (field) { | ||
1873 | case AUDIT_SE_USER: | ||
1874 | userdatum = hashtab_search(policydb.p_users.table, rulestr); | ||
1875 | if (!userdatum) | ||
1876 | rc = -EINVAL; | ||
1877 | else | ||
1878 | tmprule->au_ctxt.user = userdatum->value; | ||
1879 | break; | ||
1880 | case AUDIT_SE_ROLE: | ||
1881 | roledatum = hashtab_search(policydb.p_roles.table, rulestr); | ||
1882 | if (!roledatum) | ||
1883 | rc = -EINVAL; | ||
1884 | else | ||
1885 | tmprule->au_ctxt.role = roledatum->value; | ||
1886 | break; | ||
1887 | case AUDIT_SE_TYPE: | ||
1888 | typedatum = hashtab_search(policydb.p_types.table, rulestr); | ||
1889 | if (!typedatum) | ||
1890 | rc = -EINVAL; | ||
1891 | else | ||
1892 | tmprule->au_ctxt.type = typedatum->value; | ||
1893 | break; | ||
1894 | case AUDIT_SE_SEN: | ||
1895 | case AUDIT_SE_CLR: | ||
1896 | rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); | ||
1897 | break; | ||
1898 | } | ||
1899 | |||
1900 | POLICY_RDUNLOCK; | ||
1901 | |||
1902 | if (rc) { | ||
1903 | selinux_audit_rule_free(tmprule); | ||
1904 | tmprule = NULL; | ||
1905 | } | ||
1906 | |||
1907 | *rule = tmprule; | ||
1908 | |||
1909 | return rc; | ||
1910 | } | ||
1911 | |||
1912 | int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, | ||
1913 | struct selinux_audit_rule *rule, | ||
1914 | struct audit_context *actx) | ||
1915 | { | ||
1916 | struct context *ctxt; | ||
1917 | struct mls_level *level; | ||
1918 | int match = 0; | ||
1919 | |||
1920 | if (!rule) { | ||
1921 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
1922 | "selinux_audit_rule_match: missing rule\n"); | ||
1923 | return -ENOENT; | ||
1924 | } | ||
1925 | |||
1926 | POLICY_RDLOCK; | ||
1927 | |||
1928 | if (rule->au_seqno < latest_granting) { | ||
1929 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
1930 | "selinux_audit_rule_match: stale rule\n"); | ||
1931 | match = -ESTALE; | ||
1932 | goto out; | ||
1933 | } | ||
1934 | |||
1935 | ctxt = sidtab_search(&sidtab, ctxid); | ||
1936 | if (!ctxt) { | ||
1937 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
1938 | "selinux_audit_rule_match: unrecognized SID %d\n", | ||
1939 | ctxid); | ||
1940 | match = -ENOENT; | ||
1941 | goto out; | ||
1942 | } | ||
1943 | |||
1944 | /* a field/op pair that is not caught here will simply fall through | ||
1945 | without a match */ | ||
1946 | switch (field) { | ||
1947 | case AUDIT_SE_USER: | ||
1948 | switch (op) { | ||
1949 | case AUDIT_EQUAL: | ||
1950 | match = (ctxt->user == rule->au_ctxt.user); | ||
1951 | break; | ||
1952 | case AUDIT_NOT_EQUAL: | ||
1953 | match = (ctxt->user != rule->au_ctxt.user); | ||
1954 | break; | ||
1955 | } | ||
1956 | break; | ||
1957 | case AUDIT_SE_ROLE: | ||
1958 | switch (op) { | ||
1959 | case AUDIT_EQUAL: | ||
1960 | match = (ctxt->role == rule->au_ctxt.role); | ||
1961 | break; | ||
1962 | case AUDIT_NOT_EQUAL: | ||
1963 | match = (ctxt->role != rule->au_ctxt.role); | ||
1964 | break; | ||
1965 | } | ||
1966 | break; | ||
1967 | case AUDIT_SE_TYPE: | ||
1968 | switch (op) { | ||
1969 | case AUDIT_EQUAL: | ||
1970 | match = (ctxt->type == rule->au_ctxt.type); | ||
1971 | break; | ||
1972 | case AUDIT_NOT_EQUAL: | ||
1973 | match = (ctxt->type != rule->au_ctxt.type); | ||
1974 | break; | ||
1975 | } | ||
1976 | break; | ||
1977 | case AUDIT_SE_SEN: | ||
1978 | case AUDIT_SE_CLR: | ||
1979 | level = (op == AUDIT_SE_SEN ? | ||
1980 | &ctxt->range.level[0] : &ctxt->range.level[1]); | ||
1981 | switch (op) { | ||
1982 | case AUDIT_EQUAL: | ||
1983 | match = mls_level_eq(&rule->au_ctxt.range.level[0], | ||
1984 | level); | ||
1985 | break; | ||
1986 | case AUDIT_NOT_EQUAL: | ||
1987 | match = !mls_level_eq(&rule->au_ctxt.range.level[0], | ||
1988 | level); | ||
1989 | break; | ||
1990 | case AUDIT_LESS_THAN: | ||
1991 | match = (mls_level_dom(&rule->au_ctxt.range.level[0], | ||
1992 | level) && | ||
1993 | !mls_level_eq(&rule->au_ctxt.range.level[0], | ||
1994 | level)); | ||
1995 | break; | ||
1996 | case AUDIT_LESS_THAN_OR_EQUAL: | ||
1997 | match = mls_level_dom(&rule->au_ctxt.range.level[0], | ||
1998 | level); | ||
1999 | break; | ||
2000 | case AUDIT_GREATER_THAN: | ||
2001 | match = (mls_level_dom(level, | ||
2002 | &rule->au_ctxt.range.level[0]) && | ||
2003 | !mls_level_eq(level, | ||
2004 | &rule->au_ctxt.range.level[0])); | ||
2005 | break; | ||
2006 | case AUDIT_GREATER_THAN_OR_EQUAL: | ||
2007 | match = mls_level_dom(level, | ||
2008 | &rule->au_ctxt.range.level[0]); | ||
2009 | break; | ||
2010 | } | ||
2011 | } | ||
2012 | |||
2013 | out: | ||
2014 | POLICY_RDUNLOCK; | ||
2015 | return match; | ||
2016 | } | ||
2017 | |||
2018 | static int (*aurule_callback)(void) = NULL; | ||
2019 | |||
2020 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, | ||
2021 | u16 class, u32 perms, u32 *retained) | ||
2022 | { | ||
2023 | int err = 0; | ||
2024 | |||
2025 | if (event == AVC_CALLBACK_RESET && aurule_callback) | ||
2026 | err = aurule_callback(); | ||
2027 | return err; | ||
2028 | } | ||
2029 | |||
2030 | static int __init aurule_init(void) | ||
2031 | { | ||
2032 | int err; | ||
2033 | |||
2034 | err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, | ||
2035 | SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); | ||
2036 | if (err) | ||
2037 | panic("avc_add_callback() failed, error %d\n", err); | ||
2038 | |||
2039 | return err; | ||
2040 | } | ||
2041 | __initcall(aurule_init); | ||
2042 | |||
2043 | void selinux_audit_set_callback(int (*callback)(void)) | ||
2044 | { | ||
2045 | aurule_callback = callback; | ||
2046 | } | ||