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

Reply via email to