[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]>