All of lore.kernel.org
 help / color / mirror / Atom feed
From: Darrel Goeddel <dgoeddel@TrustedCS.com>
To: Darrel Goeddel <dgoeddel@TrustedCS.com>
Cc: "selinux@tycho.nsa.gov" <selinux@tycho.nsa.gov>,
	Linux Audit Discussion <linux-audit@redhat.com>,
	Dustin Kirkland <dustin.kirkland@us.ibm.com>,
	Amy Griffis <amy.griffis@hp.com>,
	Stephen Smalley <sds@epoch.ncsc.mil>,
	James Morris <jmorris@namei.org>
Subject: Re: [PATCH] context based audit filtering (take 3)
Date: Tue, 21 Feb 2006 17:59:30 -0600	[thread overview]
Message-ID: <43FBA962.5090904@trustedcs.com> (raw)
In-Reply-To: <43FB86DD.2020708@trustedcs.com>

Darrel Goeddel wrote:
...snip...
> The outstanding things I can think of are:
> 
> 1) Add role <, >, <=, and >= operations.
> 2) Implement the callback function in the audit code.  I have a functional
>   version that does not follow proper locking - I just need to get that
>   cleaned up.
> 3) Update Dustin's work to the latest API.  I already did this along with
>   my start at #2.  I'll post that all in a follow-up.

The updated version of Dustin's patch I referred to is below.  The changes are
are follows:

- Add the se_str char * to the audit_field.  This stores a copy of the string
  target that the rule is based on.  This is needed for the audit_compare_rule
  addition (below).  It will also be used in the callback for policy reloads
  (also below).  This is managed along with the se_rule field.  This also gets
  rid of a memory leak where the unpacked string was not being freed.
- printk a warning and ignore invalid selinux rules (but still hang on to them
  so they may be activated with a later policy reload).
- Change audit_compare_rule to compare the string values of the selinux rules
  to see if the rule exists.  Previously, it thought that any selinux filters
  based on equal length string were equal.
