From 0971365ee6f6638cbeec77db08fbdfe5f3bab53d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 13 Sep 2010 12:38:41 -0700 Subject: [PATCH] fts: use O_NOFOLLOW to avoid race condition when opening a directory * lib/fts.c (opendirat): New arg extra_flags. (__opendir2): Use it to avoid following symlinks when opening a directory, if symlinks are not supposed to be followed. See . --- ChangeLog | 6 ++++++ lib/fts.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d6d4c4fc..f2c83018f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2010-09-13 Paul Eggert + fts: use O_NOFOLLOW to avoid race condition when opening a directory + * lib/fts.c (opendirat): New arg extra_flags. + (__opendir2): Use it to avoid following symlinks when opening + a directory, if symlinks are not supposed to be followed. See + . + fdopendir: preserve argument fd before returning * lib/fdopendir.c: Adjust comments to say POSIX, not Solaris. (fdopendir_with_dup, fd_clone_opendir): New static functions. diff --git a/lib/fts.c b/lib/fts.c index 4b89ee780..1daf69c30 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -290,10 +290,11 @@ fts_set_stat_required (FTSENT *p, bool required) /* FIXME: if others need this function, move it into lib/openat.c */ static inline DIR * internal_function -opendirat (int fd, char const *dir) +opendirat (int fd, char const *dir, int extra_flags) { int new_fd = openat (fd, dir, - O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); + (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK + | extra_flags)); DIR *dirp; if (new_fd < 0) @@ -1237,7 +1238,11 @@ fts_build (register FTS *sp, int type) #else # define __opendir2(file, flag) \ ( ! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \ - ? opendirat(sp->fts_cwd_fd, file) \ + ? opendirat(sp->fts_cwd_fd, file, \ + ((ISSET(FTS_PHYSICAL) \ + && ! (cur->fts_level == FTS_ROOTLEVEL \ + && ISSET(FTS_COMFOLLOW))) \ + ? O_NOFOLLOW : 0)) \ : opendir(file)) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { -- 2.11.0