audit: Fix filter rule accounting after automatic removal
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.
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@gmail.com>
[PM: removed "audit_bench" section as that is not being upstreamed]
Signed-off-by: Paul Moore <paul@paul-moore.com>
4 files changed