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