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

