[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fts: slightly more robust
From: |
Eric Blake |
Subject: |
Re: fts: slightly more robust |
Date: |
Wed, 2 Sep 2009 14:14:33 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Jim Meyering <jim <at> meyering.net> writes:
> > While we're visiting fts, how about this patch? POSIX 2008 is clear that
> > opendir should use O_DIRECTORY, so opendirat should probably do likewise.
>
> There is no need for O_DIRECTORY in that function, since the only thing
> it does with the resulting file descriptor is to apply fdopendir, and
> fdopendir will fail with ENOTDIR when fd refers to a non-directory.
Yes, fdopendir will reject non-directories, but the point of using O_DIRECTORY
up front is to avoid blocking on a FIFO prior to reaching the fdopendir.
>
> > Do we want to obey the FIXME and make opendirat an independent module?
>
> Sure, if there is another user.
> Is there?
Not so far, so I won't bother.
> > O_DIRECTORY|O_NOFOLLOW on
> > a symlink must produce failure, although POSIX is ambiguous whether the
failure
> > will be ELOOP or ENOTDIR)
I stand corrected. The POSIX wording is that O_DIRECTORY fails if "path does
not name a directory", but elsewhere in POSIX, that same phrase applies to
symlinks that point to directories. In other words:
open("link-to-dir",O_RDONLY|O_DIRECTORY) -> passes
open("link-to-file",O_RDONLY|O_DIRECTORY) -> fails with ENOTDIR
open("link-to-dir",O_RDONLY|O_DIRECTORY|O_NOFOLLOW) -> fails with ELOOP
open("link-to-file",O_RDONLY|O_DIRECTORY|O_NOFOLLOW) -> fails with either ELOOP
or ENOTDIR
> You might as well add all four,
> O_DIRECTORY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW
> on the off-chance that O_DIRECTORY makes the earlier openat
> fail, and it fails with a more useful errno value than fdopendir.
So blindly adding O_NOFOLLOW for opendirat is wrong.
Here's the latest draft of my patch.
>From 0145db62dc0f4fc77ed98119e40d256d95aa21cb Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 1 Sep 2009 14:06:37 -0600
Subject: [PATCH] fts: make directory fds more robust
* lib/fts.c (O_DIRECTORY): Let <fcntl.h> take care of this.
(opendirat): Specify O_DIRECTORY, and add fallbacks for safety.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 6 ++++++
lib/fts.c | 7 ++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ee81a23..58decf8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2009-09-02 Eric Blake <address@hidden>
+ fts: make directory fds more robust
+ * lib/fts.c (O_DIRECTORY): Let <fcntl.h> take care of this.
+ (opendirat): Specify O_DIRECTORY, and add fallbacks for safety.
+
+2009-09-02 Eric Blake <address@hidden>
+
backupfile, chdir-long, fts, savedir: make safer
* lib/backupfile.c (includes): Use "dirent--.h", since
numbered_backup can write to stderr during readdir.
diff --git a/lib/fts.c b/lib/fts.c
index 7616c6f..ebf66fc 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -228,10 +228,6 @@ static void free_dir (FTS *fts) {}
# define SIZE_MAX ((size_t) -1)
#endif
-#ifndef O_DIRECTORY
-# define O_DIRECTORY 0
-#endif
-
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
#define STREQ(a, b) (strcmp ((a), (b)) == 0)
@@ -309,7 +305,8 @@ static inline DIR *
internal_function
opendirat (int fd, char const *dir)
{
- int new_fd = openat (fd, dir, O_RDONLY);
+ int new_fd = openat (fd, dir,
+ O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
DIR *dirp;
if (new_fd < 0)
--
1.6.3.2