From 61a665e95e2e51a0cfedc161b5153fef5eae6c5e Mon Sep 17 00:00:00 2001 From: AlmAck Date: Sat, 29 Aug 2026 19:02:15 +0200 Subject: [PATCH] fs/inode: bound fdlist_extend() against the requested row fdlist_extend() grows a task group's descriptor table to 'row' rows of CONFIG_NFILE_DESCRIPTORS_PER_BLOCK entries each, and guards the growth against OPEN_MAX: if (CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * (orig_rows + 1) > OPEN_MAX) The check sizes the table at orig_rows + 1, which assumes the caller only ever grows by a single block. The function then allocates 'row' rows, so the two agree only for growth by one. Callers do skip ahead. fdlist_dup3() asks for fd2 / CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + 1, fdlist_dupfile() for the row holding minfd, and fdlist_copy() for the row holding a parent descriptor it is duplicating. Any of those can request a row well past orig_rows + 1. Such a request passes the check and the function then allocates and installs a table with more than OPEN_MAX descriptors. With the defaults (8 per block, OPEN_MAX 256) a process holding one row that calls dup2(fd, 400) ends up with 51 rows, or 408 descriptor slots, against a 256 limit. Check the row actually being requested. For single-block growth row == orig_rows + 1 and the comparison is unchanged. Signed-off-by: AlmAck --- fs/inode/fs_files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/inode/fs_files.c b/fs/inode/fs_files.c index b039051bb7359..6407f0eb9bd30 100644 --- a/fs/inode/fs_files.c +++ b/fs/inode/fs_files.c @@ -104,7 +104,7 @@ static int fdlist_extend(FAR struct fdlist *list, size_t row) return 0; } - if (CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * (orig_rows + 1) > OPEN_MAX) + if (CONFIG_NFILE_DESCRIPTORS_PER_BLOCK * row > OPEN_MAX) { fdlist_dump(list); return -EMFILE;