1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Reading the root of an empty mount namespace holds nothing that anybody 4 * else waits for: the directory never has an entry, so a readdir stuck in 5 * the page fault of its buffer stalls neither a create nor a lookup in it. 6 */ 7 #define _GNU_SOURCE 8 #include <errno.h> 9 #include <fcntl.h> 10 #include <sched.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <unistd.h> 14 15 #include "../../kselftest_harness.h" 16 #include "../readdir_hold.h" 17 #include "empty_mntns.h" 18 TEST(readdir_blocks_nobody)19TEST(readdir_blocks_nobody) 20 { 21 struct readdir_hold hold; 22 bool stalled; 23 int dfd; 24 25 if (geteuid()) 26 SKIP(return, "test requires root"); 27 if (readdir_hold_init(&hold)) 28 SKIP(return, "test requires userfaultfd"); 29 if (unshare(UNSHARE_EMPTY_MNTNS)) { 30 readdir_hold_destroy(&hold); 31 if (errno == EINVAL) 32 SKIP(return, "UNSHARE_EMPTY_MNTNS not supported"); 33 ASSERT_TRUE(false) 34 TH_LOG("unshare(UNSHARE_EMPTY_MNTNS): %m"); 35 } 36 dfd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); 37 ASSERT_GE(dfd, 0); 38 ASSERT_EQ(readdir_hold_check(&hold, dfd, &stalled), 0); 39 /* the lookup came back while the readdir was stuck in its fault */ 40 EXPECT_FALSE(stalled); 41 close(dfd); 42 readdir_hold_destroy(&hold); 43 } 44 45 TEST_HARNESS_MAIN 46