kernel/auditfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
When a watch on dir=/ is combined with an fsnotify event for a
single-character name directly under / (e.g., creating /a), an
out-of-bounds read can occur in audit_compare_dname_path().
The helper parent_len() returns 1 for "/". In audit_compare_dname_path(),
when parentlen equals the full path length (1), the code sets p = path + 1
and pathlen = 1 - 1 = 0. The subsequent loop then dereferences
p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read.
Fix this by adding a pathlen > 0 check to the while loop condition
to prevent the out-of-bounds access.
Reported-by: Stanislav Fort <disclosure@aisle.com>
Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org>
Signed-off-by: Stanislav Fort <disclosure@aisle.com>
---
kernel/auditfilter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index e3f42018ed46..f7708fe2c457 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -1326,7 +1326,7 @@ int audit_compare_dname_path(const struct qstr *dname, const char *path, int par
/* handle trailing slashes */
pathlen -= parentlen;
- while (p[pathlen - 1] == '/')
+ while (pathlen > 0 && p[pathlen - 1] == '/')
pathlen--;
if (pathlen != dlen)
--
2.39.3 (Apple Git-146)
On Tue, Sep 2, 2025 at 7:00 AM Stanislav Fort <stanislav.fort@aisle.com> wrote: > > When a watch on dir=/ is combined with an fsnotify event for a > single-character name directly under / (e.g., creating /a), an > out-of-bounds read can occur in audit_compare_dname_path(). > > The helper parent_len() returns 1 for "/". In audit_compare_dname_path(), > when parentlen equals the full path length (1), the code sets p = path + 1 > and pathlen = 1 - 1 = 0. The subsequent loop then dereferences > p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read. > > Fix this by adding a pathlen > 0 check to the while loop condition > to prevent the out-of-bounds access. > > Reported-by: Stanislav Fort <disclosure@aisle.com> > Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> > Signed-off-by: Stanislav Fort <disclosure@aisle.com> > --- > kernel/auditfilter.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Thanks Stanislav. It looks like this problem was likely introduced in e92eebb0d611 ("audit: fix suffixed '/' filename matching"), I'll add a 'Fixes:' and a stable tag. I'm building a test kernel right now to test things, but did you verify that the path matching fixed in e92eebb0d611 still works correctly? > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c > index e3f42018ed46..f7708fe2c457 100644 > --- a/kernel/auditfilter.c > +++ b/kernel/auditfilter.c > @@ -1326,7 +1326,7 @@ int audit_compare_dname_path(const struct qstr *dname, const char *path, int par > > /* handle trailing slashes */ > pathlen -= parentlen; > - while (p[pathlen - 1] == '/') > + while (pathlen > 0 && p[pathlen - 1] == '/') > pathlen--; > > if (pathlen != dlen) > -- > 2.39.3 (Apple Git-146) -- paul-moore.com
On Tue, Sep 2, 2025 at 2:50 PM Paul Moore <paul@paul-moore.com> wrote: > On Tue, Sep 2, 2025 at 7:00 AM Stanislav Fort <stanislav.fort@aisle.com> wrote: > > > > When a watch on dir=/ is combined with an fsnotify event for a > > single-character name directly under / (e.g., creating /a), an > > out-of-bounds read can occur in audit_compare_dname_path(). > > > > The helper parent_len() returns 1 for "/". In audit_compare_dname_path(), > > when parentlen equals the full path length (1), the code sets p = path + 1 > > and pathlen = 1 - 1 = 0. The subsequent loop then dereferences > > p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read. > > > > Fix this by adding a pathlen > 0 check to the while loop condition > > to prevent the out-of-bounds access. > > > > Reported-by: Stanislav Fort <disclosure@aisle.com> > > Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> > > Signed-off-by: Stanislav Fort <disclosure@aisle.com> > > --- > > kernel/auditfilter.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > Thanks Stanislav. It looks like this problem was likely introduced in > e92eebb0d611 ("audit: fix suffixed '/' filename matching"), I'll add a > 'Fixes:' and a stable tag. > > I'm building a test kernel right now to test things, but did you > verify that the path matching fixed in e92eebb0d611 still works > correctly? The basic testing I've done today looks good. If you can let me know about the email in your sign-off we can get this merged and up to Linus this week. > > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c > > index e3f42018ed46..f7708fe2c457 100644 > > --- a/kernel/auditfilter.c > > +++ b/kernel/auditfilter.c > > @@ -1326,7 +1326,7 @@ int audit_compare_dname_path(const struct qstr *dname, const char *path, int par > > > > /* handle trailing slashes */ > > pathlen -= parentlen; > > - while (p[pathlen - 1] == '/') > > + while (pathlen > 0 && p[pathlen - 1] == '/') > > pathlen--; > > > > if (pathlen != dlen) > > -- > > 2.39.3 (Apple Git-146) -- paul-moore.com
On Tue, Sep 2, 2025 at 2:50 PM Paul Moore <paul@paul-moore.com> wrote: > On Tue, Sep 2, 2025 at 7:00 AM Stanislav Fort <stanislav.fort@aisle.com> wrote: > > > > When a watch on dir=/ is combined with an fsnotify event for a > > single-character name directly under / (e.g., creating /a), an > > out-of-bounds read can occur in audit_compare_dname_path(). > > > > The helper parent_len() returns 1 for "/". In audit_compare_dname_path(), > > when parentlen equals the full path length (1), the code sets p = path + 1 > > and pathlen = 1 - 1 = 0. The subsequent loop then dereferences > > p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read. > > > > Fix this by adding a pathlen > 0 check to the while loop condition > > to prevent the out-of-bounds access. > > > > Reported-by: Stanislav Fort <disclosure@aisle.com> > > Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> > > Signed-off-by: Stanislav Fort <disclosure@aisle.com> I also just noticed a disconnect on the email address. I can leave the Reported-by email as disclosure@, but do you mind if I convert your Signed-off-by email to stanislav.fort@? > > --- > > kernel/auditfilter.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > Thanks Stanislav. It looks like this problem was likely introduced in > e92eebb0d611 ("audit: fix suffixed '/' filename matching"), I'll add a > 'Fixes:' and a stable tag. > > I'm building a test kernel right now to test things, but did you > verify that the path matching fixed in e92eebb0d611 still works > correctly? > > > diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c > > index e3f42018ed46..f7708fe2c457 100644 > > --- a/kernel/auditfilter.c > > +++ b/kernel/auditfilter.c > > @@ -1326,7 +1326,7 @@ int audit_compare_dname_path(const struct qstr *dname, const char *path, int par > > > > /* handle trailing slashes */ > > pathlen -= parentlen; > > - while (p[pathlen - 1] == '/') > > + while (pathlen > 0 && p[pathlen - 1] == '/') > > pathlen--; > > > > if (pathlen != dlen) > > -- > > 2.39.3 (Apple Git-146) -- paul-moore.com
On Tue, Sep 2, 2025 at 2:52 PM Paul Moore <paul@paul-moore.com> wrote: > On Tue, Sep 2, 2025 at 2:50 PM Paul Moore <paul@paul-moore.com> wrote: > > On Tue, Sep 2, 2025 at 7:00 AM Stanislav Fort <stanislav.fort@aisle.com> wrote: > > > > > > When a watch on dir=/ is combined with an fsnotify event for a > > > single-character name directly under / (e.g., creating /a), an > > > out-of-bounds read can occur in audit_compare_dname_path(). > > > > > > The helper parent_len() returns 1 for "/". In audit_compare_dname_path(), > > > when parentlen equals the full path length (1), the code sets p = path + 1 > > > and pathlen = 1 - 1 = 0. The subsequent loop then dereferences > > > p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read. > > > > > > Fix this by adding a pathlen > 0 check to the while loop condition > > > to prevent the out-of-bounds access. > > > > > > Reported-by: Stanislav Fort <disclosure@aisle.com> > > > Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> > > > Signed-off-by: Stanislav Fort <disclosure@aisle.com> > > I also just noticed a disconnect on the email address. I can leave > the Reported-by email as disclosure@, but do you mind if I convert > your Signed-off-by email to stanislav.fort@? Stanislav, are you okay with changing your sign-off email to stanislav.fort@aisle.com? -- paul-moore.com
Hi Paul, Yes, please go ahead and change the Signed-off-by to: Signed-off-by: Stanislav Fort <stanislav.fort@aisle.com> Sorry for the slight delay and thanks for the quick review, testing, and for adding the Fixes tag. Best wishes, Stanislav Fort Aisle Research On Wednesday, September 3, 2025 at 6:16:59 PM UTC+3 Paul Moore wrote: > On Tue, Sep 2, 2025 at 2:52 PM Paul Moore <paul@paul-moore.com> wrote: > > On Tue, Sep 2, 2025 at 2:50 PM Paul Moore <paul@paul-moore.com> wrote: > > > On Tue, Sep 2, 2025 at 7:00 AM Stanislav Fort < > stanislav.fort@aisle.com> wrote: > > > > > > > > When a watch on dir=/ is combined with an fsnotify event for a > > > > single-character name directly under / (e.g., creating /a), an > > > > out-of-bounds read can occur in audit_compare_dname_path(). > > > > > > > > The helper parent_len() returns 1 for "/". In > audit_compare_dname_path(), > > > > when parentlen equals the full path length (1), the code sets p = > path + 1 > > > > and pathlen = 1 - 1 = 0. The subsequent loop then dereferences > > > > p[pathlen - 1] (i.e., p[-1]), causing an out-of-bounds read. > > > > > > > > Fix this by adding a pathlen > 0 check to the while loop condition > > > > to prevent the out-of-bounds access. > > > > > > > > Reported-by: Stanislav Fort <disclosure@aisle.com> > > > > Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> > > > > Signed-off-by: Stanislav Fort <disclosure@aisle.com> > > > > I also just noticed a disconnect on the email address. I can leave > > the Reported-by email as disclosure@, but do you mind if I convert > > your Signed-off-by email to stanislav.fort@? > > Stanislav, are you okay with changing your sign-off email to > stanislav.fort@aisle.com? > > -- > paul-moore.com >
On Wed, Sep 3, 2025 at 2:03 PM Disclosure <disclosure@aisle.com> wrote: > > Hi Paul, > > Yes, please go ahead and change the Signed-off-by to: > Signed-off-by: Stanislav Fort <stanislav.fort@aisle.com> > > Sorry for the slight delay and thanks for the quick review, testing, and for adding the Fixes tag. No worries, thanks for the fix :) I'm merging this into audit/stable-6.17 and I'll plan to send this up to Linus later this week. -- paul-moore.com
© 2016 - 2025 Red Hat, Inc.