summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/mercurial
diff options
context:
space:
mode:
authorZhixiong Chi <zhixiong.chi@windriver.com>2017-06-15 14:05:02 +0800
committerMartin Jansa <Martin.Jansa@gmail.com>2017-06-19 19:29:37 +0200
commita3bd8e6b3d664d050fe7590869d108002973ad7a (patch)
tree8a26f9fcfa77f31b6ef1ab833e1f9a9e8732f427 /meta-oe/recipes-devtools/mercurial
parentd3dd8bc3721f3958eb7ddeb026f7221d48daa986 (diff)
downloadmeta-openembedded-a3bd8e6b3d664d050fe7590869d108002973ad7a.tar.gz
mercurial: CVE-2017-9462
Backport the CVE patch from https://www.mercurial-scm.org/repo/hg/rev/77eaf9539499 "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and consequently execute arbitrary code, by using --debugger as a repository name. CVE: CVE-2017-9462 Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Diffstat (limited to 'meta-oe/recipes-devtools/mercurial')
-rw-r--r--meta-oe/recipes-devtools/mercurial/files/mercurial-CVE-2017-9462.patch135
-rw-r--r--meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb4
2 files changed, 138 insertions, 1 deletions
diff --git a/meta-oe/recipes-devtools/mercurial/files/mercurial-CVE-2017-9462.patch b/meta-oe/recipes-devtools/mercurial/files/mercurial-CVE-2017-9462.patch
new file mode 100644
index 000000000..3564661b4
--- /dev/null
+++ b/meta-oe/recipes-devtools/mercurial/files/mercurial-CVE-2017-9462.patch
@@ -0,0 +1,135 @@
1# HG changeset patch
2# User Augie Fackler <augie@google.com>
3# Date 1492021435 25200
4# Wed Apr 12 11:23:55 2017 -0700
5# Branch stable
6# Node ID 77eaf9539499a1b8be259ffe7ada787d07857f80
7# Parent 68f263f52d2e3e2798b4f1e55cb665c6b043f93b
8dispatch: protect against malicious 'hg serve --stdio' invocations (sec)
9
10Some shared-ssh installations assume that 'hg serve --stdio' is a safe
11command to run for minimally trusted users. Unfortunately, the messy
12implementation of argument parsing here meant that trying to access a
13repo named '--debugger' would give the user a pdb prompt, thereby
14sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S)
15is unaffected.
16
17We're not currently hardening any subcommands other than 'serve'. If
18your service exposes other commands to users with arbitrary repository
19names, it is imperative that you defend against repository names of
20'--debugger' and anything starting with '--config'.
21
22The read-only mode of hg-ssh stopped working because it provided its hook
23configuration to "hg serve --stdio" via --config parameter. This is banned for
24security reasons now. This patch switches it to directly call ui.setconfig().
25If your custom hosting infrastructure relies on passing --config to
26"hg serve --stdio", you'll need to find a different way to get that configuration
27into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch,
28or by placing an hgrc file someplace where Mercurial will read it.
29
30mitrandir@fb.com provided some extra fixes for the dispatch code and
31for hg-ssh in places that I overlooked.
32
33CVE: CVE-2017-9462
34
35Upstream-Status: Backport
36
37diff --git a/contrib/hg-ssh b/contrib/hg-ssh
38--- a/contrib/hg-ssh
39+++ b/contrib/hg-ssh
40@@ -32,7 +32,7 @@
41 # enable importing on demand to reduce startup time
42 from mercurial import demandimport; demandimport.enable()
43
44-from mercurial import dispatch
45+from mercurial import dispatch, ui as uimod
46
47 import sys, os, shlex
48
49@@ -61,14 +61,15 @@
50 repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
51 if repo in allowed_paths:
52 cmd = ['-R', repo, 'serve', '--stdio']
53+ req = dispatch.request(cmd)
54 if readonly:
55- cmd += [
56- '--config',
57- 'hooks.pretxnopen.hg-ssh=python:__main__.rejectpush',
58- '--config',
59- 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush'
60- ]
61- dispatch.dispatch(dispatch.request(cmd))
62+ if not req.ui:
63+ req.ui = uimod.ui.load()
64+ req.ui.setconfig('hooks', 'pretxnopen.hg-ssh',
65+ 'python:__main__.rejectpush', 'hg-ssh')
66+ req.ui.setconfig('hooks', 'prepushkey.hg-ssh',
67+ 'python:__main__.rejectpush', 'hg-ssh')
68+ dispatch.dispatch(req)
69 else:
70 sys.stderr.write('Illegal repository "%s"\n' % repo)
71 sys.exit(255)
72diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
73--- a/mercurial/dispatch.py
74+++ b/mercurial/dispatch.py
75@@ -155,6 +155,37 @@
76 pass # happens if called in a thread
77
78 def _runcatchfunc():
79+ realcmd = None
80+ try:
81+ cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {})
82+ cmd = cmdargs[0]
83+ aliases, entry = cmdutil.findcmd(cmd, commands.table, False)
84+ realcmd = aliases[0]
85+ except (error.UnknownCommand, error.AmbiguousCommand,
86+ IndexError, getopt.GetoptError):
87+ # Don't handle this here. We know the command is
88+ # invalid, but all we're worried about for now is that
89+ # it's not a command that server operators expect to
90+ # be safe to offer to users in a sandbox.
91+ pass
92+ if realcmd == 'serve' and '--stdio' in cmdargs:
93+ # We want to constrain 'hg serve --stdio' instances pretty
94+ # closely, as many shared-ssh access tools want to grant
95+ # access to run *only* 'hg -R $repo serve --stdio'. We
96+ # restrict to exactly that set of arguments, and prohibit
97+ # any repo name that starts with '--' to prevent
98+ # shenanigans wherein a user does something like pass
99+ # --debugger or --config=ui.debugger=1 as a repo
100+ # name. This used to actually run the debugger.
101+ if (len(req.args) != 4 or
102+ req.args[0] != '-R' or
103+ req.args[1].startswith('--') or
104+ req.args[2] != 'serve' or
105+ req.args[3] != '--stdio'):
106+ raise error.Abort(
107+ _('potentially unsafe serve --stdio invocation: %r') %
108+ (req.args,))
109+
110 try:
111 debugger = 'pdb'
112 debugtrace = {
113diff --git a/tests/test-ssh.t b/tests/test-ssh.t
114--- a/tests/test-ssh.t
115+++ b/tests/test-ssh.t
116@@ -357,6 +357,19 @@
117 abort: destination 'a repo' is not empty
118 [255]
119
120+Make sure hg is really paranoid in serve --stdio mode. It used to be
121+possible to get a debugger REPL by specifying a repo named --debugger.
122+ $ hg -R --debugger serve --stdio
123+ abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio']
124+ [255]
125+ $ hg -R --config=ui.debugger=yes serve --stdio
126+ abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio']
127+ [255]
128+Abbreviations of 'serve' also don't work, to avoid shenanigans.
129+ $ hg -R narf serv --stdio
130+ abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio']
131+ [255]
132+
133 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
134 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
135 parameters:
diff --git a/meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb b/meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb
index 028bb4232..a08acd950 100644
--- a/meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb
+++ b/meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb
@@ -5,7 +5,9 @@ LICENSE = "GPLv2"
5LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" 5LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263"
6DEPENDS = "python-native" 6DEPENDS = "python-native"
7 7
8SRC_URI = "https://www.mercurial-scm.org/release/${BP}.tar.gz" 8SRC_URI = "https://www.mercurial-scm.org/release/${BP}.tar.gz \
9 file://mercurial-CVE-2017-9462.patch \
10"
9SRC_URI[md5sum] = "22a9b1d7c0c06a53f0ae5b386d536d08" 11SRC_URI[md5sum] = "22a9b1d7c0c06a53f0ae5b386d536d08"
10SRC_URI[sha256sum] = "6aa4ade93c1b5e11937820880a466ebf1c824086d443cd799fc46e2617250d40" 12SRC_URI[sha256sum] = "6aa4ade93c1b5e11937820880a466ebf1c824086d443cd799fc46e2617250d40"
11 13