* [PATCH 0/3] tools/nolibc: verify that a directory is opened
@ 2026-08-31 16:04 Thomas Weißschuh
2026-08-31 16:04 ` [PATCH 1/3] " Thomas Weißschuh
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Thomas Weißschuh @ 2026-08-31 16:04 UTC (permalink / raw)
To: Willy Tarreau, Shuah Khan
Cc: linux-kernel, linux-kselftest, Thomas Weißschuh
If a non-directory is opened, ENODIR should be returned from
opendir()/fdopendir() right away and not only during readdir_r().
Validate the type of opened file during open.
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Thomas Weißschuh (3):
tools/nolibc: verify that a directory is opened
selftests/nolibc: validate ENOTDIR return values from opendir()/fdopendir()
tools/nolibc: validate directory with O_DIRECTORY in opendir()
tools/include/nolibc/dirent.h | 18 ++++++++++++++++--
tools/testing/selftests/nolibc/nolibc-test.c | 2 ++
2 files changed, 18 insertions(+), 2 deletions(-)
---
base-commit: 9c47af906bc655c8f45aaf1f156656239c2c5073
change-id: 20260831-nolibc-fdopendir-enotdir-3d7b39eedb51
Best regards,
--
Thomas Weißschuh <linux@weissschuh.net>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/3] tools/nolibc: verify that a directory is opened 2026-08-31 16:04 [PATCH 0/3] tools/nolibc: verify that a directory is opened Thomas Weißschuh @ 2026-08-31 16:04 ` Thomas Weißschuh 2026-08-31 16:05 ` [PATCH 2/3] selftests/nolibc: validate ENOTDIR return values from opendir()/fdopendir() Thomas Weißschuh ` (2 subsequent siblings) 3 siblings, 0 replies; 7+ messages in thread From: Thomas Weißschuh @ 2026-08-31 16:04 UTC (permalink / raw) To: Willy Tarreau, Shuah Khan Cc: linux-kernel, linux-kselftest, Thomas Weißschuh If a non-directory is opened, ENODIR should be returned from opendir()/fdopendir() right away and not only during readdir_r(). Validate the type of opened file during open. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> --- tools/include/nolibc/dirent.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h index 4e02ef25e72d..25fbff208998 100644 --- a/tools/include/nolibc/dirent.h +++ b/tools/include/nolibc/dirent.h @@ -30,10 +30,23 @@ typedef struct { static __attribute__((unused)) DIR *fdopendir(int fd) { + struct stat buf; + int ret; + if (fd < 0) { SET_ERRNO(EBADF); return NULL; } + + ret = fstat(fd, &buf); + if (ret < 0) + return NULL; + + if (!S_ISDIR(buf.st_mode)) { + SET_ERRNO(ENOTDIR); + return NULL; + } + return (DIR *)(intptr_t)~fd; } -- 2.55.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/3] selftests/nolibc: validate ENOTDIR return values from opendir()/fdopendir() 2026-08-31 16:04 [PATCH 0/3] tools/nolibc: verify that a directory is opened Thomas Weißschuh 2026-08-31 16:04 ` [PATCH 1/3] " Thomas Weißschuh @ 2026-08-31 16:05 ` Thomas Weißschuh 2026-08-31 16:05 ` [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() Thomas Weißschuh 2026-08-31 18:09 ` [PATCH 0/3] tools/nolibc: verify that a directory is opened Willy Tarreau 3 siblings, 0 replies; 7+ messages in thread From: Thomas Weißschuh @ 2026-08-31 16:05 UTC (permalink / raw) To: Willy Tarreau, Shuah Khan Cc: linux-kernel, linux-kselftest, Thomas Weißschuh Make sure that ENOTDIR is detected already during directory opening. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> --- tools/testing/selftests/nolibc/nolibc-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 0a8fe5100b7f..7091f63f3b25 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1711,6 +1711,7 @@ int run_syscall(int min, int max) CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = (char []){"/"}, [1] = NULL }, NULL), -1, EACCES); break; CASE_TEST(fchdir_stdin); EXPECT_SYSER(1, fchdir(STDIN_FILENO), -1, ENOTDIR); break; CASE_TEST(fchdir_badfd); EXPECT_SYSER(1, fchdir(-1), -1, EBADF); break; + CASE_TEST(fdopendir_notdir); EXPECT_SYSER(1, (uintptr_t)fdopendir(STDIN_FILENO), (uintptr_t)NULL, ENOTDIR); break; CASE_TEST(file_stream); EXPECT_SYSZR(1, test_file_stream()); break; CASE_TEST(file_stream_wsr); EXPECT_SYSZR(1, test_file_stream_wsr()); break; CASE_TEST(fork); EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break; @@ -1739,6 +1740,7 @@ int run_syscall(int min, int max) CASE_TEST(open_blah); EXPECT_SYSER(1, tmp = open("/proc/self/blah", O_RDONLY), -1, ENOENT); if (tmp != -1) close(tmp); break; CASE_TEST(openat_dir); EXPECT_SYSZR(1, test_openat()); break; CASE_TEST(open_mode); EXPECT_SYSZR(1, test_open_mode()); break; + CASE_TEST(opendir_notdir); EXPECT_SYSER(1, (uintptr_t)opendir("/dev/stdin"), (uintptr_t)NULL, ENOTDIR); break; CASE_TEST(pipe); EXPECT_SYSZR(1, test_pipe()); break; CASE_TEST(poll_null); EXPECT_SYSZR(1, poll(NULL, 0, 0)); break; CASE_TEST(poll_stdout); EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break; -- 2.55.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() 2026-08-31 16:04 [PATCH 0/3] tools/nolibc: verify that a directory is opened Thomas Weißschuh 2026-08-31 16:04 ` [PATCH 1/3] " Thomas Weißschuh 2026-08-31 16:05 ` [PATCH 2/3] selftests/nolibc: validate ENOTDIR return values from opendir()/fdopendir() Thomas Weißschuh @ 2026-08-31 16:05 ` Thomas Weißschuh 2026-09-01 8:51 ` David Laight 2026-08-31 18:09 ` [PATCH 0/3] tools/nolibc: verify that a directory is opened Willy Tarreau 3 siblings, 1 reply; 7+ messages in thread From: Thomas Weißschuh @ 2026-08-31 16:05 UTC (permalink / raw) To: Willy Tarreau, Shuah Khan Cc: linux-kernel, linux-kselftest, Thomas Weißschuh fdopendir() requires a call to fstat() to determine if the opened file is a directory. Currently opendir() inherits this extra syscall. Switch to O_DIRECTORY and remove the call to fdopendir() in opendir() to make the directory type check cheaper. Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> --- tools/include/nolibc/dirent.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h index 25fbff208998..2dbf4052b85a 100644 --- a/tools/include/nolibc/dirent.h +++ b/tools/include/nolibc/dirent.h @@ -55,10 +55,11 @@ DIR *opendir(const char *name) { int fd; - fd = open(name, O_RDONLY); + fd = open(name, O_RDONLY | O_DIRECTORY); if (fd == -1) return NULL; - return fdopendir(fd); + + return (DIR *)(intptr_t)~fd; } static __attribute__((unused)) -- 2.55.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() 2026-08-31 16:05 ` [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() Thomas Weißschuh @ 2026-09-01 8:51 ` David Laight 2026-09-01 18:54 ` Thomas Weißschuh 0 siblings, 1 reply; 7+ messages in thread From: David Laight @ 2026-09-01 8:51 UTC (permalink / raw) To: Thomas Weißschuh Cc: Willy Tarreau, Shuah Khan, linux-kernel, linux-kselftest On Mon, 31 Aug 2026 18:05:01 +0200 Thomas Weißschuh <linux@weissschuh.net> wrote: > fdopendir() requires a call to fstat() to determine if the opened file > is a directory. Currently opendir() inherits this extra syscall. > > Switch to O_DIRECTORY and remove the call to fdopendir() in opendir() > to make the directory type check cheaper. This should probably be the first patch. With the changed fdopendir() it leaks an fd on error. It also fixes the errno return. David > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> > --- > tools/include/nolibc/dirent.h | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h > index 25fbff208998..2dbf4052b85a 100644 > --- a/tools/include/nolibc/dirent.h > +++ b/tools/include/nolibc/dirent.h > @@ -55,10 +55,11 @@ DIR *opendir(const char *name) > { > int fd; > > - fd = open(name, O_RDONLY); > + fd = open(name, O_RDONLY | O_DIRECTORY); > if (fd == -1) > return NULL; > - return fdopendir(fd); > + > + return (DIR *)(intptr_t)~fd; > } > > static __attribute__((unused)) > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() 2026-09-01 8:51 ` David Laight @ 2026-09-01 18:54 ` Thomas Weißschuh 0 siblings, 0 replies; 7+ messages in thread From: Thomas Weißschuh @ 2026-09-01 18:54 UTC (permalink / raw) To: David Laight; +Cc: Willy Tarreau, Shuah Khan, linux-kernel, linux-kselftest On 2026-09-01 09:51:58+0100, David Laight wrote: > On Mon, 31 Aug 2026 18:05:01 +0200 > Thomas Weißschuh <linux@weissschuh.net> wrote: > > > fdopendir() requires a call to fstat() to determine if the opened file > > is a directory. Currently opendir() inherits this extra syscall. > > > > Switch to O_DIRECTORY and remove the call to fdopendir() in opendir() > > to make the directory type check cheaper. > > This should probably be the first patch. > With the changed fdopendir() it leaks an fd on error. > It also fixes the errno return. Good catch. If Willy doesn't object I'll shuffle the commits around. Thomas ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] tools/nolibc: verify that a directory is opened 2026-08-31 16:04 [PATCH 0/3] tools/nolibc: verify that a directory is opened Thomas Weißschuh ` (2 preceding siblings ...) 2026-08-31 16:05 ` [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() Thomas Weißschuh @ 2026-08-31 18:09 ` Willy Tarreau 3 siblings, 0 replies; 7+ messages in thread From: Willy Tarreau @ 2026-08-31 18:09 UTC (permalink / raw) To: Thomas Weißschuh; +Cc: Shuah Khan, linux-kernel, linux-kselftest Hi Thomas, On Mon, Aug 31, 2026 at 06:04:58PM +0200, Thomas Weißschuh wrote: > If a non-directory is opened, ENODIR should be returned from > opendir()/fdopendir() right away and not only during readdir_r(). > > Validate the type of opened file during open. Great points, I agree this is much cleaner this way! > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net> For the whole series: Reviewed-by: Willy Tarreau <w@1wt.eu> Thanks! Willy ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-01 18:55 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-08-31 16:04 [PATCH 0/3] tools/nolibc: verify that a directory is opened Thomas Weißschuh 2026-08-31 16:04 ` [PATCH 1/3] " Thomas Weißschuh 2026-08-31 16:05 ` [PATCH 2/3] selftests/nolibc: validate ENOTDIR return values from opendir()/fdopendir() Thomas Weißschuh 2026-08-31 16:05 ` [PATCH 3/3] tools/nolibc: validate directory with O_DIRECTORY in opendir() Thomas Weißschuh 2026-09-01 8:51 ` David Laight 2026-09-01 18:54 ` Thomas Weißschuh 2026-08-31 18:09 ` [PATCH 0/3] tools/nolibc: verify that a directory is opened Willy Tarreau
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®