From 67d6cd78dabd85ecc98c7569307ffb8738deceac Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Sat, 25 Jul 2026 20:24:24 -0700 Subject: [PATCH] Return EINVAL from getdents when the buffer is too small If the caller's buffer cannot hold even the first entry, the loop breaks and sys_getdents_common returns 0. Callers read 0 as end of directory, so a readdir() with a small buffer reports the directory as empty instead of failing. Linux returns EINVAL. Rewind to the entry that did not fit and return that instead; only the first iteration can be affected, since once something has been written a short count is correct. --- fs/dir.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/dir.c b/fs/dir.c index 4798bd1203..3f3247a37e 100644 --- a/fs/dir.c +++ b/fs/dir.c @@ -92,8 +92,15 @@ int_t sys_getdents_common(fd_t f, addr_t dirents, dword_t count, printed++; } - if (reclen > count) + if (reclen > count) { + if (count == orig_count) { + // If the buffer isn't large enough to read even a single dirent, + // reset the fd and return _EINVAL. + fd_seekdir(fd, ptr); + return _EINVAL; + } break; + } if (user_write(dirents, dirent_data, reclen)) return _EFAULT; dirents += reclen;