diff mercurial/subrepo.py @ 41315:6c10eba6b9cd stable

subrepo: prohibit variable expansion on creation of hg subrepo (SEC) It's probably wrong to expand path at localrepo.*repository() layer, but fixing the layering issue would require careful inspection of call paths. So, this patch adds add a validation to the subrepo constructor. os.path.realpath(util.expandpath(root)) is what vfsmod.vfs() would do.
author Yuya Nishihara <yuya@tcha.org>
date Tue, 08 Jan 2019 22:07:45 +0900
parents 9199548525fc
children 83377b4b4ae0
line wrap: on
line diff
--- a/mercurial/subrepo.py	Tue Jan 08 21:51:54 2019 +0900
+++ b/mercurial/subrepo.py	Tue Jan 08 22:07:45 2019 +0900
@@ -403,7 +403,16 @@
         r = ctx.repo()
         root = r.wjoin(path)
         create = allowcreate and not r.wvfs.exists('%s/.hg' % path)
+        # repository constructor does expand variables in path, which is
+        # unsafe since subrepo path might come from untrusted source.
+        if os.path.realpath(util.expandpath(root)) != root:
+            raise error.Abort(_('subrepo path contains illegal component: %s')
+                              % path)
         self._repo = hg.repository(r.baseui, root, create=create)
+        if self._repo.root != root:
+            raise error.ProgrammingError('failed to reject unsafe subrepo '
+                                         'path: %s (expanded to %s)'
+                                         % (root, self._repo.root))
 
         # Propagate the parent's --hidden option
         if r is r.unfiltered():