diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/llnl/util/filesystem.py | 25 | ||||
-rw-r--r-- | lib/spack/spack/directory_layout.py | 13 |
2 files changed, 37 insertions, 1 deletions
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index ced29ad760..e58f657aea 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -423,14 +423,39 @@ def mkdirp(*paths, **kwargs): Keyword Aguments: mode (permission bits or None, optional): optional permissions to set on the created directory -- use OS default if not provided + mode_intermediate (permission bits or None, optional): + same as mode, but for newly-created intermediate directories """ mode = kwargs.get('mode', None) + mode_intermediate = kwargs.get('mode_intermediate', None) for path in paths: if not os.path.exists(path): try: + intermediate_folders = [] + if mode_intermediate is not None: + # detect missing intermediate folders + intermediate_path = os.path.dirname(path) + + while intermediate_path: + if os.path.exists(intermediate_path): + break + + intermediate_folders.append(intermediate_path) + intermediate_path = os.path.dirname(intermediate_path) + + # create folders os.makedirs(path) + + # leaf folder permissions if mode is not None: os.chmod(path, mode) + + # for intermediate folders, change mode just for newly created + # ones and if mode_intermediate has been specified, otherwise + # intermediate folders list is not populated at all and default + # OS mode will be used + for intermediate_path in reversed(intermediate_folders): + os.chmod(intermediate_path, mode_intermediate) except OSError as e: if e.errno != errno.EEXIST or not os.path.isdir(path): raise e diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py index 5ba8ac144c..35a8e4dcc5 100644 --- a/lib/spack/spack/directory_layout.py +++ b/lib/spack/spack/directory_layout.py @@ -254,15 +254,26 @@ class YamlDirectoryLayout(DirectoryLayout): # Cannot import at top of file from spack.package_prefs import get_package_dir_permissions from spack.package_prefs import get_package_group + + # Each package folder can have its own specific permissions, while + # intermediate folders (arch/compiler) are set with full access to + # everyone (0o777) and install_tree root folder is the chokepoint + # for restricting global access. + # So, whoever has access to the install_tree is allowed to install + # packages for same arch/compiler and since no data is stored in + # intermediate folders, it does not represent a security threat. group = get_package_group(spec) perms = get_package_dir_permissions(spec) - mkdirp(spec.prefix, mode=perms) + perms_intermediate = 0o777 + + mkdirp(spec.prefix, mode=perms, mode_intermediate=perms_intermediate) if group: chgrp(spec.prefix, group) # Need to reset the sticky group bit after chgrp os.chmod(spec.prefix, perms) mkdirp(self.metadata_path(spec), mode=perms) + self.write_spec(spec, self.spec_file_path(spec)) def check_installed(self, spec): |