aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 3a8309149..26f9dc8a8 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -266,6 +266,17 @@ bool pathExists(const Path & path)
return false;
}
+bool pathAccessible(const Path & path)
+{
+ try {
+ return pathExists(path);
+ } catch (SysError & e) {
+ // swallow EPERM
+ if (e.errNo == EPERM) return false;
+ throw;
+ }
+}
+
Path readLink(const Path & path)
{
@@ -1842,6 +1853,7 @@ void setStackSize(size_t stackSize)
#if __linux__
static AutoCloseFD fdSavedMountNamespace;
+static AutoCloseFD fdSavedRoot;
#endif
void saveMountNamespace()
@@ -1849,10 +1861,11 @@ void saveMountNamespace()
#if __linux__
static std::once_flag done;
std::call_once(done, []() {
- AutoCloseFD fd = open("/proc/self/ns/mnt", O_RDONLY);
- if (!fd)
+ fdSavedMountNamespace = open("/proc/self/ns/mnt", O_RDONLY);
+ if (!fdSavedMountNamespace)
throw SysError("saving parent mount namespace");
- fdSavedMountNamespace = std::move(fd);
+
+ fdSavedRoot = open("/proc/self/root", O_RDONLY);
});
#endif
}
@@ -1865,9 +1878,16 @@ void restoreMountNamespace()
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
throw SysError("restoring parent mount namespace");
- if (chdir(savedCwd.c_str()) == -1) {
- throw SysError("restoring cwd");
+
+ if (fdSavedRoot) {
+ if (fchdir(fdSavedRoot.get()))
+ throw SysError("chdir into saved root");
+ if (chroot("."))
+ throw SysError("chroot into saved root");
}
+
+ if (chdir(savedCwd.c_str()) == -1)
+ throw SysError("restoring cwd");
} catch (Error & e) {
debug(e.msg());
}