comparison 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
comparison
equal deleted inserted replaced
34983:80d7dbda9294 34984:071cbeba4212
357 if f.lower() == 'hgrc': 357 if f.lower() == 'hgrc':
358 ui.warn(_("warning: removing potentially hostile 'hgrc' " 358 ui.warn(_("warning: removing potentially hostile 'hgrc' "
359 "in '%s'\n") % vfs.join(dirname)) 359 "in '%s'\n") % vfs.join(dirname))
360 vfs.unlink(vfs.reljoin(dirname, f)) 360 vfs.unlink(vfs.reljoin(dirname, f))
361 361
362 def _auditsubrepopath(repo, path):
363 # auditor doesn't check if the path itself is a symlink
364 pathutil.pathauditor(repo.root)(path)
365 if repo.wvfs.islink(path):
366 raise error.Abort(_("subrepo '%s' traverses symbolic link") % path)
367
362 def subrepo(ctx, path, allowwdir=False, allowcreate=True): 368 def subrepo(ctx, path, allowwdir=False, allowcreate=True):
363 """return instance of the right subrepo class for subrepo in path""" 369 """return instance of the right subrepo class for subrepo in path"""
364 # subrepo inherently violates our import layering rules 370 # subrepo inherently violates our import layering rules
365 # because it wants to make repo objects from deep inside the stack 371 # because it wants to make repo objects from deep inside the stack
366 # so we manually delay the circular imports to not break 372 # so we manually delay the circular imports to not break
367 # scripts that don't use our demand-loading 373 # scripts that don't use our demand-loading
368 global hg 374 global hg
369 from . import hg as h 375 from . import hg as h
370 hg = h 376 hg = h
371 377
372 pathutil.pathauditor(ctx.repo().root)(path) 378 _auditsubrepopath(ctx.repo(), path)
373 state = ctx.substate[path] 379 state = ctx.substate[path]
374 if state[2] not in types: 380 if state[2] not in types:
375 raise error.Abort(_('unknown subrepo type %s') % state[2]) 381 raise error.Abort(_('unknown subrepo type %s') % state[2])
376 if allowwdir: 382 if allowwdir:
377 state = (state[0], ctx.subrev(path), state[2]) 383 state = (state[0], ctx.subrev(path), state[2])
385 # scripts that don't use our demand-loading 391 # scripts that don't use our demand-loading
386 global hg 392 global hg
387 from . import hg as h 393 from . import hg as h
388 hg = h 394 hg = h
389 395
390 pathutil.pathauditor(ctx.repo().root)(path) 396 _auditsubrepopath(ctx.repo(), path)
391 state = ctx.substate[path] 397 state = ctx.substate[path]
392 if state[2] not in types: 398 if state[2] not in types:
393 raise error.Abort(_('unknown subrepo type %s') % state[2]) 399 raise error.Abort(_('unknown subrepo type %s') % state[2])
394 subrev = '' 400 subrev = ''
395 if state[2] == 'hg': 401 if state[2] == 'hg':