summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/readdir.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-05-05 14:05:23 +0000
committerkib <kib@FreeBSD.org>2008-05-05 14:05:23 +0000
commitc697e6f360e231d276258ea22e73c4085eba3af9 (patch)
treee3620d7f991edaa6b2b475aa8d2dae909d6e29ec /lib/libc/gen/readdir.c
parent420af22bc1279dd3fef45a8fd4e575afb086e937 (diff)
downloadFreeBSD-src-c697e6f360e231d276258ea22e73c4085eba3af9.zip
FreeBSD-src-c697e6f360e231d276258ea22e73c4085eba3af9.tar.gz
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 <mbalmer at openbsd org> Obtained from: OpenBSD MFC after: 2 weeks
Diffstat (limited to 'lib/libc/gen/readdir.c')
-rw-r--r--lib/libc/gen/readdir.c13
1 files changed, 7 insertions, 6 deletions
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) {
OpenPOWER on IntegriCloud