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 | |
| 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>
| -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 0000000000..3564661b4b --- /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 028bb4232d..a08acd9504 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 | ||
