aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c6
-rw-r--r--security/selinux/Makefile2
-rw-r--r--security/selinux/avc.c13
-rw-r--r--security/selinux/exports.c74
-rw-r--r--security/selinux/hooks.c19
-rw-r--r--security/selinux/include/security.h5
-rw-r--r--security/selinux/ss/mls.c32
-rw-r--r--security/selinux/ss/mls.h4
-rw-r--r--security/selinux/ss/services.c239
9 files changed, 361 insertions, 33 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
566static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
567{
568 return -EOPNOTSUPP;
569}
570
571static int dummy_msg_msg_alloc_security (struct msg_msg *msg) 566static 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
5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ 5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
6 6
7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o 7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o
8 8
9selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o 9selinux-$(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:
800int avc_ss_reset(u32 seqno) 800int 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);
824out:
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
24void 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
33int 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
45void 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
55void 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
65void 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..90b4cdc0c948 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
105int selinux_enabled = 1;
104#endif 106#endif
105 107
106/* Original (dummy) security module. */ 108/* Original (dummy) security module. */
@@ -3229,7 +3231,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3229 goto out; 3231 goto out;
3230 3232
3231 /* Handle mapped IPv4 packets arriving via IPv6 sockets */ 3233 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3232 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) 3234 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
3233 family = PF_INET; 3235 family = PF_INET;
3234 3236
3235 read_lock_bh(&sk->sk_callback_lock); 3237 read_lock_bh(&sk->sk_callback_lock);
@@ -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
4055static 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 */
4063static int selinux_register_security (const char *name, struct security_operations *ops) 4058static 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,
@@ -4428,6 +4422,7 @@ void selinux_complete_init(void)
4428 4422
4429 /* Set up any superblocks initialized prior to the policy load. */ 4423 /* Set up any superblocks initialized prior to the policy load. */
4430 printk(KERN_INFO "SELinux: Setting up existing superblocks.\n"); 4424 printk(KERN_INFO "SELinux: Setting up existing superblocks.\n");
4425 spin_lock(&sb_lock);
4431 spin_lock(&sb_security_lock); 4426 spin_lock(&sb_security_lock);
4432next_sb: 4427next_sb:
4433 if (!list_empty(&superblock_security_head)) { 4428 if (!list_empty(&superblock_security_head)) {
@@ -4436,19 +4431,20 @@ next_sb:
4436 struct superblock_security_struct, 4431 struct superblock_security_struct,
4437 list); 4432 list);
4438 struct super_block *sb = sbsec->sb; 4433 struct super_block *sb = sbsec->sb;
4439 spin_lock(&sb_lock);
4440 sb->s_count++; 4434 sb->s_count++;
4441 spin_unlock(&sb_lock);
4442 spin_unlock(&sb_security_lock); 4435 spin_unlock(&sb_security_lock);
4436 spin_unlock(&sb_lock);
4443 down_read(&sb->s_umount); 4437 down_read(&sb->s_umount);
4444 if (sb->s_root) 4438 if (sb->s_root)
4445 superblock_doinit(sb, NULL); 4439 superblock_doinit(sb, NULL);
4446 drop_super(sb); 4440 drop_super(sb);
4441 spin_lock(&sb_lock);
4447 spin_lock(&sb_security_lock); 4442 spin_lock(&sb_security_lock);
4448 list_del_init(&sbsec->list); 4443 list_del_init(&sbsec->list);
4449 goto next_sb; 4444 goto next_sb;
4450 } 4445 }
4451 spin_unlock(&sb_security_lock); 4446 spin_unlock(&sb_security_lock);
4447 spin_unlock(&sb_lock);
4452} 4448}
4453 4449
4454/* SELinux requires early initialization in order to label 4450/* SELinux requires early initialization in order to label
@@ -4543,6 +4539,7 @@ int selinux_disable(void)
4543 printk(KERN_INFO "SELinux: Disabled at runtime.\n"); 4539 printk(KERN_INFO "SELinux: Disabled at runtime.\n");
4544 4540
4545 selinux_disabled = 1; 4541 selinux_disabled = 1;
4542 selinux_enabled = 0;
4546 4543
4547 /* Reset security_ops to the secondary module, dummy or capability. */ 4544 /* Reset security_ops to the secondary module, dummy or capability. */
4548 security_ops = secondary_ops; 4545 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
33extern int selinux_enabled; 32extern int selinux_enabled;
34#else
35#define selinux_enabled 1
36#endif
37
38extern int selinux_mls_enabled; 33extern int selinux_mls_enabled;
39 34
40int security_load_policy(void * data, size_t len); 35int security_load_policy(void * data, size_t len);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 640d0bfdbc68..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>
@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc,
264 264
265 if (!selinux_mls_enabled) { 265 if (!selinux_mls_enabled) {
266 if (def_sid != SECSID_NULL && oldc) 266 if (def_sid != SECSID_NULL && oldc)
267 *scontext += strlen(*scontext); 267 *scontext += strlen(*scontext)+1;
268 return 0; 268 return 0;
269 } 269 }
270 270
@@ -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 */
393int 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 */
390static inline int mls_scopy_context(struct context *dst, 418static 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
30int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
31
30int mls_convert_context(struct policydb *oldp, 32int 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..c284dbb8b8c0 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
@@ -593,6 +594,10 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
593 594
594 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 595 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
595 scontextp = kmalloc(*scontext_len,GFP_ATOMIC); 596 scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
597 if (!scontextp) {
598 rc = -ENOMEM;
599 goto out;
600 }
596 strcpy(scontextp, initial_sid_to_string[sid]); 601 strcpy(scontextp, initial_sid_to_string[sid]);
597 *scontext = scontextp; 602 *scontext = scontextp;
598 goto out; 603 goto out;
@@ -1811,3 +1816,235 @@ out:
1811 POLICY_RDUNLOCK; 1816 POLICY_RDUNLOCK;
1812 return rc; 1817 return rc;
1813} 1818}
1819
1820struct selinux_audit_rule {
1821 u32 au_seqno;
1822 struct context au_ctxt;
1823};
1824
1825void selinux_audit_rule_free(struct selinux_audit_rule *rule)
1826{
1827 if (rule) {
1828 context_destroy(&rule->au_ctxt);
1829 kfree(rule);
1830 }
1831}
1832
1833int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
1834 struct selinux_audit_rule **rule)
1835{
1836 struct selinux_audit_rule *tmprule;
1837 struct role_datum *roledatum;
1838 struct type_datum *typedatum;
1839 struct user_datum *userdatum;
1840 int rc = 0;
1841
1842 *rule = NULL;
1843
1844 if (!ss_initialized)
1845 return -ENOTSUPP;
1846
1847 switch (field) {
1848 case AUDIT_SE_USER:
1849 case AUDIT_SE_ROLE:
1850 case AUDIT_SE_TYPE:
1851 /* only 'equals' and 'not equals' fit user, role, and type */
1852 if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
1853 return -EINVAL;
1854 break;
1855 case AUDIT_SE_SEN:
1856 case AUDIT_SE_CLR:
1857 /* we do not allow a range, indicated by the presense of '-' */
1858 if (strchr(rulestr, '-'))
1859 return -EINVAL;
1860 break;
1861 default:
1862 /* only the above fields are valid */
1863 return -EINVAL;
1864 }
1865
1866 tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL);
1867 if (!tmprule)
1868 return -ENOMEM;
1869
1870 context_init(&tmprule->au_ctxt);
1871
1872 POLICY_RDLOCK;
1873
1874 tmprule->au_seqno = latest_granting;
1875
1876 switch (field) {
1877 case AUDIT_SE_USER:
1878 userdatum = hashtab_search(policydb.p_users.table, rulestr);
1879 if (!userdatum)
1880 rc = -EINVAL;
1881 else
1882 tmprule->au_ctxt.user = userdatum->value;
1883 break;
1884 case AUDIT_SE_ROLE:
1885 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
1886 if (!roledatum)
1887 rc = -EINVAL;
1888 else
1889 tmprule->au_ctxt.role = roledatum->value;
1890 break;
1891 case AUDIT_SE_TYPE:
1892 typedatum = hashtab_search(policydb.p_types.table, rulestr);
1893 if (!typedatum)
1894 rc = -EINVAL;
1895 else
1896 tmprule->au_ctxt.type = typedatum->value;
1897 break;
1898 case AUDIT_SE_SEN:
1899 case AUDIT_SE_CLR:
1900 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
1901 break;
1902 }
1903
1904 POLICY_RDUNLOCK;
1905
1906 if (rc) {
1907 selinux_audit_rule_free(tmprule);
1908 tmprule = NULL;
1909 }
1910
1911 *rule = tmprule;
1912
1913 return rc;
1914}
1915
1916int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
1917 struct selinux_audit_rule *rule,
1918 struct audit_context *actx)
1919{
1920 struct context *ctxt;
1921 struct mls_level *level;
1922 int match = 0;
1923
1924 if (!rule) {
1925 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1926 "selinux_audit_rule_match: missing rule\n");
1927 return -ENOENT;
1928 }
1929
1930 POLICY_RDLOCK;
1931
1932 if (rule->au_seqno < latest_granting) {
1933 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1934 "selinux_audit_rule_match: stale rule\n");
1935 match = -ESTALE;
1936 goto out;
1937 }
1938
1939 ctxt = sidtab_search(&sidtab, ctxid);
1940 if (!ctxt) {
1941 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1942 "selinux_audit_rule_match: unrecognized SID %d\n",
1943 ctxid);
1944 match = -ENOENT;
1945 goto out;
1946 }
1947
1948 /* a field/op pair that is not caught here will simply fall through
1949 without a match */
1950 switch (field) {
1951 case AUDIT_SE_USER:
1952 switch (op) {
1953 case AUDIT_EQUAL:
1954 match = (ctxt->user == rule->au_ctxt.user);
1955 break;
1956 case AUDIT_NOT_EQUAL:
1957 match = (ctxt->user != rule->au_ctxt.user);
1958 break;
1959 }
1960 break;
1961 case AUDIT_SE_ROLE:
1962 switch (op) {
1963 case AUDIT_EQUAL:
1964 match = (ctxt->role == rule->au_ctxt.role);
1965 break;
1966 case AUDIT_NOT_EQUAL:
1967 match = (ctxt->role != rule->au_ctxt.role);
1968 break;
1969 }
1970 break;
1971 case AUDIT_SE_TYPE:
1972 switch (op) {
1973 case AUDIT_EQUAL:
1974 match = (ctxt->type == rule->au_ctxt.type);
1975 break;
1976 case AUDIT_NOT_EQUAL:
1977 match = (ctxt->type != rule->au_ctxt.type);
1978 break;
1979 }
1980 break;
1981 case AUDIT_SE_SEN:
1982 case AUDIT_SE_CLR:
1983 level = (op == AUDIT_SE_SEN ?
1984 &ctxt->range.level[0] : &ctxt->range.level[1]);
1985 switch (op) {
1986 case AUDIT_EQUAL:
1987 match = mls_level_eq(&rule->au_ctxt.range.level[0],
1988 level);
1989 break;
1990 case AUDIT_NOT_EQUAL:
1991 match = !mls_level_eq(&rule->au_ctxt.range.level[0],
1992 level);
1993 break;
1994 case AUDIT_LESS_THAN:
1995 match = (mls_level_dom(&rule->au_ctxt.range.level[0],
1996 level) &&
1997 !mls_level_eq(&rule->au_ctxt.range.level[0],
1998 level));
1999 break;
2000 case AUDIT_LESS_THAN_OR_EQUAL:
2001 match = mls_level_dom(&rule->au_ctxt.range.level[0],
2002 level);
2003 break;
2004 case AUDIT_GREATER_THAN:
2005 match = (mls_level_dom(level,
2006 &rule->au_ctxt.range.level[0]) &&
2007 !mls_level_eq(level,
2008 &rule->au_ctxt.range.level[0]));
2009 break;
2010 case AUDIT_GREATER_THAN_OR_EQUAL:
2011 match = mls_level_dom(level,
2012 &rule->au_ctxt.range.level[0]);
2013 break;
2014 }
2015 }
2016
2017out:
2018 POLICY_RDUNLOCK;
2019 return match;
2020}
2021
2022static int (*aurule_callback)(void) = NULL;
2023
2024static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
2025 u16 class, u32 perms, u32 *retained)
2026{
2027 int err = 0;
2028
2029 if (event == AVC_CALLBACK_RESET && aurule_callback)
2030 err = aurule_callback();
2031 return err;
2032}
2033
2034static int __init aurule_init(void)
2035{
2036 int err;
2037
2038 err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET,
2039 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
2040 if (err)
2041 panic("avc_add_callback() failed, error %d\n", err);
2042
2043 return err;
2044}
2045__initcall(aurule_init);
2046
2047void selinux_audit_set_callback(int (*callback)(void))
2048{
2049 aurule_callback = callback;
2050}