Re: [PATCH 2/3] audit: Fix filter rule accounting after automatic removal

From: Paul Moore

Date: Tue Sep 01 2026 - 17:35:43 EST


On Aug 6, 2026 Stanislav Kinsburskii <skinsburskii@xxxxxxxxx> wrote:
>
> The audit_n_rules and audit_signals counters are incremented when filter
> rules are installed and decremented by the explicit rule deletion path.
> Rules can also disappear when a watch or tree is removed, or when an LSM
> rule cannot be reconstructed, but those paths do not update the counters.
>
> As a result, audit_n_rules can remain nonzero after the last applicable
> rule has gone away, causing subsequent syscalls to allocate non-dummy
> audit contexts unnecessarily. A stale audit_signals value similarly
> causes unnecessary signal auditing work.
>
> This can be reproduced for an inode watch with:
>
> mkdir /tmp/audit-n-rules-bench
> touch /tmp/audit-n-rules-bench/watched
> auditctl -w /tmp/audit-n-rules-bench/watched -p r \
> -k audit_n_rules_bench
> rm /tmp/audit-n-rules-bench/watched
> rmdir /tmp/audit-n-rules-bench
>
> The rm updates the watch after its inode disappears, and the rmdir causes
> audit_remove_parent_watches() to remove the rule. For an audit tree, the
> kill_rules() path can be reproduced with:
>
> mkdir /tmp/audit-kill-rules
> auditctl -a always,exit -F arch=b64 \
> -F dir=/tmp/audit-kill-rules -F perm=r \
> -k audit_kill_rules_test
> rmdir /tmp/audit-kill-rules
>
> In both cases, auditctl -l reports no rules after the directory is
> removed. Run the following before installing the rule and again after it
> has disappeared:
>
> audit_bench --iterations 10000000 --repetitions 10
>
> For the inode watch, the same VM produced:
>
> no rules:
> median=38 mean=39 stddev=4 (10%) range=38..53 ns/op
> automatically removed, before this fix:
> median=55 mean=56 stddev=3 (5%) range=55..65 ns/op
> automatically removed, with this fix:
> median=38 mean=39 stddev=4 (10%) range=38..52 ns/op
>
> For the audit tree, it produced:
>
> no rules:
> median=38 mean=39 stddev=4 (9%) range=38..52 ns/op
> automatically removed, before this fix:
> median=59 mean=60 stddev=2 (3%) range=59..67 ns/op
> automatically removed, with this fix:
> median=38 mean=39 stddev=4 (9%) range=38..52 ns/op
>
> Reboot between the unpatched and patched tests because an already stale
> counter cannot be repaired by deleting rules which are no longer present.
>
> Factor the existing counter updates into common rule insertion and removal
> helpers and call the removal helper from every automatic removal path. All
> of these updates remain serialized by audit_filter_mutex.
>
> Fixes: 471a5c7c8391 ("[PATCH] introduce audit rules counter")
> Fixes: e54dc2431d74 ("[PATCH] audit signal recipients")
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@xxxxxxxxx>
> ---
> kernel/audit.h | 5 +++
> kernel/audit_tree.c | 1 +
> kernel/audit_watch.c | 2 ++
> kernel/auditfilter.c | 86 +++++++++++++++++++++++++---------------------------
> 4 files changed, 50 insertions(+), 44 deletions(-)

This looks good to me. I'm going to merge this into audit/dev, but I'm
going to drop the "audit_bench" references from the commit description as
I don't think we want that tool in the kernel sources right now.

Thanks Stanislav, both for finding the bug and providing a clean, elegant
fix.

--
paul-moore.com