1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-07 22:33:57 +02:00

restoreMountNamespace(): Restore the original root directory

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.

(cherry picked from commit e54538c461)
(cherry picked from commit 92e198f1db)
This commit is contained in:
Eelco Dolstra 2023-06-09 16:09:29 +02:00 committed by github-actions[bot]
parent 6aba9b0c32
commit 9783bbad54

View file

@ -1800,6 +1800,7 @@ void setStackSize(size_t stackSize)
#if __linux__ #if __linux__
static AutoCloseFD fdSavedMountNamespace; static AutoCloseFD fdSavedMountNamespace;
static AutoCloseFD fdSavedRoot;
#endif #endif
void saveMountNamespace() void saveMountNamespace()
@ -1807,10 +1808,11 @@ void saveMountNamespace()
#if __linux__ #if __linux__
static std::once_flag done; static std::once_flag done;
std::call_once(done, []() { std::call_once(done, []() {
AutoCloseFD fd = open("/proc/self/ns/mnt", O_RDONLY); fdSavedMountNamespace = open("/proc/self/ns/mnt", O_RDONLY);
if (!fd) if (!fdSavedMountNamespace)
throw SysError("saving parent mount namespace"); throw SysError("saving parent mount namespace");
fdSavedMountNamespace = std::move(fd);
fdSavedRoot = open("/proc/self/root", O_RDONLY);
}); });
#endif #endif
} }
@ -1823,9 +1825,16 @@ void restoreMountNamespace()
if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1) if (fdSavedMountNamespace && setns(fdSavedMountNamespace.get(), CLONE_NEWNS) == -1)
throw SysError("restoring parent mount namespace"); 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) { } catch (Error & e) {
debug(e.msg()); debug(e.msg());
} }