Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: cwd unintentionally changed
- X-seq: zsh-workers 44254
- From: Peter Stephenson <p.stephenson@xxxxxxxxxxx>
- To: <zsh-workers@xxxxxxx>
- Subject: Re: cwd unintentionally changed
- Date: Thu, 25 Apr 2019 14:31:08 +0100
- Cms-type: 201P
- Dkim-filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20190425133111euoutp010f5b97d362bd2dc28b0a01b6424ad4a9~Yus9nAsxq1591115911euoutp01R
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1556199071; bh=IR6eB4cI63wBhV6orEiVoM0mzqVYFMkOsRPLW8rFlDo=; h=Subject:From:To:Date:In-Reply-To:References:From; b=q1GXISuCXYVum+q+zRReF3gdlof37BRjkFDvnDIJst85KpIlyJxC1DwndbsYGsxoU FB0Z1UpdpIYspUyI2B6nvNO30rj+Xr0KopNdLuijBL1uQIF6uR/kchGRc05aFXNR8/ yYjMhIYjtpETBGr5XjM1YixZ4Ye1swkSZasgxUbM=
- In-reply-to: <f6d8b44f-84be-0102-5ab8-b56824e23f87@ibr.cs.tu-bs.de>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <CGME20190425120502epcas5p21b83b94136e0b2fae1002220c7d52656@epcas5p2.samsung.com> <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) {
Messages sorted by:
Reverse Date,
Date,
Thread,
Author