xref: /linux/tools/testing/selftests/filesystems/mntns_cleanup/mntns_cleanup_test.c (revision 1c3e8cef79ea5f1415cff0d3c507e2e07b71ade8)
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