[PATCH] jfs: bound readdir name expansion to the dirent page

From: Pengpeng Hou

Date: Tue Mar 24 2026 - 22:30:42 EST


jfs_readdir() checks the remaining dirent page space with d->namlen + 1
before calling jfs_strfromUCS_le(). That is too small once a codepage is
active, because each UCS-2 character can expand to up to
NLS_MAX_CHARSET_SIZE output bytes. The current check also starts from the
dirent base rather than the name field, so it does not account for the
dirent header bytes already consumed on the page.

Compute the worst-case number of output bytes for the directory name and
reject entries whose expanded name would run past the end of the
one-page dirent buffer before converting them.

Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
fs/jfs/jfs_dtree.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 9ab3f2fc61d1..aacfbe91b256 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2732,6 +2732,7 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
struct ldtentry *d;
struct dtslot *t;
int d_namleft, len, outlen;
+ size_t max_name_bytes;
unsigned long dirent_buf;
char *name_ptr;
u32 dir_index;
@@ -2913,8 +2914,12 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)

d = (struct ldtentry *) & p->slot[stbl[i]];

- if (((long) jfs_dirent + d->namlen + 1) >
- (dirent_buf + PAGE_SIZE)) {
+ max_name_bytes = d->namlen;
+ if (codepage)
+ max_name_bytes *= NLS_MAX_CHARSET_SIZE;
+
+ if ((char *)jfs_dirent->name + max_name_bytes + 1 >
+ (char *)dirent_buf + PAGE_SIZE) {
/* DBCS codepages could overrun dirent_buf */
index = i;
overflow = 1;
--
2.50.1 (Apple Git-155)