Messages in this thread Patch in this message | | | From | Ankur Arora <> | Subject | [PATCH 3/3] audit: unify audit_filter_{uring(),inode_name(),syscall()} | Date | Tue, 27 Sep 2022 15:59:44 -0700 |
| |
audit_filter_uring(), audit_filter_inode_name() are substantially similar to audit_filter_syscall(). Move the core logic to __audit_filter() which can be parametrized for all three.
On a Skylakex system, getpid() latency (all results aggregated across 12 boot cycles):
Min Mean Median Max pstdev (ns) (ns) (ns) (ns)
- 173.11 182.51 179.65 202.09 (+- 4.34%) + 162.11 175.26 173.71 190.56 (+- 4.33%)
Performance counter stats for 'bin/getpid' (3 runs) go from: cycles 706.13 ( +- 4.13% ) instructions 1654.70 ( +- .06% ) IPC 2.35 ( +- 4.25% ) branches 430.99 ( +- .06% ) branch-misses 0.50 ( +- 2.00% ) L1-dcache-loads 440.02 ( +- .07% ) L1-dcache-load-misses 5.22 ( +- 82.75% )
to: cycles 678.79 ( +- 4.22% ) instructions 1657.79 ( +- .05% ) IPC 2.45 ( +- 4.08% ) branches 432.00 ( +- .05% ) branch-misses 0.38 ( +- 23.68% ) L1-dcache-loads 444.96 ( +- .03% ) L1-dcache-load-misses 5.13 ( +- 73.09% )
(Both aggregated over 12 boot cycles.)
Unclear if the improvement is just run-to-run variation or because of a slightly denser loop (the list parameter in the list_for_each_entry_rcu() exit check now comes from a register rather than a constant as before.)
Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com> --- kernel/auditsc.c | 86 +++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 42 deletions(-)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index bf26f47b5226..dd89a52988b0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -805,6 +805,41 @@ static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) return rule->mask[word] & bit; } +/** + * __audit_filter - common filter + * + * @tsk: associated task + * @ctx: audit context + * @list: audit filter list + * @op: current syscall/uring_op + * @name: name to be filtered (used by audit_filter_inode_name) + * + * return: 1 if we hit a filter, 0 if we don't + */ +static int __audit_filter(struct task_struct *tsk, + struct audit_context *ctx, + struct list_head *list, + unsigned long op, + struct audit_names *name) +{ + struct audit_entry *e; + enum audit_state state; + + rcu_read_lock(); + list_for_each_entry_rcu(e, list, list) { + if (unlikely(audit_in_mask(&e->rule, op))) { + if (audit_filter_rules(tsk, &e->rule, ctx, name, + &state, false)) { + rcu_read_unlock(); + ctx->current_state = state; + return 1; + } + } + } + rcu_read_unlock(); + return 0; +} + /** * audit_filter_uring - apply filters to an io_uring operation * @tsk: associated task @@ -813,24 +848,11 @@ static bool audit_in_mask(const struct audit_krule *rule, unsigned long val) static void audit_filter_uring(struct task_struct *tsk, struct audit_context *ctx) { - struct audit_entry *e; - enum audit_state state; - if (auditd_test_task(tsk)) return; - rcu_read_lock(); - list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_URING_EXIT], - list) { - if (audit_in_mask(&e->rule, ctx->uring_op) && - audit_filter_rules(tsk, &e->rule, ctx, NULL, &state, - false)) { - rcu_read_unlock(); - ctx->current_state = state; - return; - } - } - rcu_read_unlock(); + __audit_filter(tsk, ctx, &audit_filter_list[AUDIT_FILTER_URING_EXIT], + ctx->uring_op, NULL); } /* At syscall exit time, this filter is called if the audit_state is @@ -841,26 +863,11 @@ static void audit_filter_uring(struct task_struct *tsk, static void audit_filter_syscall(struct task_struct *tsk, struct audit_context *ctx) { - struct audit_entry *e; - enum audit_state state; - unsigned long major = ctx->major; - if (auditd_test_task(tsk)) return; - rcu_read_lock(); - list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_EXIT], list) { - if (unlikely(audit_in_mask(&e->rule, major))) { - if (audit_filter_rules(tsk, &e->rule, ctx, NULL, - &state, false)) { - rcu_read_unlock(); - ctx->current_state = state; - return; - } - } - } - rcu_read_unlock(); - return; + __audit_filter(tsk, ctx, &audit_filter_list[AUDIT_FILTER_EXIT], + ctx->major, NULL); } /* @@ -872,17 +879,12 @@ static int audit_filter_inode_name(struct task_struct *tsk, struct audit_context *ctx) { int h = audit_hash_ino((u32)n->ino); struct list_head *list = &audit_inode_hash[h]; - struct audit_entry *e; - enum audit_state state; - list_for_each_entry_rcu(e, list, list) { - if (audit_in_mask(&e->rule, ctx->major) && - audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { - ctx->current_state = state; - return 1; - } - } - return 0; + /* + * We are called holding an rcu read lock. __audit_filter() will take + * one as well. + */ + return __audit_filter(tsk, ctx, list, ctx->major, n); } /* At syscall exit time, this filter is called if any audit_names have been -- 2.31.1
| |