mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-16 15:11:52 +00:00
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
This commit is contained in:
parent
f2db8876a0
commit
90c68c1799
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178772
@ -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) {
|
||||
|
@ -98,7 +98,7 @@ _seekdir(dirp, loc)
|
||||
dirp->dd_seek = lp->loc_seek;
|
||||
dirp->dd_loc = 0;
|
||||
while (dirp->dd_loc < lp->loc_loc) {
|
||||
dp = _readdir_unlocked(dirp);
|
||||
dp = _readdir_unlocked(dirp, 0);
|
||||
if (dp == NULL)
|
||||
break;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ struct _telldir {
|
||||
long td_loccnt; /* index of entry for sequential readdir's */
|
||||
};
|
||||
|
||||
struct dirent *_readdir_unlocked(DIR *);
|
||||
struct dirent *_readdir_unlocked(DIR *, int);
|
||||
void _reclaim_telldir(DIR *);
|
||||
void _seekdir(DIR *, long);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user