]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
ls: fix crash with --context
authorPádraig Brady <P@draigBrady.com>
Fri, 17 Jan 2025 17:29:34 +0000 (17:29 +0000)
committerPádraig Brady <P@draigBrady.com>
Sat, 18 Jan 2025 13:14:29 +0000 (13:14 +0000)
* src/ls.c (main): Flag that we need to stat()
if we're going to get security context (call file_has_aclinfo_cache).
(file_has_aclinfo_cache): Be defensive and only lookup the device
for the file if the stat has been performed.
(has_capability_cache): Likewise.
* tests/ls/selinux-segfault.sh: Add a test case.
* NEWS: Mention the bug fix.
Reported by Bruno Haible.

NEWS
src/ls.c
tests/ls/selinux-segfault.sh

diff --git a/NEWS b/NEWS
index 9be61e4c430f4404e65e0e22994fd72e213b0460..c9ba5f1965cd90435fda8133095f01ad5eb25f0d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes
+
+  `ls -Z dir` would crash.
+  [bug introduced in coreutils-9.6]
+
 
 * Noteworthy changes in release 9.6 (2025-01-17) [stable]
 
index 3215360216910125de73f265a2b4ea56ad3c2caa..f67167f1602dbcfefc7662f1c8352108d2703bc9 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -1768,7 +1768,7 @@ main (int argc, char **argv)
 
   format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size)
                        | (format == long_format)
-                       | print_block_size | print_hyperlink);
+                       | print_block_size | print_hyperlink | print_scontext);
   format_needs_type = ((! format_needs_stat)
                        & (recursive | print_with_color | print_scontext
                           | directories_first
@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f,
   static int unsupported_scontext_err;
   static dev_t unsupported_device;
 
-  if (f->stat.st_dev == unsupported_device)
+  if (f->stat_ok && f->stat.st_dev == unsupported_device)
     {
       ai->buf = ai->u.__gl_acl_ch;
       ai->size = 0;
@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f,
   errno = 0;
   int n = file_has_aclinfo (file, ai, flags);
   int err = errno;
-  if (n <= 0 && !acl_errno_valid (err))
+  if (f->stat_ok && n <= 0 && !acl_errno_valid (err))
     {
       unsupported_return = n;
       unsupported_scontext = ai->scontext;
@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f)
      found that has_capability fails indicating lack of support.  */
   static dev_t unsupported_device;
 
-  if (f->stat.st_dev == unsupported_device)
+  if (f->stat_ok && f->stat.st_dev == unsupported_device)
     {
       errno = ENOTSUP;
       return 0;
     }
 
   bool b = has_capability (file);
-  if ( !b && !acl_errno_valid (errno))
+  if (f->stat_ok && !b && !acl_errno_valid (errno))
     unsupported_device = f->stat.st_dev;
   return b;
 }
index 11623acb3fe692b38013f442c03fa2083a99d4f4..1cac2b5fc0cae66bc3584e5860f8a3b44d1483a2 100755 (executable)
@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_
 ln -sf missing sedir/broken || framework_failure_
 returns_ 1 ls -L -R -Z -m sedir > out || fail=1
 
+# ls 9.6 would segfault with the following
+ls -Z . > out || fail=1
+
 Exit $fail