[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 287451] [/bin/ls] readdir() errors delivered via fts_children() are silently discarded"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 11 Jun 2025 15:32:51 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287451
Bug ID: 287451
Summary: [/bin/ls] readdir() errors delivered via
fts_children() are silently discarded
Product: Base System
Version: 15.0-CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: bin
Assignee: bugs@FreeBSD.org
Reporter: no.spam.c@mail.ru
Hello.
# Problem
When running the 'ls' command against an unreadable directory, its exit code is
zero, and no read error is printed.
Example:
root@testhost:~ # mount | grep -F /mnt
/dev/da1p1.eli on /mnt (ufs, local, soft-updates)
root@testhost:~ # ls /mnt
.snap test test2
root@testhost:~ # ls /mnt/test2
1.txt
root@testhost:~ # ls /mnt/test
root@testhost:~ # echo $?
0
root@testhost:~ # truss ls -l /mnt/test/ 2>&1 | tail
fstat(4,{ mode=drwxr-xr-x ,inode=98304,size=26624,blksize=32768 }) = 0 (0x0)
fchdir(0x4) = 0 (0x0)
getdirentries(4,0x5743bd843000,4096,0x5743bd840028) ERR#97 'Integrity check
failed'
close(4) = 0 (0x0)
fchdir(0x3) = 0 (0x0)
fstat(1,{ mode=p--------- ,inode=708,size=0,blksize=4096 }) = 0 (0x0)
total 0
write(1,"total 0\n",8) = 8 (0x8)
exit(0x0)
process exit, rval = 0
root@testhost:~ #
Compare this to the 'find' command (which reports the error properly):
root@testhost:~ # find /mnt/
/mnt/
/mnt/.snap
/mnt/test
find: /mnt/test: Integrity check failed
/mnt/test2
/mnt/test2/1.txt
root@testhost:~ # echo $?
1
root@testhost:~ #
# Root cause
The bug is in 'bin/ls/ls.c':
static void
traverse(int argc, char *argv[], int options)
{
FTS *ftsp;
FTSENT *p, *chp;
int ch_options;
if ((ftsp =
fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
err(1, "fts_open");
[...]
chp = fts_children(ftsp, 0);
if (chp != NULL)
display(NULL, chp, options);
if (f_listdir) {
fts_close(ftsp);
return;
}
[...]
while (errno = 0, (p = fts_read(ftsp)) != NULL)
switch (p->fts_info) {
case FTS_DC:
[...]
break;
case FTS_DNR:
case FTS_ERR:
[...]
break;
case FTS_D:
if (p->fts_level != FTS_ROOTLEVEL &&
p->fts_name[0] == '.' && !f_listdot)
break;
[...]
chp = fts_children(ftsp, ch_options); // BUG!
display(p, chp, options);
[...]
break;
default:
break;
}
if (errno) // 'errno' is 0 after the loop!
err(1, "fts_read");
fts_close(ftsp);
}
The second call to 'fts_children()' returns NULL and 'errno' is set to a
non-zero value, but it's not checked in the code.
Subsequent calls (i.e., to 'fts_read()' in the while loop) reset the 'errno'
value, so it becomes zero after the loop.
--
You are receiving this mail because:
You are the assignee for the bug.