Linux Kernel Selftest development
 help / color / mirror / Atom feed
* [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