Re: [PATCH 1/1] audit: fix potential use-after-free in audit_del_rule()
Paul Moore <[email protected]> Wed, 29 Jul 2026 16:31:46 -0400
| Newsgroups | org.kernel.vger.audit |
|---|---|
| Message-ID | <CAHC9VhRGM5Cpup5=Vz1J1WNh+KkPpGUacayz4mt=ov_d=a8_xw@mail.gmail.com> |
On Thu, Jul 23, 2026 at 11:11=E2=80=AFPM Lain Anc <[email protected]> wrot= e: > Paul Moore <[email protected]> =E4=BA=8E2026=E5=B9=B47=E6=9C=8824=E6=97= =A5=E5=91=A8=E4=BA=94 05:57=E5=86=99=E9=81=93=EF=BC=9A > > > > On Jul 21, 2026 Ren Wei <[email protected]> wrote: > > > > > > `audit_del_rule()` destroys `e->rule.exe` via `audit_remove_mark_rule= ()` > > > before unlinking the rule from RCU-visible filter lists and waiting f= or a > > > grace period. Concurrent readers in `audit_filter()` and > > > `audit_filter_rules()` still dereference `e->rule.exe`, while the fsn= otify > > > mark can be freed on an independent lifetime path. This creates a use= -after-free > > > window during rule deletion. > > > > > > Fix this by unlinking the rule from the RCU-visible lists and invokin= g > > > `synchronize_rcu()` before calling `audit_remove_mark_rule()` (and ot= her > > > rule removal helpers). This ensures that all existing RCU readers hav= e exited > > > the critical section before any underlying resources are destroyed. > > > > > > Fixes: 34d99af52ad4 ("audit: implement audit by executable") > > > Cc: [email protected] > > > Reported-by: Vega <[email protected]> > > > Assisted-by: Codex:gpt-5.4 > > > Signed-off-by: Luxiao Xu <[email protected]> > > > Signed-off-by: Ren Wei <[email protected]> > > > --- > > > kernel/auditfilter.c | 6 ++++-- > > > 1 file changed, 4 insertions(+), 2 deletions(-) > > > > Thanks for identifying this and providing a patch, some initial thought= s > > below ... > > > > > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c > > > index 4401119b5275..7f791afe5791 100644 > > > --- a/kernel/auditfilter.c > > > +++ b/kernel/auditfilter.c > > > @@ -1045,6 +1045,10 @@ int audit_del_rule(struct audit_entry *entry) > > > goto out; > > > } > > > > > > + list_del_rcu(&e->list); > > > + list_del(&e->rule.list); > > > + synchronize_rcu(); > > > > I generally prefer to use call_rcu() instead of synchronize_rcu() when > > possible. Did you consider creating a audit_del_rule_rcu() (or similar= ) > > function which would perform the other cleanups/releases below this poi= nt > > including the call to audit_free_rule_rcu() which could then be called > > by call_rcu()? > > > > It's worth mentioning that I didn't verify all of the code involved to > > know if this would work, be safe, etc., I just wanted to check to see i= f > > you already had and decided synchronize_rcu() was the only option. > > > > Thanks for reviewing the patch and for the suggestion! I did look > into using call_rcu() for the cleanup, but we cannot do so due to > sleeping constraints in RCU callbacks. Merged into audit/stable-7.2, thanks. --=20 paul-moore.com