static void test_sc_is_ns_group_dir_private() { if (geteuid() != 0) { g_test_skip("this test needs to run as root"); return; } const char *ns_dir = sc_test_use_fake_ns_dir(); g_test_queue_destroy(unmount_dir, (char *)ns_dir); if (g_test_subprocess()) { // The temporary directory should not be private initially g_assert_false(sc_is_ns_group_dir_private()); /// do what "mount --bind /foo /foo; mount --make-private /foo" does. int err; err = mount(ns_dir, ns_dir, NULL, MS_BIND, NULL); g_assert_cmpint(err, ==, 0); err = mount(NULL, ns_dir, NULL, MS_PRIVATE, NULL); g_assert_cmpint(err, ==, 0); // The temporary directory should now be private g_assert_true(sc_is_ns_group_dir_private()); return; } g_test_trap_subprocess(NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR); g_test_trap_assert_passed(); }
static void test_sc_initialize_ns_groups() { if (geteuid() != 0) { g_test_skip("this test needs to run as root"); return; } // NOTE: this is g_test_subprocess aware! const char *ns_dir = sc_test_use_fake_ns_dir(); g_test_queue_destroy(unmount_dir, (char *)ns_dir); if (g_test_subprocess()) { // Initialize namespace groups using a fake directory. sc_initialize_ns_groups(); // Check that the fake directory is now a private mount. g_assert_true(sc_is_ns_group_dir_private()); // Check that the lock file did not leak unclosed. // Construct the name of the lock file char *lock_file __attribute__ ((cleanup(sc_cleanup_string))) = NULL; lock_file = g_strdup_printf("%s/%s", sc_ns_dir, SC_NS_LOCK_FILE); // Attempt to open and lock the lock file. int lock_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1; lock_fd = open(lock_file, O_RDWR | O_CLOEXEC | O_NOFOLLOW); g_assert_cmpint(lock_fd, !=, -1); // The non-blocking lock operation should not fail int err = flock(lock_fd, LOCK_EX | LOCK_NB); g_assert_cmpint(err, ==, 0); return; } g_test_trap_subprocess(NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR); g_test_trap_assert_passed(); }
void sc_initialize_ns_groups() { debug("creating namespace group directory %s", sc_ns_dir); if (sc_nonfatal_mkpath(sc_ns_dir, 0755) < 0) { die("cannot create namespace group directory %s", sc_ns_dir); } debug("opening namespace group directory %s", sc_ns_dir); int dir_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1; dir_fd = open(sc_ns_dir, O_DIRECTORY | O_PATH | O_CLOEXEC | O_NOFOLLOW); if (dir_fd < 0) { die("cannot open namespace group directory"); } debug("opening lock file for group directory"); int lock_fd __attribute__ ((cleanup(sc_cleanup_close))) = -1; lock_fd = openat(dir_fd, SC_NS_LOCK_FILE, O_CREAT | O_RDWR | O_CLOEXEC | O_NOFOLLOW, 0600); if (lock_fd < 0) { die("cannot open lock file for namespace group directory"); } debug("locking the namespace group directory"); sc_enable_sanity_timeout(); if (flock(lock_fd, LOCK_EX) < 0) { die("cannot acquire exclusive lock for namespace group directory"); } sc_disable_sanity_timeout(); if (!sc_is_ns_group_dir_private()) { debug ("bind mounting the namespace group directory over itself"); if (mount(sc_ns_dir, sc_ns_dir, NULL, MS_BIND | MS_REC, NULL) < 0) { die("cannot bind mount namespace group directory over itself"); } debug ("making the namespace group directory mount point private"); if (mount(NULL, sc_ns_dir, NULL, MS_PRIVATE, NULL) < 0) { die("cannot make the namespace group directory mount point private"); } } else { debug ("namespace group directory does not require intialization"); } debug("unlocking the namespace group directory"); if (flock(lock_fd, LOCK_UN) < 0) { die("cannot release lock for namespace control directory"); } }
void sc_initialize_ns_groups(void) { debug("creating namespace group directory %s", sc_ns_dir); if (sc_nonfatal_mkpath(sc_ns_dir, 0755) < 0) { die("cannot create namespace group directory %s", sc_ns_dir); } if (!sc_is_ns_group_dir_private()) { debug ("bind mounting the namespace group directory over itself"); if (mount(sc_ns_dir, sc_ns_dir, NULL, MS_BIND | MS_REC, NULL) < 0) { die("cannot bind mount namespace group directory over itself"); } debug ("making the namespace group directory mount point private"); if (mount(NULL, sc_ns_dir, NULL, MS_PRIVATE, NULL) < 0) { die("cannot make the namespace group directory mount point private"); } } else { debug ("namespace group directory does not require intialization"); } }