From 5adc8a6adc91c4c85a64c75a70a619fffc924817 Mon Sep 17 00:00:00 2001 From: Amy Griffis Date: Wed, 14 Jun 2006 18:45:21 -0400 Subject: [PATCH] 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. Signed-off-by: Amy Griffis --- kernel/auditsc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'kernel/auditsc.c') diff --git a/kernel/auditsc.c b/kernel/auditsc.c index dc5e3f01efe7..316657855165 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -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 task_struct *tsk, 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(struct audit_context *context) } audit_free_names(context); audit_free_aux(context); + kfree(context->filterkey); kfree(context); context = previous; } while (context); @@ -735,6 +743,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts 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) { @@ -1060,6 +1073,8 @@ void audit_syscall_exit(int valid, long return_code) } else { audit_free_names(context); audit_free_aux(context); + kfree(context->filterkey); + context->filterkey = NULL; tsk->audit_context = context; } } -- cgit v1.2.3