skisela / rpms / mercurial

Forked from rpms/mercurial 5 years ago
Clone
1f5a365
# HG changeset patch
1f5a365
# User Mateusz Kwapich <mitrandir@fb.com>
1f5a365
# Date 1458535941 25200
1f5a365
#      Sun Mar 20 21:52:21 2016 -0700
1f5a365
# Branch stable
1f5a365
# Node ID 34d43cb85de8d06764039d8868eee19d00fddeab
1f5a365
# Parent  b9714d958e89cd6ff1da46b46f39076c03325ac7
1f5a365
subrepo: set GIT_ALLOW_PROTOCOL to limit git clone protocols (SEC)
1f5a365
1f5a365
CVE-2016-3068 (1/1)
1f5a365
1f5a365
Git's git-remote-ext remote helper provides an ext:: URL scheme that
1f5a365
allows running arbitrary shell commands. This feature allows
1f5a365
implementing simple git smart transports with a single shell shell
1f5a365
command. However, git submodules could clone arbitrary URLs specified
1f5a365
in the .gitmodules file. This was reported as CVE-2015-7545 and fixed
1f5a365
in git v2.6.1.
1f5a365
1f5a365
However, if a user directly clones a malicious ext URL, the git client
1f5a365
will still run arbitrary shell commands.
1f5a365
1f5a365
Mercurial is similarly effected. Mercurial allows specifying git
1f5a365
repositories as subrepositories. Git ext:: URLs can be specified as
1f5a365
Mercurial subrepositories allowing arbitrary shell commands to be run
1f5a365
on `hg clone ...`.
1f5a365
1f5a365
1f5a365
The Mercurial community would like to thank Blake Burkhart for
1f5a365
reporting this issue. The description of the issue is copied from
1f5a365
Blake's report.
1f5a365
1f5a365
This commit changes submodules to pass the GIT_ALLOW_PROTOCOL env
1f5a365
variable to git commands  with the same list of allowed protocols that
1f5a365
git submodule is using.
1f5a365
1f5a365
When the GIT_ALLOW_PROTOCOL env variable is already set, we just pass it
1f5a365
to git without modifications.
1f5a365
1f5a365
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
1f5a365
--- a/mercurial/subrepo.py
1f5a365
+++ b/mercurial/subrepo.py
1f5a365
@@ -1383,6 +1383,11 @@ class gitsubrepo(abstractsubrepo):
1f5a365
         are not supported and very probably fail.
1f5a365
         """
1f5a365
         self.ui.debug('%s: git %s\n' % (self._relpath, ' '.join(commands)))
1f5a365
+        if env is None:
1f5a365
+            env = os.environ.copy()
1f5a365
+        # fix for Git CVE-2015-7545
1f5a365
+        if 'GIT_ALLOW_PROTOCOL' not in env:
1f5a365
+            env['GIT_ALLOW_PROTOCOL'] = 'file:git:http:https:ssh'
1f5a365
         # unless ui.quiet is set, print git's stderr,
1f5a365
         # which is mostly progress and useful info
1f5a365
         errpipe = None
1f5a365
diff --git a/tests/test-subrepo-git.t b/tests/test-subrepo-git.t
1f5a365
--- a/tests/test-subrepo-git.t
1f5a365
+++ b/tests/test-subrepo-git.t
1f5a365
@@ -1132,4 +1132,36 @@ make sure we show changed files, rather 
1f5a365
   ? s/foobar.orig
1f5a365
   ? s/snake.python.orig
1f5a365
 
1f5a365
+test for Git CVE-2016-3068
1f5a365
+  $ hg init malicious-subrepository
1f5a365
+  $ cd malicious-subrepository
1f5a365
+  $ echo "s = [git]ext::sh -c echo% pwned% >&2" > .hgsub
1f5a365
+  $ git init s
1f5a365
+  Initialized empty Git repository in $TESTTMP/tc/malicious-subrepository/s/.git/
1f5a365
+  $ cd s
1f5a365
+  $ git commit --allow-empty -m 'empty'
1f5a365
+  [master (root-commit) 153f934] empty
1f5a365
   $ cd ..
1f5a365
+  $ hg add .hgsub
1f5a365
+  $ hg commit -m "add subrepo"
1f5a365
+  $ cd ..
1f5a365
+  $ env -u GIT_ALLOW_PROTOCOL hg clone malicious-subrepository malicious-subrepository-protected
1f5a365
+  Cloning into '$TESTTMP/tc/malicious-subrepository-protected/s'...
1f5a365
+  fatal: transport 'ext' not allowed
1f5a365
+  updating to branch default
1f5a365
+  cloning subrepo s from ext::sh -c echo% pwned% >&2
1f5a365
+  abort: git clone error 128 in s (in subrepo s)
1f5a365
+  [255]
1f5a365
+
1f5a365
+whitelisting of ext should be respected (that's the git submodule behaviour)
1f5a365
+  $ env GIT_ALLOW_PROTOCOL=ext hg clone malicious-subrepository malicious-subrepository-clone-allowed
1f5a365
+  Cloning into '$TESTTMP/tc/malicious-subrepository-clone-allowed/s'...
1f5a365
+  pwned
1f5a365
+  fatal: Could not read from remote repository.
1f5a365
+  
1f5a365
+  Please make sure you have the correct access rights
1f5a365
+  and the repository exists.
1f5a365
+  updating to branch default
1f5a365
+  cloning subrepo s from ext::sh -c echo% pwned% >&2
1f5a365
+  abort: git clone error 128 in s (in subrepo s)
1f5a365
+  [255]