- Change audit_krule_to_data to put in the string target of the rule for the
  selinux filters.  This will hopefully allow the display of the type, level,
  etc. when dumping rules via AUDIT_LIST_RULES (I'll test tommorrow).
- Add a selinux callback for re-initializing the se_rule field when there is
  a policy reload.  THIS NEEDS WORK - It doesn't obey proper locking yet, but
  it is functional.  I need to get my head around the locking of the audit
  structures a little better - I'll also take suggestions ;)
- Obtain the sid of the task in audit_filter_rules instead of the callers
  obtaining it and passing it in.


diff --git a/kernel/audit.h b/kernel/audit.h
index eb33354..3ffc70a 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -59,9 +59,11 @@ struct audit_watch {
 };
 
 struct audit_field {
-	u32			type;
-	u32			val;
-	u32			op;
+	u32				type;
+	u32				val;
+	u32				op;
+	char				*se_str;
+	struct selinux_audit_rule	*se_rule;
 };
 
 struct audit_krule {
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index 3712295..306e941 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include <linux/netlink.h>
+#include <linux/selinux.h>
 #include "audit.h"
 
 /* There are three lists of rules -- one to search at task creation
@@ -50,6 +51,12 @@ static inline void audit_free_watch(stru
 
 static inline void audit_free_rule(struct audit_entry *e)
 {
+	int i;
+	for (i = 0; i < e->rule.field_count; i++) {
+		struct audit_field *f = &e->rule.fields[i];
+		kfree(f->se_str);
+		selinux_audit_rule_free(f->se_rule);
+	}
 	kfree(e->rule.fields);
 	kfree(e);
 }
@@ -222,7 +229,7 @@ static struct audit_entry *audit_data_to
 	void *bufp;
 	size_t remain = datasz - sizeof(struct audit_rule_data);
 	int i;
-	char *path;
+	char *str;
 
 	entry = audit_to_entry_common((struct audit_rule *)data);
 	if (IS_ERR(entry))
@@ -241,16 +248,40 @@ static struct audit_entry *audit_data_to
 		f->op = data->fieldflags[i] & AUDIT_OPERATORS;
 		f->type = data->fields[i];
 		f->val = data->values[i];
+		f->se_str = NULL;
+		f->se_rule = NULL;
 		switch(f->type) {
+		case AUDIT_SE_USER:
+		case AUDIT_SE_ROLE:
+		case AUDIT_SE_TYPE:
+		case AUDIT_SE_SEN:
+		case AUDIT_SE_CLR:
+			str = audit_unpack_string(&bufp, &remain, f->val);
+			if (IS_ERR(str))
+				goto exit_free;
+			entry->rule.buflen += f->val;
+
+			err = selinux_audit_rule_init(f->type, f->op, str,
+			                              &f->se_rule);
+			if (err == -EINVAL) {
+				printk(KERN_WARNING "selinux audit rule for item %s is invalid\n", str);
+				err = 0;
+			}
+			if (err) {
+				kfree(str);
+				goto exit_free;
+			} else
+				f->se_str = str;
+			break;
 		case AUDIT_WATCH:
-			path = audit_unpack_string(&bufp, &remain, f->val);
-			if (IS_ERR(path))
+			str = audit_unpack_string(&bufp, &remain, f->val);
+			if (IS_ERR(str))
 				goto exit_free;
 			entry->rule.buflen += f->val;
 
-			err = audit_to_watch(path, &entry->rule, i);
+			err = audit_to_watch(str, &entry->rule, i);
 			if (err) {
-				kfree(path);
+				kfree(str);
 				goto exit_free;
 			}
 			break;
@@ -333,6 +364,15 @@ static struct audit_rule_data *audit_kru
 			data->buflen += data->values[i] =
 				audit_pack_string(&bufp, krule->watch->path);
 			break;
+		case AUDIT_SE_USER:
+		case AUDIT_SE_ROLE:
+		case AUDIT_SE_TYPE:
+		case AUDIT_SE_SEN:
+		case AUDIT_SE_CLR:
+			data->buflen += data->values[i] =
+				audit_pack_string(&bufp,
+				                  krule->fields[i].se_str);
+			break;
 		default:
 			data->values[i] = f->val;
 		}
@@ -370,6 +410,14 @@ static int audit_compare_rule(struct aud
 			if (audit_compare_watch(a->watch, b->watch))
 				return 1;
 			break;
+		case AUDIT_SE_USER:
+		case AUDIT_SE_ROLE:
+		case AUDIT_SE_TYPE:
+		case AUDIT_SE_SEN:
+		case AUDIT_SE_CLR:
+			if (strcmp(a->fields[i].se_str, b->fields[i].se_str))
+				return 1;
+			break;
 		default:
 			if (a->fields[i].val != b->fields[i].val)
 				return 1;
@@ -640,6 +688,9 @@ int audit_comparator(const u32 left, con
 	default:
 		return -EINVAL;
 	}
+	/* should NEVER get here */
+	BUG();
+	return 0;
 }
 
 
@@ -726,3 +777,45 @@ unlock_and_return:
 	rcu_read_unlock();
 	return result;
 }
+
+static int selinux_callback(void)
+{
+	struct audit_entry *entry;
+	int i, j, err = 0;
+
+	/* TODO: add proper locking. */
+	for (i = 0; i < AUDIT_NR_FILTERS; i++) {
+		list_for_each_entry(entry, &audit_filter_list[i], list) {
+			for (j = 0; j < entry->rule.field_count; j++) {
+				struct audit_field *f = &entry->rule.fields[j];
+				switch (f->type) {
+				case AUDIT_SE_USER:
+				case AUDIT_SE_ROLE:
+				case AUDIT_SE_TYPE:
+				case AUDIT_SE_SEN:
+				case AUDIT_SE_CLR:
+					selinux_audit_rule_free(f->se_rule);
+					err = selinux_audit_rule_init(f->type,
+					         f->op, f->se_str, &f->se_rule);
+					if (err == -EINVAL) {
+						printk(KERN_WARNING "selinux audit rule for item %s is invalid\n", f->se_str);
+						err = 0;
+					}
+					if (err)
+						goto out;
+				}
+			}
+		}
+	}
+
+out:
+	return err;
+}
+
+static int __init register_selinux_callback(void)
+{
+	selinux_audit_set_callback(&selinux_callback);
+	return 0;
+}
+__initcall(register_selinux_callback);
+
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index cd83289..c52c80a 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -58,6 +58,7 @@
 #include <linux/security.h>
 #include <linux/list.h>
 #include <linux/tty.h>
