diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-12-21 18:03:30 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-12-22 10:52:41 +0000 |
commit | 30d5a029e4ca99c925141fd0fe3e46ae73846608 (patch) | |
tree | 05ceb383c642830afa07ddb48faa20ec3e4e22bf | |
parent | a6ff0d0665e0502a7628f73f27d80be40a8d826e (diff) | |
download | buildstream-sam/symlinks.tar.gz |
utils.py: Remove check for symlinks that overwrite the hostsam/symlinks
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.
-rw-r--r-- | buildstream/utils.py | 24 |
1 files 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): |