From c697e6f360e231d276258ea22e73c4085eba3af9 Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 5 May 2008 14:05:23 +0000 Subject: Do not read away the target directory entry when encountering deleted files after a seekdir(). The seekdir shall set the position for the next readdir operation. When the _readdir_unlocked() encounters deleted entry, dd_loc is already advanced. Continuing the loop leads to premature read of the target entry. Submitted by: Marc Balmer Obtained from: OpenBSD MFC after: 2 weeks --- lib/libc/gen/readdir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'lib/libc/gen/readdir.c') diff --git a/lib/libc/gen/readdir.c b/lib/libc/gen/readdir.c index fd52067..b4b4c39 100644 --- a/lib/libc/gen/readdir.c +++ b/lib/libc/gen/readdir.c @@ -48,8 +48,9 @@ __FBSDID("$FreeBSD$"); * get next entry in a directory. */ struct dirent * -_readdir_unlocked(dirp) +_readdir_unlocked(dirp, skip) DIR *dirp; + int skip; { struct dirent *dp; @@ -72,7 +73,7 @@ _readdir_unlocked(dirp) dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) return (NULL); dirp->dd_loc += dp->d_reclen; - if (dp->d_ino == 0) + if (dp->d_ino == 0 && skip) continue; if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) continue; @@ -88,11 +89,11 @@ readdir(dirp) if (__isthreaded) { _pthread_mutex_lock(&dirp->dd_lock); - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 1); _pthread_mutex_unlock(&dirp->dd_lock); } else - dp = _readdir_unlocked(dirp); + dp = _readdir_unlocked(dirp, 1); return (dp); } @@ -109,11 +110,11 @@ readdir_r(dirp, entry, result) errno = 0; if (__isthreaded) { _pthread_mutex_lock(&dirp->dd_lock); - if ((dp = _readdir_unlocked(dirp)) != NULL) + if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); _pthread_mutex_unlock(&dirp->dd_lock); } - else if ((dp = _readdir_unlocked(dirp)) != NULL) + else if ((dp = _readdir_unlocked(dirp, 1)) != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); if (errno != 0) { -- cgit v1.1