+#include <linux/selinux.h>
 
 #include "audit.h"
 
@@ -168,6 +169,9 @@ static int audit_filter_rules(struct tas
 			      enum audit_state *state)
 {
 	int i, j;
+	u32 sid;
+
+	selinux_task_ctxid(tsk, &sid);
 
 	for (i = 0; i < rule->field_count; i++) {
 		struct audit_field *f = &rule->fields[i];
@@ -258,6 +262,18 @@ static int audit_filter_rules(struct tas
 			if (ctx)
 				result = audit_comparator(ctx->loginuid, f->op, f->val);
 			break;
+		case AUDIT_SE_USER:
+		case AUDIT_SE_ROLE:
+		case AUDIT_SE_TYPE:
+		case AUDIT_SE_SEN:
+		case AUDIT_SE_CLR:
+			/* NOTE: this may return negative values indicating
+			   a temporary error.  We simply treat this as a
+			   match for now to avoid losing information that
+			   may be wanted. */
+			result = selinux_audit_rule_match(sid, f->type, f->op,
+			                                  f->se_rule);
+			break;
 		case AUDIT_ARG0:
 		case AUDIT_ARG1:
 		case AUDIT_ARG2:



-- 

Darrel

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

  reply	other threads:[~2006-02-22  0:00 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-16 15:19 [RFC] [PATCH] Darrel Goeddel
2006-02-16 18:12 ` Stephen Smalley
2006-02-16 20:09   ` Darrel Goeddel
2006-02-16 20:36     ` Stephen Smalley
2006-02-17 14:43       ` Darrel Goeddel
     [not found]         ` <1140192267.3083.119.camel@kirkland1.austin.ibm.com>
2006-02-17 16:23           ` Darrel Goeddel
2006-02-17 18:26           ` Stephen Smalley
2006-02-21 21:32 ` [PATCH] context based audit filtering (take 3) Darrel Goeddel
2006-02-21 23:59   ` Darrel Goeddel [this message]
2006-02-22 14:58     ` Stephen Smalley
2006-02-23 23:31       ` Darrel Goeddel
2006-02-24 13:32         ` Stephen Smalley
2006-02-24 15:08           ` Steve Grubb
2006-02-22 15:07     ` Stephen Smalley
2006-02-22 15:24       ` Stephen Smalley
     [not found]     ` <d9c105ea0602212217g2f255fd8gbf6ac190d7ccd751@mail.gmail.com>
2006-02-22 15:09       ` Stephen Smalley
2006-02-22 14:46   ` Stephen Smalley
2006-02-23 17:42     ` [PATCH] context based audit filtering (take 4) Darrel Goeddel
2006-02-24 13:27       ` Stephen Smalley
2006-02-24 21:44         ` [PATCH] support for context based audit filtering Darrel Goeddel
2006-02-24 22:26           ` Darrel Goeddel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43FBA962.5090904@trustedcs.com \
    --to=dgoeddel@trustedcs.com \
    --cc=amy.griffis@hp.com \
    --cc=dustin.kirkland@us.ibm.com \
    --cc=jmorris@namei.org \
    --cc=linux-audit@redhat.com \
    --cc=sds@epoch.ncsc.mil \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.