1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <sched.h> 7 #include <sys/mount.h> 8 #include <sys/stat.h> 9 #include <unistd.h> 10 11 #include "../../kselftest_harness.h" 12 13 FIXTURE(mntns_cleanup) { 14 }; 15 16 FIXTURE_SETUP(mntns_cleanup) 17 { 18 if (geteuid() != 0) 19 SKIP(return, "test requires CAP_SYS_ADMIN"); 20 21 ASSERT_EQ(unshare(CLONE_NEWNS), 0); 22 ASSERT_EQ(mount("", "/", NULL, MS_REC | MS_PRIVATE, NULL), 0); 23 24 rmdir("/mnt_dir"); 25 ASSERT_EQ(mkdir("/mnt_dir", 0755), 0); 26 ASSERT_EQ(mount("tmpfs", "/mnt_dir", "tmpfs", 0, NULL), 0); 27 ASSERT_EQ(mkdir("/mnt_dir/hidden", 0755), 0); 28 ASSERT_EQ(mkdir("/mnt_dir/hidden/secret", 0755), 0); 29 ASSERT_EQ(mount("tmpfs", "/mnt_dir/hidden", "tmpfs", 0, NULL), 0); 30 } 31 32 FIXTURE_TEARDOWN(mntns_cleanup) 33 { 34 } 35 36 /* Mounts must stay connected when a mount namespace is cleaned up. */ 37 TEST_F(mntns_cleanup, keeps_mounts_connected) 38 { 39 int fd, sfd, err; 40 41 fd = open("/mnt_dir", O_PATH | O_DIRECTORY | O_CLOEXEC); 42 ASSERT_GE(fd, 0); 43 44 /* Destroy the namespace; the fd keeps /mnt_dir alive. */ 45 ASSERT_EQ(unshare(CLONE_NEWNS), 0); 46 47 sfd = openat(fd, "hidden/secret", O_RDONLY); 48 err = errno; 49 if (sfd >= 0) 50 close(sfd); 51 close(fd); 52 53 ASSERT_LT(sfd, 0) 54 TH_LOG("mount namespace teardown revealed what the overmount covered"); 55 ASSERT_EQ(err, ENOENT); 56 } 57 58 TEST_HARNESS_MAIN 59