[PATCH 4/5] fs: ext4: reject dirents with too-small direntlen to prevent infinite loops

Sascha Hauer
2026-04-02T10:13:21Z

ext4fs_iterate_dir() and ext4fs_get_ino() walk directory entries using
dirent->direntlen from disk to advance the position. If a crafted
filesystem has direntlen == 0, the position never advances, causing an
infinite loop that can only be broken by a reset.

Reject directory entries where direntlen is smaller than the minimum
dirent struct size. This catches the zero case and also prevents
reading overlapping dirents.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
fs/ext4/ext4_common.c | 2 ++
fs/ext4/ext_barebox.c | 2 ++
2 files changed, 4 insertions(+)

diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 5d252b4a2c..b0c78f9e9a 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -359,6 +359,8 @@ int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,

free(fdiro);
}
+ if (le16_to_cpu(dirent.direntlen) < sizeof(struct ext2_dirent))
+ return -EINVAL;
fpos += le16_to_cpu(dirent.direntlen);
}
return -ENOENT;
diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c
index ef1a71368d..f9a978c10c 100644
--- a/fs/ext4/ext_barebox.c
+++ b/fs/ext4/ext_barebox.c
@@ -106,6 +106,8 @@ static int ext4fs_get_ino(struct ext2fs_node *dir, struct qstr *name, int *inum)
return 0;
}
}
+ if (le16_to_cpu(dirent.direntlen) < sizeof(struct ext2_dirent))
+ return -EINVAL;
fpos += le16_to_cpu(dirent.direntlen);
}

--
2.47.3