about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <p.stephenson@samsung.com>2019-04-25 17:08:43 +0100
committerPeter Stephenson <p.stephenson@samsung.com>2019-04-25 17:09:26 +0100
commitd4972af12c29bded4706464dbae3458e5a425d00 (patch)
treed6ab87fed9d007c6117d32f4160c8140b466a5bb /Src
parent39b0f5540c624f11d087632ae2d67a113d84a773 (diff)
downloadzsh-d4972af12c29bded4706464dbae3458e5a425d00.tar.gz
zsh-d4972af12c29bded4706464dbae3458e5a425d00.tar.xz
zsh-d4972af12c29bded4706464dbae3458e5a425d00.zip
44254: Handle error case in zgetdir().
When retrieving path to current directory by looking for /,
ensure we have actually reached / by comparing inode.
If the current directory became invalid on some OSes including
Linux the parent directory is valid but is the same as the
current one.
Diffstat (limited to 'Src')
-rw-r--r--Src/compat.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/Src/compat.c b/Src/compat.c
index 7b5c4411c..7131d91a4 100644
--- a/Src/compat.c
+++ b/Src/compat.c
@@ -361,8 +361,18 @@ zgetdir(struct dirsav *d)
 	pino = sbuf.st_ino;
 	pdev = sbuf.st_dev;
 
-	/* If they're the same, we've reached the root directory. */
+	/* If they're the same, we've reached the root directory... */
 	if (ino == pino && dev == pdev) {
+	    /*
+	     * ...well, probably.  If this was an orphaned . after
+	     * an unmount, or something such, we could be in trouble...
+	     */
+	    if (stat("/", &sbuf) < 0 ||
+		sbuf.st_ino != ino ||
+		sbuf.st_dev != dev) {
+		zerr("Failed to get current directory: path invalid");
+		return NULL;
+	    }
 	    if (!buf[pos])
 		buf[--pos] = '/';
 	    if (d) {