Skip to content

Commit

Permalink
restoreMountNamespace(): Restore the original root directory
Browse files Browse the repository at this point in the history
This is necessary when we're in a chroot environment, where the
process root is not the same as the root of the mount namespace
(e.g. in nixos-enter).

Fixes #7602.
  • Loading branch information
edolstra committed Jun 9, 2023
1 parent 03f9ff6 commit e54538c
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions src/libutil/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1853,17 +1853,19 @@ void setStackSize(size_t stackSize)

#if __linux__
static AutoCloseFD fdSavedMountNamespace;
static AutoCloseFD fdSavedRoot;
#endif

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
}
Expand All @@ -1876,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());
}
Expand Down

0 comments on commit e54538c

Please sign in to comment.