* [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 related [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 related [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 related [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
* 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
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