diff mercurial/subrepo.py @ 34984:071cbeba4212 stable

subrepo: disallow symlink traversal across subrepo mount point (SEC) It wasn't easy to extend the pathauditor to check symlink traversal across subrepos because pathauditor._checkfs() rejects a directory having ".hg" directory. That's why I added the explicit islink() check. No idea if this patch is necessary after we've fixed the issue5730 by splitting submerge() into planning and execution phases.
author Yuya Nishihara <yuya@tcha.org>
date Fri, 03 Nov 2017 20:12:50 +0900
parents 7d51a7792f52
children 5e27afeddaee
line wrap: on
line diff
--- a/mercurial/subrepo.py	Fri Nov 03 19:17:25 2017 +0900
+++ b/mercurial/subrepo.py	Fri Nov 03 20:12:50 2017 +0900
@@ -359,6 +359,12 @@
                           "in '%s'\n") % vfs.join(dirname))
                 vfs.unlink(vfs.reljoin(dirname, f))
 
+def _auditsubrepopath(repo, path):
+    # auditor doesn't check if the path itself is a symlink
+    pathutil.pathauditor(repo.root)(path)
+    if repo.wvfs.islink(path):
+        raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
+
 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
     """return instance of the right subrepo class for subrepo in path"""
     # subrepo inherently violates our import layering rules
@@ -369,7 +375,7 @@
     from . import hg as h
     hg = h
 
-    pathutil.pathauditor(ctx.repo().root)(path)
+    _auditsubrepopath(ctx.repo(), path)
     state = ctx.substate[path]
     if state[2] not in types:
         raise error.Abort(_('unknown subrepo type %s') % state[2])
@@ -387,7 +393,7 @@
     from . import hg as h
     hg = h
 
-    pathutil.pathauditor(ctx.repo().root)(path)
+    _auditsubrepopath(ctx.repo(), path)
     state = ctx.substate[path]
     if state[2] not in types:
         raise error.Abort(_('unknown subrepo type %s') % state[2])