From 93785052e7a8c1ca5f263a39c3e77286f487e22d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 14 Sep 2010 09:03:55 -0700 Subject: [PATCH] fts, getcwd, glob: audit for dirfd returning -1 * lib/fts.c (opendir): Remove #define; no longer used. (opendirat): New arg PDIR_FD. All callers changed. (fts_build, _opendir2): Use new opendirat to avoid the need for dirfd, or for checking whether dirfd returns a negative value. Don't use opendir; always use openat followed by fdopendir. * lib/getcwd.c (__getcwd): Don't reset fd; fdopendir no longer clobbers it. * lib/glob.c (link_exists_p): Add comment explaining why dirfd never returns -1 here. * modules/fts (Depends-on): Remove dirfd. * modules/getcwd (Depends-on): Likewise. --- ChangeLog | 15 +++++++++++++++ lib/fts.c | 27 ++++++++++++++------------- lib/getcwd.c | 2 -- lib/glob.c | 2 ++ modules/fts | 1 - modules/getcwd | 1 - 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76fdacb1e..a9cb9769d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-09-13 Paul Eggert + + fts, getcwd, glob: audit for dirfd returning -1 + * lib/fts.c (opendir): Remove #define; no longer used. + (opendirat): New arg PDIR_FD. All callers changed. + (fts_build, _opendir2): Use new opendirat to avoid the need for + dirfd, or for checking whether dirfd returns a negative value. + Don't use opendir; always use openat followed by fdopendir. + * lib/getcwd.c (__getcwd): Don't reset fd; fdopendir no longer clobbers + it. + * lib/glob.c (link_exists_p): Add comment explaining why dirfd never + returns -1 here. + * modules/fts (Depends-on): Remove dirfd. + * modules/getcwd (Depends-on): Likewise. + 2010-09-13 Eric Blake float: fix broken MirBSD header diff --git a/lib/fts.c b/lib/fts.c index 1daf69c30..2c1e0ecdc 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -160,8 +160,6 @@ enum Fts_stat # define fchdir __fchdir # undef open # define open __open -# undef opendir -# define opendir __opendir # undef readdir # define readdir __readdir #else @@ -290,7 +288,7 @@ 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, int extra_flags) +opendirat (int fd, char const *dir, int extra_flags, int *pdir_fd) { int new_fd = openat (fd, dir, (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK @@ -301,7 +299,9 @@ opendirat (int fd, char const *dir, int extra_flags) return NULL; set_cloexec_flag (new_fd, true); dirp = fdopendir (new_fd); - if (dirp == NULL) + if (dirp) + *pdir_fd = new_fd; + else { int saved_errno = errno; close (new_fd); @@ -1222,6 +1222,7 @@ fts_build (register FTS *sp, int type) bool nostat; size_t len, maxlen, new_len; char *cp; + int dir_fd; /* Set current node pointer. */ cur = sp->fts_cur; @@ -1237,13 +1238,14 @@ fts_build (register FTS *sp, int type) oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND; #else # define __opendir2(file, flag) \ - ( ! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \ - ? opendirat(sp->fts_cwd_fd, file, \ - ((ISSET(FTS_PHYSICAL) \ - && ! (cur->fts_level == FTS_ROOTLEVEL \ - && ISSET(FTS_COMFOLLOW))) \ - ? O_NOFOLLOW : 0)) \ - : opendir(file)) + opendirat((! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \ + ? sp->fts_cwd_fd : AT_FDCWD), \ + file, \ + ((ISSET(FTS_PHYSICAL) \ + && ! (ISSET(FTS_COMFOLLOW) \ + && cur->fts_level == FTS_ROOTLEVEL)) \ + ? O_NOFOLLOW : 0), \ + &dir_fd) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { if (type == BREAD) { @@ -1306,8 +1308,7 @@ fts_build (register FTS *sp, int type) * checking FTS_NS on the returned nodes. */ if (nlinks || type == BREAD) { - int dir_fd = dirfd(dirp); - if (ISSET(FTS_CWDFD) && 0 <= dir_fd) + if (ISSET(FTS_CWDFD)) { dir_fd = dup (dir_fd); if (0 <= dir_fd) diff --git a/lib/getcwd.c b/lib/getcwd.c index 7d4707210..26e47f745 100644 --- a/lib/getcwd.c +++ b/lib/getcwd.c @@ -247,8 +247,6 @@ __getcwd (char *buf, size_t size) dirstream = fdopendir (fd); if (dirstream == NULL) goto lose; - /* Reset fd. It may have been closed by fdopendir. */ - fd = dirfd (dirstream); fd_needs_closing = false; #else dirstream = __opendir (dotlist); diff --git a/lib/glob.c b/lib/glob.c index 03b55df28..5be8c3211 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -1282,6 +1282,8 @@ link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname, return link_exists2_p (dir, dirlen, fname, pglob); else { + /* dfd cannot be -1 here, because dirfd never returns -1 on + glibc, or on hosts that have fstatat. */ struct_stat64 st64; return __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; } diff --git a/modules/fts b/modules/fts index ba8cd573a..0414ea108 100644 --- a/modules/fts +++ b/modules/fts @@ -13,7 +13,6 @@ cycle-check d-ino d-type dirent-safer -dirfd fchdir fcntl-h fcntl-safer diff --git a/modules/getcwd b/modules/getcwd index c1544f5e5..108f14b28 100644 --- a/modules/getcwd +++ b/modules/getcwd @@ -10,7 +10,6 @@ m4/getcwd.m4 Depends-on: mempcpy d-ino -dirfd extensions memmove openat -- 2.11.0