All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.