[Bug libc/23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
patrickdepinguin at gmail dot com
sourceware-bugzilla@sourceware.org
Thu Dec 20 13:53:00 GMT 2018
https://sourceware.org/bugzilla/show_bug.cgi?id=23497
--- Comment #11 from Thomas De Schampheleire <patrickdepinguin at gmail dot com> ---
What I specifically see is that a readdir does not return entries when
accessing the 9p filesystem inside Qemu, with a CentOS 7 host. With following
simple test program:
#include <dirent.h>
#include <stdio.h>
void readonce(DIR *dirp)
{
struct dirent *d;
d = readdir(dirp);
if (d == NULL) {
printf("no more entries\n");
return;
}
printf("d_name: %s\n", d->d_name);
printf("d_ino: %lx\n", d->d_ino);
printf("d_off: %lx\n", d->d_off);
printf("d_reclen: %x\n", d->d_reclen);
printf("d_type: %x\n", d->d_type);
printf("\n");
}
int main(int argc, char *argv[])
{
DIR *dirp = opendir(argv[1]);
for (int i = 0; i < 6 ; i++) {
readonce(dirp);
}
}
Output under strace shows multiple calls to getdents64 when accessing the 9p
filesystem:
openat(AT_FDCWD, "/foo", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)
= 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
brk(NULL) = 0x90ad000
brk(0x90ce000) = 0x90ce000
brk(0x90cf000) = 0x90cf000
getdents64(3, /* 30 entries */, 32768) = 944
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 65), ...}) = 0
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "no more entries\n", 16no more entries
) = 16
getdents64(3, /* 0 entries */, 32768) = 0
write(1, "no more entries\n", 16no more entries
) = 16
getdents64(3, /* 0 entries */, 32768) = 0
write(1, "no more entries\n", 16no more entries
) = 16
getdents64(3, /* 0 entries */, 32768) = 0
write(1, "no more entries\n", 16no more entries
) = 16
getdents64(3, /* 0 entries */, 32768) = 0
write(1, "no more entries\n", 16no more entries
) = 16
getdents64(3, /* 0 entries */, 32768) = 0
write(1, "no more entries\n", 16no more entries
) = 16
while there is only one getdents64 call when accessing a local filesystem like
/tmp:
openat(AT_FDCWD, "/tmp", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC)
= 3
fstat64(3, {st_mode=S_IFDIR|S_ISVTX|0777, st_size=160, ...}) = 0
brk(NULL) = 0x8939000
brk(0x895a000) = 0x895a000
brk(0x895b000) = 0x895b000
getdents64(3, /* 8 entries */, 32768) = 256
fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 65), ...}) = 0
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
write(1, "d_name: .\n", 10d_name: .
) = 10
write(1, "d_ino: 12f8\n", 12d_ino: 12f8
) = 12
write(1, "d_off: 1\n", 9d_off: 1
) = 9
write(1, "d_reclen: 10\n", 13d_reclen: 10
) = 13
write(1, "d_type: 4\n", 10d_type: 4
) = 10
write(1, "\n", 1
) = 1
write(1, "d_name: ..\n", 11d_name: ..
) = 11
write(1, "d_ino: 12f8\n", 12d_ino: 12f8
) = 12
write(1, "d_off: 2\n", 9d_off: 2
) = 9
write(1, "d_reclen: 10\n", 13d_reclen: 10
) = 13
write(1, "d_type: 4\n", 10d_type: 4
) = 10
write(1, "\n", 1
) = 1
...
Using the same target software and same qemu version on another host machine
(which is a more modern Gentoo system with kernel 4.14.x, rather than the old
CentOS 7 with kernel 3.10), I see no issues on either type of filesystem.
I have yet to try it myself, but do you still think that the fix for this bug
(#23497) is not the solution here?
The other bug #23960 refers to sigaction changes but I fail to see how they
relate to the reproducer above.
If I should open a new bug, please let me know.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Glibc-bugs
mailing list