[PATCH] erofs: validate nameoff for all dirents in erofs_fill_dentries()

Junrui Luo <[email protected]>
Newsgroups org.ozlabs.lists.linux-erofs,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <SYBPR01MB78819C794EC3532E5E7FCB3CAF252@SYBPR01MB7881.ausprd01.prod.outlook.com>
erofs_readdir() validates de[0].nameoff before calling
erofs_fill_dentries(), but subsequent dirents are used without
validation. The loop computes `maxsize - nameoff` as an unsigned int
to bound strnlen().

If a crafted EROFS image has a dirent with nameoff >= maxsize, the
subtraction underflows, causing strnlen() to read past the block
buffer.

Fix by validating each entry's nameoff at the top of the loop: it
must be >= nameoff0 and <= maxsize.

Cc: [email protected]
Fixes: 3aa8ec716e52 ("staging: erofs: add directory operations")
Reported-by: Yuhao Jiang <[email protected]>
Signed-off-by: Junrui Luo <[email protected]>
---
 fs/erofs/dir.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/erofs/dir.c b/fs/erofs/dir.c
index e5132575b9d3..2efa16fa162f 100644
--- a/fs/erofs/dir.c
+++ b/fs/erofs/dir.c
@@ -19,6 +19,13 @@ static int erofs_fill_dentries(struct inode *dir, struct dir_context *ctx,
 		const char *de_name = (char *)dentry_blk + nameoff;
 		unsigned int de_namelen;
 
+		if (nameoff < nameoff0 || nameoff > maxsize) {
+			erofs_err(dir->i_sb, "bogus dirent @ nid %llu",
+				  EROFS_I(dir)->nid);
+			DBG_BUGON(1);
+			return -EFSCORRUPTED;
+		}
+
 		/* the last dirent in the block? */
 		if (de + 1 >= end)
 			de_namelen = strnlen(de_name, maxsize - nameoff);

---
base-commit: 7aaa8047eafd0bd628065b15757d9b48c5f9c07d
change-id: 20260414-fixes-ae20cd389f52

Best regards,
-- 
Junrui Luo <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.