diff --git a/SOURCES/mercurial-cve-2017-9462.patch b/SOURCES/mercurial-cve-2017-9462.patch new file mode 100644 index 0000000..8835a81 --- /dev/null +++ b/SOURCES/mercurial-cve-2017-9462.patch @@ -0,0 +1,140 @@ +diff --git a/contrib/hg-ssh b/contrib/hg-ssh +index 5ec5100..c643f97 100755 +--- a/contrib/hg-ssh ++++ b/contrib/hg-ssh +@@ -32,7 +32,7 @@ command="hg-ssh --read-only repos/*" + # enable importing on demand to reduce startup time + from mercurial import demandimport; demandimport.enable() + +-from mercurial import dispatch ++from mercurial import dispatch, ui as uimod + + import sys, os, shlex + +@@ -61,14 +61,15 @@ def main(): + repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path))) + if repo in allowed_paths: + cmd = ['-R', repo, 'serve', '--stdio'] ++ req = dispatch.request(cmd) + if readonly: +- cmd += [ +- '--config', +- 'hooks.prechangegroup.hg-ssh=python:__main__.rejectpush', +- '--config', +- 'hooks.prepushkey.hg-ssh=python:__main__.rejectpush' +- ] +- dispatch.dispatch(dispatch.request(cmd)) ++ if not req.ui: ++ req.ui = uimod.ui() ++ req.ui.setconfig('hooks', 'pretxnopen.hg-ssh', ++ 'python:__main__.rejectpush', 'hg-ssh') ++ req.ui.setconfig('hooks', 'prepushkey.hg-ssh', ++ 'python:__main__.rejectpush', 'hg-ssh') ++ dispatch.dispatch(req) + else: + sys.stderr.write('Illegal repository "%s"\n' % repo) + sys.exit(255) +diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py +index fa2532d..99e1d5b 100644 +--- a/mercurial/dispatch.py ++++ b/mercurial/dispatch.py +@@ -87,6 +87,36 @@ def _runcatch(req): + pass # happens if called in a thread + + try: ++ realcmd = None ++ try: ++ cmdargs = fancyopts.fancyopts(req.args[:], commands.globalopts, {}) ++ cmd = cmdargs[0] ++ aliases, entry = cmdutil.findcmd(cmd, commands.table, False) ++ realcmd = aliases[0] ++ except (error.UnknownCommand, error.AmbiguousCommand, ++ IndexError, fancyopts.getopt.GetoptError): ++ # Don't handle this here. We know the command is ++ # invalid, but all we're worried about for now is that ++ # it's not a command that server operators expect to ++ # be safe to offer to users in a sandbox. ++ pass ++ if realcmd == 'serve' and '--stdio' in cmdargs: ++ # We want to constrain 'hg serve --stdio' instances pretty ++ # closely, as many shared-ssh access tools want to grant ++ # access to run *only* 'hg -R $repo serve --stdio'. We ++ # restrict to exactly that set of arguments, and prohibit ++ # any repo name that starts with '--' to prevent ++ # shenanigans wherein a user does something like pass ++ # --debugger or --config=ui.debugger=1 as a repo ++ # name. This used to actually run the debugger. ++ if (len(req.args) != 4 or ++ req.args[0] != '-R' or ++ req.args[1].startswith('--') or ++ req.args[2] != 'serve' or ++ req.args[3] != '--stdio'): ++ raise error.Abort( ++ _('potentially unsafe serve --stdio invocation: %r') % ++ (req.args,)) + try: + # enter the debugger before command execution + if '--debugger' in req.args: +diff --git a/tests/test-hup.t b/tests/test-hup.t +deleted file mode 100644 +index 9745643..0000000 +--- a/tests/test-hup.t ++++ /dev/null +@@ -1,28 +0,0 @@ +-Test hangup signal in the middle of transaction +- +- $ "$TESTDIR/hghave" serve fifo || exit 80 +- $ hg init +- $ mkfifo p +- $ hg serve --stdio < p 1>out 2>&1 & +- $ P=$! +- +-Do test while holding fifo open +- +- $ ( +- > echo lock +- > echo addchangegroup +- > while [ ! -s .hg/store/journal ]; do sleep 0; done +- > kill -HUP $P +- > ) > p +- +- $ wait +- $ cat out +- 0 +- 0 +- adding changesets +- transaction abort! +- rollback completed +- killed! +- +- $ echo .hg/* .hg/store/* +- .hg/00changelog.i .hg/journal.bookmarks .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a .hg/store/journal.phaseroots +diff --git a/tests/test-ssh.t b/tests/test-ssh.t +index f1584af..ad60b0e 100644 +--- a/tests/test-ssh.t ++++ b/tests/test-ssh.t +@@ -291,6 +291,19 @@ Test (non-)escaping of remote paths with spaces when cloning (issue3145): + abort: destination 'a repo' is not empty + [255] + ++Make sure hg is really paranoid in serve --stdio mode. It used to be ++possible to get a debugger REPL by specifying a repo named --debugger. ++ $ hg -R --debugger serve --stdio ++ abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio'] ++ [255] ++ $ hg -R --config=ui.debugger=yes serve --stdio ++ abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio'] ++ [255] ++Abbreviations of 'serve' also don't work, to avoid shenanigans. ++ $ hg -R narf serv --stdio ++ abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio'] ++ [255] ++ + Test hg-ssh using a helper script that will restore PYTHONPATH (which might + have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right + parameters: +@@ -382,3 +395,4 @@ Test hg-ssh in read-only mode: + Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio + Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio + Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio ++ changegroup-in-remote hook: HG_NODE=f9f0a8007dba27625503c51182b535f85fd4bb6b HG_SOURCE=serve HG_URL=remote:ssh: diff --git a/SPECS/mercurial.spec b/SPECS/mercurial.spec index 2103e4e..9a43ca9 100644 --- a/SPECS/mercurial.spec +++ b/SPECS/mercurial.spec @@ -3,7 +3,7 @@ Summary: Mercurial -- a distributed SCM Name: mercurial Version: 2.6.2 -Release: 6%{?dist} +Release: 7%{?dist} #Release: 1.rc1%{?dist} #%define upstreamversion %{version}-rc @@ -22,7 +22,7 @@ Patch2: mercurial-absolute-shebang.patch Patch3: mercurial-cve-2016-3068.patch Patch4: mercurial-cve-2016-3069.patch - +Patch5: mercurial-cve-2017-9462.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: python python-devel @@ -96,6 +96,7 @@ documentation. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 %build make all @@ -202,6 +203,9 @@ rm -rf $RPM_BUILD_ROOT ##cd tests && %{__python} run-tests.py %changelog +* Thu Jun 15 2017 Petr Stodulka - 2.6.2-7 +- Fix CVE-2017-9462 + * Thu Apr 14 2016 Petr Stodulka - 2.6.2-6 - fix previous patch for CVE-2016-3069