On 2024-12-04 09:10, Ioanna Alifieraki wrote:
When ls -la is run on NFS shares, get_aclinfo() in gnulib is eventually
invoked. This calls listxattr, which, as expected, returns -1 and sets
errno when the user lacks permissions for a directory.

That's not what I expect, any more than I'd expect 'stat' to fail on the directory. A directory's permissions should affect only accesses to its data, not to its metadata.

Do you observe similar problems on file systems other than NFS? If not, this sounds like an NFS bug. Possibly coreutils should work around the bug, but first it'd be helpful to know exactly how the bug works. For example, what permissions does NFS require on a directory before it allows listxattr to succeed? What platform are you running (OS, version, etc.)?

I could not reproduce the problem on a non-NFS file system with bleeding-edge coreutils (commit fd01fc8075a0df4e9036fdb962b589e60c134e26) on Fedora 40 x86-64. I tried on ext4 as follows:

  mkdir d d/e
  setfacl -m u:root:r d/e
  chmod 0 d/e
  LC_ALL=C strace -o tr ls -la d

This worked as expected, producing this output:

  total 32
  drwxrwxr-x.  3 eggert eggert  4096 Dec  5 13:47 .
  drwxr-xr-x. 10 eggert eggert 20480 Dec  5 13:47 ..
  d---------+  2 eggert eggert  4096 Dec  5 13:47 e

with no diagnostics. Inspecting the 'tr' file, I found the following. Notice that the call listxattr("d/e", ...) succeeds even though I lack all permissions to d/e. Could you try something similar on your platform?

...
openat(AT_FDCWD, "d", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
getdents64(3, 0x5621e6b8a740 /* 3 entries */, 32768) = 72
statx(AT_FDCWD, "d/e", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|000, stx_size=4096, ...}) = 0 lgetxattr("d/e", "security.selinux", "unconfined_u:object_r:user_home_"..., 255) = 37
listxattr("d/e", "security.selinux\0system.posix_ac"..., 152) = 41
statx(AT_FDCWD, "d/..", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0755, stx_size=20480, ...}) = 0 lgetxattr("d/..", "security.selinux", "unconfined_u:object_r:user_home_"..., 255) = 37
listxattr("d/..", "security.selinux\0", 152) = 17
statx(AT_FDCWD, "d/.", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_MODE|STATX_NLINK|STATX_UID|STATX_GID|STATX_MTIME|STATX_SIZE, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=4096, ...}) = 0 lgetxattr("d/.", "security.selinux", "unconfined_u:object_r:user_home_"..., 255) = 37
listxattr("d/.", "security.selinux\0", 152) = 17
getdents64(3, 0x5621e6b8a740 /* 0 entries */, 32768) = 0
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x1), ...}) = 0
write(1, "total 32\n", 9)               = 9
...



Reply via email to