From 30d5a029e4ca99c925141fd0fe3e46ae73846608 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Thu, 21 Dec 2017 18:03:30 +0000 Subject: utils.py: Remove check for symlinks that overwrite the host This cannot happen in practice as we make sure that every symlink inside an artifact is relative when we create the artifact. The new integration-tests/symlink-test should ensure we don't regress there. This saves one call to os.path.realpath() for every file we stage, which makes a large performance difference. --- buildstream/utils.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/buildstream/utils.py b/buildstream/utils.py index 34d9c03be..c624c9faa 100644 --- a/buildstream/utils.py +++ b/buildstream/utils.py @@ -492,20 +492,16 @@ def _copy_directories(srcdir, destdir, target): 'directory expected: {}'.format(old_dir)) -def _ensure_real_directory(root, destpath): - # The realpath in the sandbox may refer to a file outside of the - # sandbox when any of the direcory branches are a symlink to an - # absolute path. - # - # This should not happen as we rely on relative_symlink_target() below - # when staging the actual symlinks which may lead up to this path. +def _ensure_real_directory(destpath): + # We assume here that the artifacts we have staged only contain symlinks + # with relative paths. If 'destpath' has a symlink in its path that points + # /bin for example then 'realpath' would end up pointing somewhere inside + # /bin which would cause us to try and write stuff over host OS filesystem. # + # There is too much of a performance cost incurred if we check each symlink + # here after resolving it, but integration-tests/symlinks-test should catch + # any regressions on that front. realpath = os.path.realpath(destpath) - if not realpath.startswith(os.path.realpath(root)): - raise UtilError('Destination path resolves to a path outside ' + - 'of the staging area\n\n' + - ' Destination path: {}\n'.format(destpath) + - ' Real path: {}'.format(realpath)) # Ensure the real destination path exists before trying to get the mode # of the real destination path. @@ -568,7 +564,7 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, ignore_missing= # Ensure that broken symlinks to directories have their targets # created before attempting to stage files across broken # symlink boundaries - _ensure_real_directory(destdir, os.path.dirname(destpath)) + _ensure_real_directory(os.path.dirname(destpath)) try: file_stat = os.lstat(srcpath) @@ -584,7 +580,7 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, ignore_missing= if stat.S_ISDIR(mode): # Ensure directory exists in destination if not os.path.exists(destpath): - _ensure_real_directory(destdir, destpath) + _ensure_real_directory(destpath) dest_stat = os.lstat(os.path.realpath(destpath)) if not stat.S_ISDIR(dest_stat.st_mode): -- cgit v1.2.1