bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] ls: don't use an undefined struct stat after failed stat/lstat


From: Jim Meyering
Subject: [PATCH] ls: don't use an undefined struct stat after failed stat/lstat
Date: Tue, 29 Sep 2009 11:40:03 +0200

Nearly missed this one.
ls initializes a struct stat to all NUL bytes.
It calls stat or lstat on a dangling symlink, and that fails.
ls then tests stat.st_ino.

Sometimes, it's 0, but sometimes it's the inode of the symlink,
possibly depending on how the package was configured/built or
the environment.
I haven't determined precisely what makes the difference,
but ls (from coreutils-7.6) built some way prints 0 as the inode
number, and other ways, it prints the inode of the dangling symlink.


>From f7db178fdff1ebb113841035b55b103e074b5f6f Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Tue, 29 Sep 2009 07:28:01 +0200
Subject: [PATCH] ls: don't use an undefined struct stat after failed stat/lstat

* src/ls.c (gobble_file): After a failed stat/lstat call,
clear the f->stat buffer, since the syscall may have modified it,
and we may need to know that stat.st_ino is zero.
* NEWS (Bug fixes): Mention it.
---
 NEWS     |    4 ++++
 src/ls.c |    6 ++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/NEWS b/NEWS
index 1a0c847..d5270c8 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,10 @@ GNU coreutils NEWS                                    -*- 
outline -*-
     ls: cannot access d/s: No such file or directory
     ? s

+  ls -Li no longer relies on unspecified behavior of stat/lstat.
+  Before this change, "ls -Li dangling-symlink" would mistakenly
+  print the inode number of the symlink under some conditions.
+
 ** Portability

   On Solaris 9, many commands would mistakenly treat file/ the same as
diff --git a/src/ls.c b/src/ls.c
index c8e8abb..dc2f86e 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -2777,6 +2777,12 @@ gobble_file (char const *name, enum filetype type, ino_t 
inode,

       if (err != 0)
         {
+          /* The failed stat/lstat may have modified f->stat.  Clear it,
+             since we may use at least its st_ino member, e.g.,
+             when trying to print the inode of dangling symlink:
+             mkdir d; ln -s no-such d/s; ls -Li d  */
+          memset (&f->stat, 0, sizeof (f->stat));
+
           /* Failure to stat a command line argument leads to
              an exit status of 2.  For other files, stat failure
              provokes an exit status of 1.  */
--
1.6.5.rc2.177.ga9dd6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]