diff options
author | Florian Weimer <fweimer@redhat.com> | 2024-09-21 19:32:34 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2024-09-21 19:32:34 +0200 |
commit | 6f3f6c506cdaf981a4374f1f12863b98ac7fea1a (patch) | |
tree | f720b5128e51ba81e28ac31da1e5f642d8e35a0b /sysdeps | |
parent | 6aa1645f669322b36bda8e1fded6fd524d3e08ff (diff) | |
download | glibc-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.c | 29 |
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) { |