Mercurial > public > mercurial-scm > hg
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': |