aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2024-09-21 19:32:34 +0200
committerFlorian Weimer <fweimer@redhat.com>2024-09-21 19:32:34 +0200
commit6f3f6c506cdaf981a4374f1f12863b98ac7fea1a (patch)
treef720b5128e51ba81e28ac31da1e5f642d8e35a0b /sysdeps
parent6aa1645f669322b36bda8e1fded6fd524d3e08ff (diff)
downloadglibc-6f3f6c506cdaf981a4374f1f12863b98ac7fea1a.zip
glibc-6f3f6c506cdaf981a4374f1f12863b98ac7fea1a.tar.gz
glibc-6f3f6c506cdaf981a4374f1f12863b98ac7fea1a.tar.bz2
Linux: readdir64_r should not skip d_ino == 0 entries (bug 32126)
This is the same bug as bug 12165, but for readdir_r. The regression test covers both bug 12165 and bug 32126. Reviewed-by: DJ Delorie <dj@redhat.com>
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/readdir64_r.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c
index 7ad7e59..c42a161 100644
--- a/sysdeps/unix/sysv/linux/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/readdir64_r.c
@@ -37,7 +37,7 @@ __readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
__libc_lock_lock (dirp->lock);
- do
+ while (1)
{
if (dirp->offset >= dirp->size)
{
@@ -79,26 +79,21 @@ __readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result)
dirp->filepos = dp->d_off;
- if (reclen > offsetof (struct dirent64, d_name) + NAME_MAX + 1)
+ if (reclen <= offsetof (struct dirent64, d_name) + NAME_MAX + 1)
+ break;
+
+ /* The record is very long. It could still fit into the
+ caller-supplied buffer if we can skip padding at the end. */
+ size_t namelen = _D_EXACT_NAMLEN (dp);
+ if (namelen <= NAME_MAX)
{
- /* The record is very long. It could still fit into the
- caller-supplied buffer if we can skip padding at the
- end. */
- size_t namelen = _D_EXACT_NAMLEN (dp);
- if (namelen <= NAME_MAX)
- reclen = offsetof (struct dirent64, d_name) + namelen + 1;
- else
- {
- /* The name is too long. Ignore this file. */
- dirp->errcode = ENAMETOOLONG;
- dp->d_ino = 0;
- continue;
- }
+ reclen = offsetof (struct dirent64, d_name) + namelen + 1;
+ break;
}
- /* Skip deleted and ignored files. */
+ /* The name is too long. Ignore this file. */
+ dirp->errcode = ENAMETOOLONG;
}
- while (dp->d_ino == 0);
if (dp != NULL)
{