[PATCH] erofs-utils: lib: bound-check truncated directory blocks
Vansh Choudhary
ch at vnsh.in
Tue Mar 31 04:22:20 AEDT 2026
Reject directory blocks smaller than one dirent, and validate the first
dirent nameoff against the bytes actually read rather than the block
size.
This avoids walking past valid data when the last directory block is
truncated in erofs_iterate_dir() or erofs_namei().
Signed-off-by: Vansh Choudhary <ch at vnsh.in>
---
lib/dir.c | 8 ++++++--
lib/namei.c | 8 ++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/lib/dir.c b/lib/dir.c
index 98edb8e..bf57849 100644
--- a/lib/dir.c
+++ b/lib/dir.c
@@ -172,9 +172,13 @@ int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck)
return err;
}
+ if (maxsize < sizeof(struct erofs_dirent)) {
+ erofs_err("too small dir block %llu @ nid %llu, lblk %llu",
+ maxsize | 0ULL, dir->nid | 0ULL, lblk | 0ULL);
+ return -EFSCORRUPTED;
+ }
nameoff = le16_to_cpu(de->nameoff);
- if (nameoff < sizeof(struct erofs_dirent) ||
- nameoff >= erofs_blksiz(sbi)) {
+ if (nameoff < sizeof(struct erofs_dirent) || nameoff >= maxsize) {
erofs_err("invalid de[0].nameoff %u @ nid %llu, lblk %llu",
nameoff, dir->nid | 0ULL, lblk | 0ULL);
return -EFSCORRUPTED;
diff --git a/lib/namei.c b/lib/namei.c
index 896e348..a4f68cb 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -247,9 +247,13 @@ int erofs_namei(struct nameidata *nd, const char *name, unsigned int len)
if (ret)
return ret;
+ if (maxsize < sizeof(struct erofs_dirent)) {
+ erofs_err("too small dir block %llu @ nid %llu",
+ maxsize | 0ULL, nid | 0ULL);
+ return -EFSCORRUPTED;
+ }
nameoff = le16_to_cpu(de->nameoff);
- if (nameoff < sizeof(struct erofs_dirent) ||
- nameoff >= erofs_blksiz(sbi)) {
+ if (nameoff < sizeof(struct erofs_dirent) || nameoff >= maxsize) {
erofs_err("invalid de[0].nameoff %u @ nid %llu",
nameoff, nid | 0ULL);
return -EFSCORRUPTED;
--
2.43.0
More information about the Linux-erofs
mailing list