summaryrefslogtreecommitdiff
path: root/src/buildstream/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildstream/utils.py')
-rw-r--r--src/buildstream/utils.py37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/buildstream/utils.py b/src/buildstream/utils.py
index 181ea1df9..7f7bf67b2 100644
--- a/src/buildstream/utils.py
+++ b/src/buildstream/utils.py
@@ -65,6 +65,11 @@ _INITIAL_NUM_THREADS_IN_MAIN_PROCESS = 1
# Number of seconds to wait for background threads to exit.
_AWAIT_THREADS_TIMEOUT_SECONDS = 5
+# The process's file mode creation mask.
+# Impossible to retrieve without temporarily changing it on POSIX.
+_UMASK = os.umask(0o777)
+os.umask(_UMASK)
+
class UtilError(BstError):
"""Raised by utility functions when system calls fail.
@@ -602,6 +607,8 @@ def save_file_atomic(
if tempdir is None:
tempdir = os.path.dirname(filename)
fd, tempname = tempfile.mkstemp(dir=tempdir)
+ # Apply mode allowed by umask
+ os.fchmod(fd, 0o666 & ~_UMASK)
os.close(fd)
f = open(
@@ -638,6 +645,17 @@ def save_file_atomic(
raise
+# get_umask():
+#
+# Get the process's file mode creation mask without changing it.
+#
+# Returns:
+# (int) The process's file mode creation mask.
+#
+def get_umask():
+ return _UMASK
+
+
# _get_dir_size():
#
# Get the disk usage of a given directory in bytes.
@@ -1002,6 +1020,13 @@ def _set_deterministic_mtime(directory):
#
# A context manager for doing work in a temporary directory.
#
+# NOTE: Unlike mkdtemp(), this method may not restrict access to other
+# users. The process umask is the only access restriction, similar
+# to mkdir().
+# This is potentially insecure. Do not create directories in /tmp
+# with this method. *Only* use this in directories whose parents are
+# more tightly controlled (i.e., non-public directories).
+#
# Args:
# dir (str): A path to a parent directory for the temporary directory
# suffix (str): A suffix for the temproary directory name
@@ -1015,7 +1040,14 @@ def _set_deterministic_mtime(directory):
# supports cleaning up the temp directory on SIGTERM.
#
@contextmanager
-def _tempdir(suffix="", prefix="tmp", dir=None): # pylint: disable=redefined-builtin
+def _tempdir(*, suffix="", prefix="tmp", dir): # pylint: disable=redefined-builtin
+ # Do not allow fallback to a global temp directory. Due to the chmod
+ # below, this method is not safe to be used in global temp
+ # directories such as /tmp.
+ assert (
+ dir
+ ), "Creating directories in the public fallback `/tmp` is dangerous. Please use a directory with tight access controls."
+
tempdir = tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=dir)
def cleanup_tempdir():
@@ -1024,6 +1056,9 @@ def _tempdir(suffix="", prefix="tmp", dir=None): # pylint: disable=redefined-bu
try:
with _signals.terminator(cleanup_tempdir):
+ # Apply mode allowed by umask
+ os.chmod(tempdir, 0o777 & ~_UMASK)
+
yield tempdir
finally:
cleanup_tempdir()