Skip to contentSkip to conversation

add rule filterkey

PATCH New Amy Griffis 1 participant 1 message Jun 14, 2006 Audit

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 add rule filterkey

Add support for a rule key, which can be used to tie audit records to audit rules. This is useful when a watched file is accessed through a link or symlink, as well as for general audit log analysis.

Because this patch uses a string key instead of an integer key, there is a bit of extra overhead to do the kstrdup() when a rule fires. However, we're also allocating memory for the audit record buffer, so it's probably not that significant. I went ahead with a string key because it seems more user-friendly.

Note that the user must ensure that filterkeys are unique. The kernel only checks for duplicate rules.

---
 include/linux/audit.h |    3 ++
 kernel/audit.h        |    1 +
 kernel/auditfilter.c  |   95 ++++++++++++++++++++++++++++++-------------------
 kernel/auditsc.c      |   15 ++++++++
 4 files changed, 78 insertions(+), 36 deletions(-)
include/linux/audit.h +3 -0
index e1c1dbd..f7883ec 100644
@@ -123,6 +123,7 @@ #define AUDIT_ALWAYS   2	/* Generate aud
 /* Rule structure sizes -- if these change, different AUDIT_ADD and
  * AUDIT_LIST commands must be implemented. */
 #define AUDIT_MAX_FIELDS   64
+#define AUDIT_MAX_KEY_LEN  32
 #define AUDIT_BITMASK_SIZE 64
 #define AUDIT_WORD(nr) ((__u32)((nr)/32))
 #define AUDIT_BIT(nr)  (1 << ((nr) - AUDIT_WORD(nr)*32))
@@ -172,6 +173,8 @@ #define AUDIT_ARG1      (AUDIT_ARG0+1)
 #define AUDIT_ARG2      (AUDIT_ARG0+2)
 #define AUDIT_ARG3      (AUDIT_ARG0+3)
 
+#define AUDIT_FILTERKEY	210
+
 #define AUDIT_NEGATE			0x80000000
 
 /* These are the supported operators.
kernel/audit.h +1 -0
index 38e62b7..0381640 100644
@@ -81,6 +81,7 @@ struct audit_krule {
 	u32			mask[AUDIT_BITMASK_SIZE];
 	u32			buflen; /* for data alloc on list rules */
 	u32			field_count;
+	char			*filterkey; /* ties events to rules */
 	struct audit_field	*fields;
 	struct audit_field	*inode_f; /* quick access to an inode field */
 	struct audit_watch	*watch;	/* associated watch */
kernel/auditfilter.c +59 -36

149 lines not on this page · raw message

kernel/auditsc.c +15 -0
index 1c43dba..b32ccfa 100644
@@ -186,6 +186,7 @@ struct audit_context {
 	int		    auditable;  /* 1 if record should be written */
 	int		    name_count;
 	struct audit_names  names[AUDIT_NAMES];
+	char *		    filterkey;	/* key for rule that triggered record */
 	struct dentry *	    pwd;
 	struct vfsmount *   pwdmnt;
 	struct audit_context *previous; /* For nested syscalls */
@@ -348,11 +349,17 @@ static int audit_filter_rules(struct tas
 			if (ctx)
 				result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
 			break;
+		case AUDIT_FILTERKEY:
+			/* ignore this field for filtering */
+			result = 1;
+			break;
 		}
 
 		if (!result)
 			return 0;
 	}
+	if (rule->filterkey)
+		ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
 	switch (rule->action) {
 	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
 	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
@@ -627,6 +634,7 @@ static inline void audit_free_context(st
 		}
 		audit_free_names(context);
 		audit_free_aux(context);
+		kfree(context->filterkey);
 		kfree(context);
 		context  = previous;
 	} while (context);
@@ -736,6 +744,11 @@ static void audit_log_exit(struct audit_
 		  context->euid, context->suid, context->fsuid,
 		  context->egid, context->sgid, context->fsgid, tty);
 	audit_log_task_info(ab, tsk);
+	if (context->filterkey) {
+		audit_log_format(ab, " key=");
+		audit_log_untrustedstring(ab, context->filterkey);
+	} else
+		audit_log_format(ab, " key=(null)");
 	audit_log_end(ab);
 
 	for (aux = context->aux; aux; aux = aux->next) {
@@ -1061,6 +1074,8 @@ void audit_syscall_exit(int valid, long 
 	} else {
 		audit_free_names(context);
 		audit_free_aux(context);
+		kfree(context->filterkey);
+		context->filterkey = NULL;
 		tsk->audit_context = context;
 	}
 }
Signature · 1 line
1.4.0