On Aug  6, 2026 Stanislav Kinsburskii <[email protected]> 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 <[email protected]>
> ---
>  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

Reply via email to