ls: fix missing ACL indicators or capability colors

On systems where the security context reports as unsupported,
and we encountered a file without ACLs, no further lookups
would be performed.  Introduced in commit v9.5-156-gb857d66b5.
This fix is along similar lines as commit v9.6-40-gcb2abbac7.

* src/ls.c (file_has_aclinfo_cache): Don't mark file system as
unsupported if there might be ACLs or capabilities present.
* tests/ls/acl-cache.sh: Add a new test.
* tests/local.mk: Reference the new test.
* tests/ls/acl.sh: Add a check.
* NEWS: Mention the bug fix.
This commit is contained in:
Pádraig Brady committed 2026-10-13 11:32:41 +01:00
1 parent 19cc2bad3c
commit 402bce6637
5 files changed
+69

No files matched your search

+5
View File
@@ -18,6 +18,11 @@ GNU coreutils NEWS -*- outline -*-
after a tab character are accounted for correctly.
[bugs introduced in coreutils-9.8]
'ls' no longer omits ACL indicators or capability coloring for subsequent
files on the same file system after an unsupported security context
lookup on a file without an ACL.
[bug introduced in coreutils-9.6]
'realpath' without -s, or 'readlink' with -e,-f,-m no longer
loop infinitely when resolving a symbolic link which
resolves to a path beginning with the symbolic link itself.
+3
View File
@@ -3255,7 +3255,10 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f,
errno = 0;
int n = file_has_aclinfo (file, ai, flags);
int err = errno;
/* A security-context error does not imply that ACLs are unsupported.
Require an unsupported attribute listing too. */
if (f->stat_ok && n <= 0 && !acl_errno_valid (err)
&& ai->size < 0 && !acl_errno_valid (ai->u.err)
&& (!(flags & ACL_GET_SCONTEXT) || !acl_errno_valid (ai->scontext_err)))
{
unsupported_return = n;
+1
View File
@@ -716,6 +716,7 @@ all_tests = \
tests/ln/target-1.sh \
tests/ls/a-option.sh \
tests/ls/acl.sh \
tests/ls/acl-cache.sh \
tests/ls/abmon-align.sh \
tests/ls/birthtime.sh \
tests/ls/block-size.sh \
+55
View File
@@ -0,0 +1,55 @@
#!/bin/sh
# A failed security-context lookup must not disable ACL detection.
# This failed from v9.6 to v9.12 inclusive.
# Copyright (C) 2026 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ ls
require_strace_ getxattr,listxattr
require_setfacl_
grep '^#define USE_ACL 1' $CONFIG_HEADER > /dev/null ||
skip_ 'insufficient ACL support'
touch acl plain || framework_failure_
uid=$(id -u) || framework_failure_
setfacl -m "u:$uid:rw" acl && setfacl -b plain || framework_failure_
ls -l acl > exp || framework_failure_
grep '^..........+' exp > /dev/null || skip_ 'ls does not report ACLs'
# Require injection to affect only the selected path.
strace --quiet=all -o /dev/null -P plain \
-e fault=listxattr,llistxattr:error=EIO ls -l acl > out 2> err &&
compare exp out || skip_ 'strace does not support path-filtered injection'
# Ensure a failed getxattr doesn't induce failure to lookup ACLs.
# Also check the fallback when listxattr fails with E2BIG.
for list_fault in '' '-e fault=listxattr,llistxattr:error=E2BIG'; do
strace --quiet=all -o trace -P plain \
-e trace=listxattr,llistxattr,getxattr,lgetxattr \
-e fault=getxattr,lgetxattr:error=EOPNOTSUPP \
$list_fault ls -l acl plain acl > out 2> err || fail=1
test "$DEBUG" && cat trace
compare /dev/null err || fail=1
test "$(grep -c '^..........+' out)" = 2 || fail=1
done
grep ' (INJECTED)' trace > /dev/null ||
skip_ 'strace did not inject the requested failure'
Exit $fail
+5
View File
@@ -52,4 +52,9 @@ gap1=$(ls -l pad/f1 | sed -n 's/^[^+]*+\( *\)[0-9].*/\1/p')
gap5=$(ls -l pad | sed -n 's/^[^+]*+\( *\)[0-9].*/\1/p' | head -n1)
test "x$gap1" = "x$gap5" || fail=1
# A file without an ACL must not suppress ACLs on subsequent files.
touch pad/plain && setfacl -b pad/plain || framework_failure_
ls -l pad/f1 pad/plain pad/f1 > out || fail=1
test "$(grep -c '^..........+' out)" = 2 || fail=1
Exit $fail