add rule filterkey
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.
Signed-off-by Amy Griffis <[email protected]>
--- 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
@@ -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
@@ -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
@@ -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 tasif (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