Bug#773847: unblock: mercurial/3.1.2-2
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package mercurial. It fixes #773640[0] (CVE-2014-9390:
Errors in handling case-sensitive directories allow for remote code
execution on pull). Upstream has confirmed[1] that the three patches
that this update adds are the ones needed to fix it. See below the
debdiff against 3.1.2-1, the version currently in jessie.
[0] https://bugs.debian.org/773640
[1] http://selenic.com/pipermail/mercurial-packaging/2014-December/000133.html
---8<---
diff -Nru mercurial-3.1.2/debian/changelog mercurial-3.1.2/debian/changelog
--- mercurial-3.1.2/debian/changelog 2014-10-03 00:34:41.000000000 +0200
+++ mercurial-3.1.2/debian/changelog 2014-12-23 16:01:50.000000000 +0100
@@ -1,3 +1,15 @@
+mercurial (3.1.2-2) unstable; urgency=high
+
+ * Fix "CVE-2014-9390: Errors in handling case-sensitive directories
+ allow for remote code execution on pull" by adding patches
+ from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch,
+ from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch,
+ and
+ from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch
+ (Closes: #773640)
+
+ -- Javi Merino <vicho@debian.org> Tue, 23 Dec 2014 16:01:50 +0100
+
mercurial (3.1.2-1) unstable; urgency=medium
* New upstream version
diff -Nru mercurial-3.1.2/debian/patches/from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch mercurial-3.1.2/debian/patches/from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch
--- mercurial-3.1.2/debian/patches/from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch 1970-01-01 01:00:00.000000000 +0100
+++ mercurial-3.1.2/debian/patches/from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch 2014-12-23 15:57:51.000000000 +0100
@@ -0,0 +1,44 @@
+Origin: http://selenic.com/repo/hg-stable/rev/885bd7c5c7e3
+Description: encoding: add hfsignoreclean to clean out HFS-ignored characters
+ According to Apple Technote 1150 (unavailable from Apple as far as I
+ can tell, but archived in several places online), HFS+ ignores sixteen
+ specific unicode runes when doing path normalization. We need to
+ handle those cases, so this function lets us efficiently strip the
+ offending characters from a UTF-8 encoded string (which is the only
+ way it seems to matter on OS X.)
+ .
+ This is a fix for CVE-2014-9390
+Applied-Upstream: 3.2.3
+
+diff --git a/mercurial/encoding.py b/mercurial/encoding.py
+--- a/mercurial/encoding.py
++++ b/mercurial/encoding.py
+@@ -8,6 +8,28 @@
+ import error
+ import unicodedata, locale, os
+
++# These unicode characters are ignored by HFS+ (Apple Technote 1150,
++# "Unicode Subtleties"), so we need to ignore them in some places for
++# sanity.
++_ignore = [unichr(int(x, 16)).encode("utf-8") for x in
++ "200c 200d 200e 200f 202a 202b 202c 202d 202e "
++ "206a 206b 206c 206d 206e 206f feff".split()]
++# verify the next function will work
++assert set([i[0] for i in _ignore]) == set(["\xe2", "\xef"])
++
++def hfsignoreclean(s):
++ """Remove codepoints ignored by HFS+ from s.
++
++ >>> hfsignoreclean(u'.h\u200cg'.encode('utf-8'))
++ '.hg'
++ >>> hfsignoreclean(u'.h\ufeffg'.encode('utf-8'))
++ '.hg'
++ """
++ if "\xe2" in s or "\xef" in s:
++ for c in _ignore:
++ s = s.replace(c, '')
++ return s
++
+ def _getpreferredencoding():
+ '''
+ On darwin, getpreferredencoding ignores the locale environment and
diff -Nru mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch
--- mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch 1970-01-01 01:00:00.000000000 +0100
+++ mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch 2014-12-23 15:57:51.000000000 +0100
@@ -0,0 +1,59 @@
+Origin: http://selenic.com/repo/hg-stable/rev/c02a05cc6f5e
+Description: pathauditor: check for codepoints ignored on OS X
+ This is a fix for CVE-2014-9390
+Applied-Upstream: 3.2.3
+
+--- a/mercurial/pathutil.py
++++ b/mercurial/pathutil.py
+@@ -1,8 +1,12 @@
+ import os, errno, stat
+
++import encoding
+ import util
+ from i18n import _
+
++def _lowerclean(s):
++ return encoding.hfsignoreclean(s.lower())
++
+ class pathauditor(object):
+ '''ensure that a filesystem path contains no banned components.
+ the following properties of a path are checked:
+@@ -39,11 +43,11 @@ class pathauditor(object):
+ raise util.Abort(_("path ends in directory separator: %s") % path)
+ parts = util.splitpath(path)
+ if (os.path.splitdrive(path)[0]
+- or parts[0].lower() in ('.hg', '.hg.', '')
++ or _lowerclean(parts[0]) in ('.hg', '.hg.', '')
+ or os.pardir in parts):
+ raise util.Abort(_("path contains illegal component: %s") % path)
+- if '.hg' in path.lower():
+- lparts = [p.lower() for p in parts]
++ if '.hg' in _lowerclean(path):
++ lparts = [_lowerclean(p.lower()) for p in parts]
+ for p in '.hg', '.hg.':
+ if p in lparts[1:]:
+ pos = lparts.index(p)
+--- a/tests/test-commit.t
++++ b/tests/test-commit.t
+@@ -418,4 +418,21 @@ commit copy
+ 0 0 6 ..... 0 26d3ca0dfd18 000000000000 000000000000 (re)
+ 1 6 7 ..... 1 d267bddd54f7 26d3ca0dfd18 000000000000 (re)
+
++verify pathauditor blocks evil filepaths
++ $ cat > evil-commit.py <<EOF
++ > from mercurial import ui, hg, context, node
++ > notrc = u".h\u200cg".encode('utf-8') + '/hgrc'
++ > u = ui.ui()
++ > r = hg.repository(u, '.')
++ > def filectxfn(repo, memctx, path):
++ > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
++ > c = context.memctx(r, [r['tip'].node(), node.nullid],
++ > 'evil', [notrc], filectxfn, 0)
++ > r.commitctx(c)
++ > EOF
++ $ $PYTHON evil-commit.py
++ $ hg co --clean tip
++ abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
++ [255]
++
+ $ cd ..
diff -Nru mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch
--- mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch 1970-01-01 01:00:00.000000000 +0100
+++ mercurial-3.1.2/debian/patches/from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch 2014-12-23 15:57:51.000000000 +0100
@@ -0,0 +1,63 @@
+Origin: http://selenic.com/repo/hg-stable/rev/6dad422ecc5a
+Description: pathauditor: check for Windows shortname aliases
+ This is a fix for CVE-2014-9390
+Applied-Upstream: 3.2.3
+
+--- a/mercurial/pathutil.py
++++ b/mercurial/pathutil.py
+@@ -46,6 +46,13 @@ class pathauditor(object):
+ or _lowerclean(parts[0]) in ('.hg', '.hg.', '')
+ or os.pardir in parts):
+ raise util.Abort(_("path contains illegal component: %s") % path)
++ # Windows shortname aliases
++ for p in parts:
++ if "~" in p:
++ first, last = p.split("~", 1)
++ if last.isdigit() and first.upper() in ["HG", "HG8B6C"]:
++ raise util.Abort(_("path contains illegal component: %s")
++ % path)
+ if '.hg' in _lowerclean(path):
+ lparts = [_lowerclean(p.lower()) for p in parts]
+ for p in '.hg', '.hg.':
+--- a/tests/test-commit.t
++++ b/tests/test-commit.t
+@@ -435,4 +435,38 @@ verify pathauditor blocks evil filepaths
+ abort: path contains illegal component: .h\xe2\x80\x8cg/hgrc (esc)
+ [255]
+
+- $ cd ..
++ $ hg rollback -f
++ repository tip rolled back to revision 1 (undo commit)
++ $ cat > evil-commit.py <<EOF
++ > from mercurial import ui, hg, context, node
++ > notrc = "HG~1/hgrc"
++ > u = ui.ui()
++ > r = hg.repository(u, '.')
++ > def filectxfn(repo, memctx, path):
++ > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
++ > c = context.memctx(r, [r['tip'].node(), node.nullid],
++ > 'evil', [notrc], filectxfn, 0)
++ > r.commitctx(c)
++ > EOF
++ $ $PYTHON evil-commit.py
++ $ hg co --clean tip
++ abort: path contains illegal component: HG~1/hgrc
++ [255]
++
++ $ hg rollback -f
++ repository tip rolled back to revision 1 (undo commit)
++ $ cat > evil-commit.py <<EOF
++ > from mercurial import ui, hg, context, node
++ > notrc = "HG8B6C~2/hgrc"
++ > u = ui.ui()
++ > r = hg.repository(u, '.')
++ > def filectxfn(repo, memctx, path):
++ > return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
++ > c = context.memctx(r, [r['tip'].node(), node.nullid],
++ > 'evil', [notrc], filectxfn, 0)
++ > r.commitctx(c)
++ > EOF
++ $ $PYTHON evil-commit.py
++ $ hg co --clean tip
++ abort: path contains illegal component: HG8B6C~2/hgrc
++ [255]
diff -Nru mercurial-3.1.2/debian/patches/series mercurial-3.1.2/debian/patches/series
--- mercurial-3.1.2/debian/patches/series 2014-09-03 12:15:32.000000000 +0200
+++ mercurial-3.1.2/debian/patches/series 2014-12-23 15:57:51.000000000 +0100
@@ -9,3 +9,6 @@
for_upstream__dont_rm_usr_bin_python_when_running_testsuite.patch
for_upstream__lenient_test-shelve.patch
from_upstream__test-patchbomb_t_work_around_Python_change_d579866d6419_issue4188.patch
+from_upstream__encoding_add_hfsignoreclean_to_clean_out_HFS-ignored_characters.patch
+from_upstream__pathauditor_check_for_codepoints_ignored_on_OS_X.patch
+from_upstream__pathauditor_check_for_Windows_shortname_aliases.patch
---8<---
unblock mercurial/3.1.2-2
-- System Information:
Debian Release: 8.0
APT prefers unstable
APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=es_ES.UTF-8, LC_CTYPE=es_ES.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Reply to: