[redhat-lspp] [RFC KERNEL] object audit filters based on SELinux context
Darrel Goeddel
dgoeddel at trustedcs.com
Fri Jun 23 21:57:50 UTC 2006
I recently noticed that we never got around to doing object filters
based on context... This patch introduces object audit filters
based on the fields of the SELinux context. I put in everything
(user, role, type, levels) even though I don't think user and role
will be of use. I'm also open to names on the filters because I
couldn't really think of anything that sounded really good
(especially for the object's mls - "ol1 means object level 1" and
"ol2 means object level2"...). So, I'll trim and rename if people
want that. This is just the kernel part, the userspace patch to
handle these fields is forthcoming. One more thing - this patch
only checks the contexts of filesystem objects. We also collect
sids for ipc objects in the aux structs, should I also loop through
those and filter based on the sids contained in AUDIT_IPC records?
include/linux/audit.h | 5 +++++
kernel/auditfilter.c | 25 +++++++++++++++++++++++++
kernel/auditsc.c | 25 +++++++++++++++++++++++++
security/selinux/ss/services.c | 17 ++++++++++++++++-
4 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index f7883ec..f0857d6 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -158,6 +158,11 @@ #define AUDIT_SE_TYPE 15 /* security lab
#define AUDIT_SE_SEN 16 /* security label sensitivity label */
#define AUDIT_SE_CLR 17 /* security label clearance label */
#define AUDIT_PPID 18
+#define AUDIT_SE_OUSER 19
+#define AUDIT_SE_OROLE 20
+#define AUDIT_SE_OTYPE 21
+#define AUDIT_SE_OL1 22
+#define AUDIT_SE_OL2 23
/* These are ONLY useful when checking
* at syscall exit time (AUDIT_AT_EXIT). */
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index e98db08..6d77d1d 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -475,6 +475,11 @@ static struct audit_entry *audit_data_to
case AUDIT_SE_TYPE:
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
str = audit_unpack_string(&bufp, &remain, f->val);
if (IS_ERR(str))
goto exit_free;
@@ -616,6 +621,11 @@ static struct audit_rule_data *audit_kru
case AUDIT_SE_TYPE:
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
data->buflen += data->values[i] =
audit_pack_string(&bufp, f->se_str);
break;
@@ -659,6 +669,11 @@ static int audit_compare_rule(struct aud
case AUDIT_SE_TYPE:
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
return 1;
break;
@@ -779,6 +794,11 @@ static struct audit_entry *audit_dupe_ru
case AUDIT_SE_TYPE:
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
err = audit_dupe_selinux_field(&new->fields[i],
&old->fields[i]);
break;
@@ -1542,6 +1562,11 @@ static inline int audit_rule_has_selinux
case AUDIT_SE_TYPE:
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
return 1;
}
}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b32ccfa..fa6ead8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -342,6 +342,31 @@ static int audit_filter_rules(struct tas
ctx);
}
break;
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
+ /* The above note for AUDIT_SE_USER...AUDIT_SE_CLR
+ also applies here */
+ if (f->se_rule) {
+ if (name) {
+ result = selinux_audit_rule_match(
+ name->osid, f->type, f->op,
+ f->se_rule, ctx);
+ } else if (ctx) {
+ for (j = 0; j < ctx->name_count; j++) {
+ if (selinux_audit_rule_match(
+ ctx->names[j].osid,
+ f->type, f->op,
+ f->se_rule, ctx)) {
+ ++result;
+ break;
+ }
+ }
+ }
+ }
+ break;
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index d82898c..5d0edd0 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1858,12 +1858,17 @@ int selinux_audit_rule_init(u32 field, u
case AUDIT_SE_USER:
case AUDIT_SE_ROLE:
case AUDIT_SE_TYPE:
+ case AUDIT_SE_OUSER:
+ case AUDIT_SE_OROLE:
+ case AUDIT_SE_OTYPE:
/* only 'equals' and 'not equals' fit user, role, and type */
if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
return -EINVAL;
break;
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
/* we do not allow a range, indicated by the presense of '-' */
if (strchr(rulestr, '-'))
return -EINVAL;
@@ -1885,6 +1890,7 @@ int selinux_audit_rule_init(u32 field, u
switch (field) {
case AUDIT_SE_USER:
+ case AUDIT_SE_OUSER:
userdatum = hashtab_search(policydb.p_users.table, rulestr);
if (!userdatum)
rc = -EINVAL;
@@ -1892,6 +1898,7 @@ int selinux_audit_rule_init(u32 field, u
tmprule->au_ctxt.user = userdatum->value;
break;
case AUDIT_SE_ROLE:
+ case AUDIT_SE_OROLE:
roledatum = hashtab_search(policydb.p_roles.table, rulestr);
if (!roledatum)
rc = -EINVAL;
@@ -1899,6 +1906,7 @@ int selinux_audit_rule_init(u32 field, u
tmprule->au_ctxt.role = roledatum->value;
break;
case AUDIT_SE_TYPE:
+ case AUDIT_SE_OTYPE:
typedatum = hashtab_search(policydb.p_types.table, rulestr);
if (!typedatum)
rc = -EINVAL;
@@ -1907,6 +1915,8 @@ int selinux_audit_rule_init(u32 field, u
break;
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
break;
}
@@ -1959,6 +1969,7 @@ int selinux_audit_rule_match(u32 ctxid,
without a match */
switch (field) {
case AUDIT_SE_USER:
+ case AUDIT_SE_OUSER:
switch (op) {
case AUDIT_EQUAL:
match = (ctxt->user == rule->au_ctxt.user);
@@ -1969,6 +1980,7 @@ int selinux_audit_rule_match(u32 ctxid,
}
break;
case AUDIT_SE_ROLE:
+ case AUDIT_SE_OROLE:
switch (op) {
case AUDIT_EQUAL:
match = (ctxt->role == rule->au_ctxt.role);
@@ -1979,6 +1991,7 @@ int selinux_audit_rule_match(u32 ctxid,
}
break;
case AUDIT_SE_TYPE:
+ case AUDIT_SE_OTYPE:
switch (op) {
case AUDIT_EQUAL:
match = (ctxt->type == rule->au_ctxt.type);
@@ -1990,7 +2003,9 @@ int selinux_audit_rule_match(u32 ctxid,
break;
case AUDIT_SE_SEN:
case AUDIT_SE_CLR:
- level = (field == AUDIT_SE_SEN ?
+ case AUDIT_SE_OL1:
+ case AUDIT_SE_OL2:
+ level = ((field == AUDIT_SE_SEN || field == AUDIT_SE_OL1) ?
&ctxt->range.level[0] : &ctxt->range.level[1]);
switch (op) {
case AUDIT_EQUAL:
--
Darrel
More information about the redhat-lspp
mailing list