[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