gfs2 filesystem and dlm development
 help / color / mirror / Atom feed
From: Michael Bommarito <michael.bommarito@gmail.com>
To: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Andrew Price <anprice@redhat.com>,
	gfs2@lists.linux.dev, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: [PATCH v2] gfs2: reject an over-long directory entry name in gfs2_check_dirent
Date: Tue, 14 Jul 2026 07:50:27 -0400	[thread overview]
Message-ID: <20260714115027.3765869-1-michael.bommarito@gmail.com> (raw)

gfs2_check_dirent() validates a directory entry against the space in its
dirent record but never bounds de_name_len to GFS2_FNAMESIZE. A dirent
with a large de_rec_len can therefore carry a de_name_len far greater than
GFS2_FNAMESIZE and still pass the check. That length flows unclamped
through do_filldir_main() -> dir_emit() to the ctx->actor. In the
NFS-export get_name path get_name_filldir() copies the name into the
fixed NAME_MAX+1 byte buffer nbuf[] on the exportfs_decode_fh_raw() stack
with memcpy(gnfd->name, name, length), so a crafted or corrupted on-disk
directory overflows that buffer.

Impact: an out-of-bounds write past the NAME_MAX+1 byte name buffer
(KASAN), reachable when a gfs2 filesystem carrying a crafted directory
entry is re-exported over NFS and a file handle is resolved.

Reject dirents whose name length exceeds GFS2_FNAMESIZE at the read-path
check, so no over-long name reaches any dirent consumer.

Fixes: b3b94faa5fe5 ("[GFS2] The core of GFS2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
v2: move the validation from get_name_filldir() into gfs2_check_dirent()
    on the dirent read path, per Andrew Price's review, so every dirent
    consumer is protected rather than only the NFS get_name path; and
    correct the buffer description (the destination is the NAME_MAX+1
    byte nbuf[] in exportfs_decode_fh_raw(), not a GFS2_FNAMESIZE buffer).
v1: https://lore.kernel.org/gfs2/20260711150845.gfs2-getname-v1@bommarito/

v1: https://lore.kernel.org/gfs2/20260711150808.2919076-1-michael.bommarito@gmail.com/

Evidence: a crafted gfs2 image with a directory dirent whose de_name_len
is 300 (record length left valid so the existing size check passes),
resolved with open_by_handle_at() on a KASAN + KASAN_STACK kernel.  Stock:
BUG: KASAN: stack-out-of-bounds in get_name_filldir, Write of size 300 into
the NAME_MAX+1 byte nbuf[] object of the exportfs_decode_fh_raw() stack
frame, via open_by_handle_at -> exportfs_decode_fh_raw -> reconnect_path ->
gfs2_get_name -> do_filldir_main -> get_name_filldir.  Patched:
gfs2_check_dirent() rejects the entry (name length exceeds GFS2_FNAMESIZE)
and the handle resolves to ESTALE; a valid name still reconnects.  Built
clean, no new warnings.

 fs/gfs2/dir.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 0237b36b9eb16..905b658a05177 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -521,6 +521,10 @@ static int gfs2_check_dirent(struct gfs2_sbd *sdp,
 	    unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
 		     size))
 		goto error;
+	msg = "name length exceeds GFS2_FNAMESIZE";
+	if (!gfs2_dirent_sentinel(dent) &&
+	    unlikely(be16_to_cpu(dent->de_name_len) > GFS2_FNAMESIZE))
+		goto error;
 	return 0;
 error:
 	fs_warn(sdp, "%s: %s (%s)\n",
-- 
2.53.0


                 reply	other threads:[~2026-07-14 11:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260714115027.3765869-1-michael.bommarito@gmail.com \
    --to=michael.bommarito@gmail.com \
    --cc=agruenba@redhat.com \
    --cc=anprice@redhat.com \
    --cc=gfs2@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox