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