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 <gluca86@gmail.com>