On 2018-05-30 10:45, Ondrej Mosnacek wrote:
This patch allows the AUDIR_DIR field to be used also with the
exclude
filter.
Not-yet-signed-off-by: Ondrej Mosnacek <omosnace(a)redhat.com>
---
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);
I don't see why you need to send a context to audit_filter, since the
rest of the function assumes the current task you can just use
audit_context() to hand to match_tree_refs(). You could even check that
ctx isn't NULL in match_tree_refs() to hide that code from
audit_filter().
+ 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;
-}
-
Why did you move match_tree_refs() out of auditsc.c?
static int audit_compare_uid(kuid_t uid,
struct audit_names *name,
struct audit_field *f,
--
2.17.0
- RGB
--
Richard Guy Briggs <rgb(a)redhat.com>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635