Fix/clarify problems about mount namespaces

This commit is contained in:
Ruihan Li 2025-09-24 12:29:43 +08:00 committed by Chengjun Chen
parent 48c7c37f50
commit 89959d07df
5 changed files with 18 additions and 13 deletions

View File

@ -56,6 +56,9 @@ impl FsResolver {
///
/// Otherwise, the method will change both the `cwd` and `root` to their corresponding
/// `Path`s within the new `MountNamespace`.
//
// FIXME: This cannot fail if we clone mount namespaces and update resolvers in an atomic way.
// We currently leak this error to userspace, which is not a correct behavior.
pub fn switch_to_mnt_ns(&mut self, mnt_ns: &Arc<MountNamespace>) -> Result<()> {
if mnt_ns.owns(self.root.mount_node()) && mnt_ns.owns(self.cwd.mount_node()) {
return Ok(());

View File

@ -169,7 +169,9 @@ impl ContextSetNsAdminApi for Context<'_> {
// TODO: When setting a specific namespace,
// other dependent fields of a posix thread may also need to be updated.
*self.thread_local.borrow_fs().resolver().write() = ns_proxy.mnt_ns.new_fs_resolver();
if !Arc::ptr_eq(&thread_local_ns_proxy.unwrap().mnt_ns, &ns_proxy.mnt_ns) {
*self.thread_local.borrow_fs().resolver().write() = ns_proxy.mnt_ns.new_fs_resolver();
}
*pthread_ns_proxy = Some(ns_proxy.clone());
thread_local_ns_proxy.replace(Some(ns_proxy));

View File

@ -63,8 +63,7 @@ impl ContextUnshareAdminApi for Context<'_> {
.borrow_fs()
.resolver()
.write()
.switch_to_mnt_ns(new_ns_proxy.mnt_ns())
.unwrap();
.switch_to_mnt_ns(new_ns_proxy.mnt_ns())?;
}
*pthread_ns_proxy = Some(new_ns_proxy.clone());

View File

@ -2,15 +2,9 @@
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/syscall.h>
#include "../test.h"
@ -168,14 +162,21 @@ FN_TEST(setns_newns)
close(pipefd[1]);
char buf;
char buf[10];
TEST_SUCC(read(pipefd[0], &buf, 1));
close(pipefd[0]);
int pid_fd = TEST_SUCC(syscall(SYS_pidfd_open, child_pid, 0));
// Switch into the child's mount namespace using the pidfd.
// Switching into the child's UTS namespace will not change the CWD.
TEST_SUCC(chdir("/mnt"));
TEST_SUCC(setns(pid_fd, CLONE_NEWUTS));
TEST_RES(getcwd(buf, sizeof(buf)), strcmp(buf, "/mnt") == 0);
// Switching into the child's mount namespace will reset the CWD.
TEST_SUCC(setns(pid_fd, CLONE_NEWNS));
TEST_RES(getcwd(buf, sizeof(buf)), strcmp(buf, "/") == 0);
TEST_SUCC(close(pid_fd));
// Check if we can see the file created by the child in its namespace.
@ -188,4 +189,4 @@ FN_TEST(setns_newns)
TEST_SUCC(umount(SETNS_MNT));
TEST_SUCC(rmdir(SETNS_MNT));
}
END_TEST()
END_TEST()

View File

@ -34,7 +34,7 @@ mmap/mmap_beyond_the_file
mmap/mmap_shared_filebacked
mmap/mmap_readahead
mmap/mmap_vmrss
namepsace/mnt_ns
namespace/mnt_ns
namespace/setns
namespace/unshare
process/group_session