zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.stephenson@samsung.com>
To: <zsh-workers@zsh.org>
Subject: Re: cwd unintentionally changed
Date: Thu, 25 Apr 2019 14:31:08 +0100	[thread overview]
Message-ID: <1556199068.2667.13.camel@samsung.com> (raw)
In-Reply-To: <f6d8b44f-84be-0102-5ab8-b56824e23f87@ibr.cs.tu-bs.de>

On Thu, 2019-04-25 at 14:03 +0200, Yannic Schröder wrote:
> Hi *,
> 
> I got myself into a situation where zsh changed my working directory to
> "/" without further notice. Unfortunately, the next command I issued was
> "sudo rm -rf *", which did not end well with cwd being "/" :-(
> 
> My colleagues and me started to track down the bug. Our efforts are
> documented here:
> https://github.com/grml/grml-etc-core/issues/76
> 
> (We initially though it was a bug with grml zsh config.)
> 
> A minimal example that triggers the bug looks like this:
> 
> $ mkdir /tmp/tmp.0HnyRZ1iXv/
> $ cd /tmp/tmp.0HnyRZ1iXv/
> $ mkdir a
> $ sudo zsh -f -c 'mount -t tmpfs tmpfs a; cd a; touch x; ls; umount
> --lazy ../a; ls; foo=.; echo ${foo:a}; ls; realpath .; echo $PWD;'

Thanks, easy to follow.

That's certainly not pleasant as it's silent.

The source of the problem is in zgetdir().  We attempt to climb the
directory hierarchy until we get to /.  In this case we appear to get
there immediately.  Then, fatally, we call zchdir() to the place where we
think we are, but actually we aren't.

The patch below fixes up this case so we make quite sure we're in /.
This looks safe, but I'm not sure it's necessarily the limit of
what we can do to make things as safe as possible...

I'm not quite sure why we need to zchdir().  It seems to be a side
effect rather than a basic part of the call.  In particular I don't see
why it's a good idea in this case --- maybe we just add an argument
saying "not actually changing directory"?

Or should we be using getcwd() nowadays?  Presumably this is fine on most
modern systems?

pws

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) {


  reply	other threads:[~2019-04-25 13:32 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20190425120502epcas5p21b83b94136e0b2fae1002220c7d52656@epcas5p2.samsung.com>
2019-04-25 12:03 ` Yannic Schröder
2019-04-25 13:31   ` Peter Stephenson [this message]
2019-04-26  6:12     ` Yannic Schröder
2019-04-26  8:30       ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1556199068.2667.13.camel@samsung.com \
    --to=p.stephenson@samsung.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).