subrepo: reject potentially unsafe subrepo paths (BC) (SEC) stable 4.9
authorYuya Nishihara <yuya@tcha.org>
Tue, 08 Jan 2019 22:19:36 +0900
branchstable
changeset 41458 83377b4b4ae0
parent 41457 6c10eba6b9cd
child 41459 5a4d2ab7b55c
subrepo: reject potentially unsafe subrepo paths (BC) (SEC) In addition to the previous patch, this prohibits '~', '$nonexistent', etc. for any subrepo types. I think this is safer, and real-world subrepos wouldn't use such (local) paths.
mercurial/subrepo.py
tests/test-audit-subrepo.t
--- a/mercurial/subrepo.py	Tue Jan 08 22:07:45 2019 +0900
+++ b/mercurial/subrepo.py	Tue Jan 08 22:19:36 2019 +0900
@@ -115,6 +115,10 @@
                 vfs.unlink(vfs.reljoin(dirname, f))
 
 def _auditsubrepopath(repo, path):
+    # sanity check for potentially unsafe paths such as '~' and '$FOO'
+    if path.startswith('~') or '$' in path or util.expandpath(path) != path:
+        raise error.Abort(_('subrepo path contains illegal component: %s')
+                          % path)
     # auditor doesn't check if the path itself is a symlink
     pathutil.pathauditor(repo.root)(path)
     if repo.wvfs.islink(path):
--- a/tests/test-audit-subrepo.t	Tue Jan 08 22:07:45 2019 +0900
+++ b/tests/test-audit-subrepo.t	Tue Jan 08 22:19:36 2019 +0900
@@ -279,8 +279,9 @@
 on clone (and update) with various substitutions:
 
   $ hg clone -q main main2
+  abort: subrepo path contains illegal component: $SUB
+  [255]
   $ ls main2
-  $SUB
 
   $ SUB=sub1 hg clone -q main main3
   abort: subrepo path contains illegal component: $SUB
@@ -363,8 +364,9 @@
 Test tilde
 ----------
 
-The leading tilde may be expanded to $HOME, but it's a valid subrepo path.
-However, we might want to prohibit it as it seems potentially unsafe.
+The leading tilde may be expanded to $HOME, but it can be a valid subrepo
+path in theory. However, we want to prohibit it as there might be unsafe
+handling of such paths.
 
 on commit:
 
@@ -373,15 +375,32 @@
   $ hg init './~'
   $ echo '~ = ~' >> .hgsub
   $ hg ci -qAm 'add subrepo "~"'
-  $ ls
-  ~
+  abort: subrepo path contains illegal component: ~
+  [255]
+
+prepare tampered repo (including the commit above):
+
+  $ hg import --bypass -qm 'add subrepo "~"' - <<'EOF'
+  > diff --git a/.hgsub b/.hgsub
+  > new file mode 100644
+  > --- /dev/null
+  > +++ b/.hgsub
+  > @@ -0,0 +1,1 @@
+  > +~ = ~
+  > diff --git a/.hgsubstate b/.hgsubstate
+  > new file mode 100644
+  > --- /dev/null
+  > +++ b/.hgsubstate
+  > @@ -0,0 +1,1 @@
+  > +0000000000000000000000000000000000000000 ~
+  > EOF
   $ cd ..
 
 on clone (and update):
 
   $ hg clone -q tilde tilde2
-  $ ls tilde2
-  ~
+  abort: subrepo path contains illegal component: ~
+  [255]
 
 Test direct symlink traversal
 -----------------------------