diff options
author | Zhixiong Chi <zhixiong.chi@windriver.com> | 2017-06-15 14:05:02 +0800 |
---|---|---|
committer | Martin Jansa <Martin.Jansa@gmail.com> | 2017-06-19 19:29:37 +0200 |
commit | a3bd8e6b3d664d050fe7590869d108002973ad7a (patch) | |
tree | 8a26f9fcfa77f31b6ef1ab833e1f9a9e8732f427 /meta-oe/recipes-devtools/mercurial | |
parent | d3dd8bc3721f3958eb7ddeb026f7221d48daa986 (diff) | |
download | meta-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.patch | 135 | ||||
-rw-r--r-- | meta-oe/recipes-devtools/mercurial/mercurial-native_4.0.1.bb | 4 |
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 | ||
8 | dispatch: protect against malicious 'hg serve --stdio' invocations (sec) | ||
9 | |||
10 | Some shared-ssh installations assume that 'hg serve --stdio' is a safe | ||
11 | command to run for minimally trusted users. Unfortunately, the messy | ||
12 | implementation of argument parsing here meant that trying to access a | ||
13 | repo named '--debugger' would give the user a pdb prompt, thereby | ||
14 | sidestepping any hoped-for sandboxing. Serving repositories over HTTP(S) | ||
15 | is unaffected. | ||
16 | |||
17 | We're not currently hardening any subcommands other than 'serve'. If | ||
18 | your service exposes other commands to users with arbitrary repository | ||
19 | names, it is imperative that you defend against repository names of | ||
20 | '--debugger' and anything starting with '--config'. | ||
21 | |||
22 | The read-only mode of hg-ssh stopped working because it provided its hook | ||
23 | configuration to "hg serve --stdio" via --config parameter. This is banned for | ||
24 | security reasons now. This patch switches it to directly call ui.setconfig(). | ||
25 | If 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 | ||
27 | into Mercurial, either by using ui.setconfig() as hg-ssh does in this patch, | ||
28 | or by placing an hgrc file someplace where Mercurial will read it. | ||
29 | |||
30 | mitrandir@fb.com provided some extra fixes for the dispatch code and | ||
31 | for hg-ssh in places that I overlooked. | ||
32 | |||
33 | CVE: CVE-2017-9462 | ||
34 | |||
35 | Upstream-Status: Backport | ||
36 | |||
37 | diff --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) | ||
72 | diff --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 = { | ||
113 | diff --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" | |||
5 | LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" | 5 | LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" |
6 | DEPENDS = "python-native" | 6 | DEPENDS = "python-native" |
7 | 7 | ||
8 | SRC_URI = "https://www.mercurial-scm.org/release/${BP}.tar.gz" | 8 | SRC_URI = "https://www.mercurial-scm.org/release/${BP}.tar.gz \ |
9 | file://mercurial-CVE-2017-9462.patch \ | ||
10 | " | ||
9 | SRC_URI[md5sum] = "22a9b1d7c0c06a53f0ae5b386d536d08" | 11 | SRC_URI[md5sum] = "22a9b1d7c0c06a53f0ae5b386d536d08" |
10 | SRC_URI[sha256sum] = "6aa4ade93c1b5e11937820880a466ebf1c824086d443cd799fc46e2617250d40" | 12 | SRC_URI[sha256sum] = "6aa4ade93c1b5e11937820880a466ebf1c824086d443cd799fc46e2617250d40" |
11 | 13 | ||