This patch allows the AUDIR_DIR field to be used also with the exclude filter.
Not-yet-signed-off-by: Ondrej Mosnacek <[email protected]> --- kernel/audit.c | 5 +++-- kernel/audit.h | 32 +++++++++++++++++++++++++++++++- kernel/audit_tree.c | 4 +++- kernel/auditfilter.c | 6 +++++- kernel/auditsc.c | 28 ---------------------------- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/kernel/audit.c b/kernel/audit.c index e7478cb58079..aac5b6ecc11d 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1333,7 +1333,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!audit_enabled && msg_type != AUDIT_USER_AVC) return 0; - err = audit_filter(msg_type, AUDIT_FILTER_USER); + // FIXME: do we need to pass the context here? + err = audit_filter(msg_type, AUDIT_FILTER_USER, NULL); if (err == 1) { /* match or error */ err = 0; if (msg_type == AUDIT_USER_TTY) { @@ -1754,7 +1755,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, if (audit_initialized != AUDIT_INITIALIZED) return NULL; - if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE))) + if (unlikely(!audit_filter(type, AUDIT_FILTER_TYPE, ctx))) return NULL; /* NOTE: don't ever fail/sleep on these two conditions: diff --git a/kernel/audit.h b/kernel/audit.h index 214e14948370..43cfeba25802 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -324,13 +324,43 @@ extern void audit_kill_trees(struct list_head *list); #define audit_kill_trees(list) BUG() #endif +struct audit_tree_refs { + struct audit_tree_refs *next; + struct audit_chunk *c[31]; +}; + +/* A utility function to match tree refs: */ +static inline int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) +{ +#ifdef CONFIG_AUDIT_TREE + struct audit_tree_refs *p; + int n; + if (!tree) + return 0; + /* full ones */ + for (p = ctx->first_trees; p != ctx->trees; p = p->next) { + for (n = 0; n < 31; n++) + if (audit_tree_match(p->c[n], tree)) + return 1; + } + /* partial */ + if (p) { + for (n = ctx->tree_count; n < 31; n++) + if (audit_tree_match(p->c[n], tree)) + return 1; + } +#endif + return 0; +} + extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len); extern pid_t audit_sig_pid; extern kuid_t audit_sig_uid; extern u32 audit_sig_sid; -extern int audit_filter(int msgtype, unsigned int listtype); +extern int audit_filter(int msgtype, unsigned int listtype, + struct audit_context *ctx); #ifdef CONFIG_AUDITSYSCALL extern int audit_signal_info(int sig, struct task_struct *t); diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 67e6956c0b61..d4d36389c3d7 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -675,9 +675,11 @@ void audit_trim_trees(void) int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op) { + if (krule->listnr != AUDIT_FILTER_EXIT && + krule->listnr != AUDIT_FILTER_TYPE) + return -EINVAL; if (pathname[0] != '/' || - rule->listnr != AUDIT_FILTER_EXIT || op != Audit_equal || rule->inode_f || rule->watch || rule->tree) return -EINVAL; diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 6db9847ca031..e1d70cb77ea3 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1309,7 +1309,7 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen) return strncmp(p, dname, dlen); } -int audit_filter(int msgtype, unsigned int listtype) +int audit_filter(int msgtype, unsigned int listtype, struct audit_context *ctx) { struct audit_entry *e; int ret = 1; /* Audit by default */ @@ -1363,6 +1363,10 @@ int audit_filter(int msgtype, unsigned int listtype) if (f->op == Audit_not_equal) result = !result; break; + case AUDIT_DIR: + if (ctx) + result = match_tree_refs(ctx, e->rule.tree); + break; default: goto unlock_and_return; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ceb1c4596c51..0d00b9354886 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -125,11 +125,6 @@ struct audit_aux_data_bprm_fcaps { struct audit_cap_data new_pcap; }; -struct audit_tree_refs { - struct audit_tree_refs *next; - struct audit_chunk *c[31]; -}; - static int audit_match_perm(struct audit_context *ctx, int mask) { unsigned n; @@ -286,29 +281,6 @@ static void free_tree_refs(struct audit_context *ctx) } } -static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) -{ -#ifdef CONFIG_AUDIT_TREE - struct audit_tree_refs *p; - int n; - if (!tree) - return 0; - /* full ones */ - for (p = ctx->first_trees; p != ctx->trees; p = p->next) { - for (n = 0; n < 31; n++) - if (audit_tree_match(p->c[n], tree)) - return 1; - } - /* partial */ - if (p) { - for (n = ctx->tree_count; n < 31; n++) - if (audit_tree_match(p->c[n], tree)) - return 1; - } -#endif - return 0; -} - static int audit_compare_uid(kuid_t uid, struct audit_names *name, struct audit_field *f, -- 2.17.0 -- Linux-audit mailing list [email protected] https://www.redhat.com/mailman/listinfo/linux-audit
