7d0f2b
From 837a69dc6ff77d8c93e73a64c067fe60530e4f1b Mon Sep 17 00:00:00 2001
7d0f2b
From: Mateusz Kwapich <mitrandir@fb.com>
7d0f2b
Date: Sun, 20 Mar 2016 21:52:21 -0700
7d0f2b
Subject: [PATCH 1/6] subrepo: set GIT_ALLOW_PROTOCOL to limit git clone
7d0f2b
 protocols (SEC)
7d0f2b
7d0f2b
CVE-2016-3068 (1/1)
7d0f2b
7d0f2b
Git's git-remote-ext remote helper provides an ext:: URL scheme that
7d0f2b
allows running arbitrary shell commands. This feature allows
7d0f2b
implementing simple git smart transports with a single shell shell
7d0f2b
command. However, git submodules could clone arbitrary URLs specified
7d0f2b
in the .gitmodules file. This was reported as CVE-2015-7545 and fixed
7d0f2b
in git v2.6.1.
7d0f2b
7d0f2b
However, if a user directly clones a malicious ext URL, the git client
7d0f2b
will still run arbitrary shell commands.
7d0f2b
7d0f2b
Mercurial is similarly effected. Mercurial allows specifying git
7d0f2b
repositories as subrepositories. Git ext:: URLs can be specified as
7d0f2b
Mercurial subrepositories allowing arbitrary shell commands to be run
7d0f2b
on `hg clone ...`.
7d0f2b
7d0f2b
The Mercurial community would like to thank Blake Burkhart for
7d0f2b
reporting this issue. The description of the issue is copied from
7d0f2b
Blake's report.
7d0f2b
7d0f2b
This commit changes submodules to pass the GIT_ALLOW_PROTOCOL env
7d0f2b
variable to git commands  with the same list of allowed protocols that
7d0f2b
git submodule is using.
7d0f2b
7d0f2b
When the GIT_ALLOW_PROTOCOL env variable is already set, we just pass it
7d0f2b
to git without modifications.
7d0f2b
---
7d0f2b
 mercurial/subrepo.py     |  5 +++++
7d0f2b
 tests/test-subrepo-git.t | 34 ++++++++++++++++++++++++++++++++++
7d0f2b
 2 files changed, 39 insertions(+)
7d0f2b
7d0f2b
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
7d0f2b
index 3747377..7286f06 100644
7d0f2b
--- a/mercurial/subrepo.py
7d0f2b
+++ b/mercurial/subrepo.py
7d0f2b
@@ -1060,6 +1060,11 @@ class gitsubrepo(abstractsubrepo):
7d0f2b
         are not supported and very probably fail.
7d0f2b
         """
7d0f2b
         self._ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
7d0f2b
+        if env is None:
7d0f2b
+            env = os.environ.copy()
7d0f2b
+        # fix for Git CVE-2015-7545
7d0f2b
+        if 'GIT_ALLOW_PROTOCOL' not in env:
7d0f2b
+            env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh'
7d0f2b
         # unless ui.quiet is set, print git's stderr,
7d0f2b
         # which is mostly progress and useful info
7d0f2b
         errpipe = None
7d0f2b
diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t
7d0f2b
index 9361193..24cb6a2 100644
7d0f2b
--- a/tests/test-subrepo-git.t
7d0f2b
+++ b/tests/test-subrepo-git.t
7d0f2b
@@ -558,3 +558,37 @@ traceback
7d0f2b
 #endif
7d0f2b
 
7d0f2b
   $ cd ..
7d0f2b
+
7d0f2b
+test for Git CVE-2016-3068
7d0f2b
+  $ hg init malicious-subrepository
7d0f2b
+  $ cd malicious-subrepository
7d0f2b
+  $ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub
7d0f2b
+  $ git init s
7d0f2b
+  Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/
7d0f2b
+  $ cd s
7d0f2b
+  $ git commit --allow-empty -m 'empty'
7d0f2b
+  [master (root-commit) 153f934] empty
7d0f2b
+  $ cd ..
7d0f2b
+  $ hg add .hgsub
7d0f2b
+  $ hg commit -m "add subrepo"
7d0f2b
+  $ cd ..
7d0f2b
+  $ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected
7d0f2b
+  Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'...
7d0f2b
+  fatal: transport 'ext' not allowed
7d0f2b
+  updating to branch default
7d0f2b
+  cloning subrepo s from ext::sh -c echo% pwned% >&2
7d0f2b
+  abort: git clone error 128 in s (in subrepo s)
7d0f2b
+  [255]
7d0f2b
+
7d0f2b
+whitelisting of ext should be respected (that's the git submodule behaviour)
7d0f2b
+  $ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed
7d0f2b
+  Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'...
7d0f2b
+  pwned
7d0f2b
+  fatal: Could not read from remote repository.
7d0f2b
+  
7d0f2b
+  Please make sure you have the correct access rights
7d0f2b
+  and the repository exists.
7d0f2b
+  updating to branch default
7d0f2b
+  cloning subrepo s from ext::sh -c echo% pwned% >&2
7d0f2b
+  abort: git clone error 128 in s (in subrepo s)
7d0f2b
+  [255]
7d0f2b
-- 
7d0f2b
2.4.11
7d0f2b