Skip to content

Commit a5161ee

Browse files
author
Christian Brauner
committed
tests: add CLOSE_RANGE_UNSHARE tests
Signed-off-by: Christian Brauner <[email protected]>
1 parent 60997c3 commit a5161ee

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

tools/testing/selftests/core/close_range_test.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@
1313
#include <unistd.h>
1414

1515
#include "../kselftest_harness.h"
16+
#include "../clone3/clone3_selftests.h"
1617

1718
#ifndef __NR_close_range
1819
#define __NR_close_range -1
1920
#endif
2021

22+
#ifndef CLOSE_RANGE_UNSHARE
23+
#define CLOSE_RANGE_UNSHARE (1U << 1)
24+
#endif
25+
2126
static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
2227
unsigned int flags)
2328
{
@@ -87,4 +92,136 @@ TEST(close_range)
8792
EXPECT_EQ(-1, fcntl(open_fds[100], F_GETFL));
8893
}
8994

95+
TEST(close_range_unshare)
96+
{
97+
int i, ret, status;
98+
pid_t pid;
99+
int open_fds[101];
100+
struct clone_args args = {
101+
.flags = CLONE_FILES,
102+
.exit_signal = SIGCHLD,
103+
};
104+
105+
for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
106+
int fd;
107+
108+
fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
109+
ASSERT_GE(fd, 0) {
110+
if (errno == ENOENT)
111+
XFAIL(return, "Skipping test since /dev/null does not exist");
112+
}
113+
114+
open_fds[i] = fd;
115+
}
116+
117+
pid = sys_clone3(&args, sizeof(args));
118+
ASSERT_GE(pid, 0);
119+
120+
if (pid == 0) {
121+
ret = sys_close_range(open_fds[0], open_fds[50],
122+
CLOSE_RANGE_UNSHARE);
123+
if (ret)
124+
exit(EXIT_FAILURE);
125+
126+
for (i = 0; i <= 50; i++)
127+
if (fcntl(open_fds[i], F_GETFL) != -1)
128+
exit(EXIT_FAILURE);
129+
130+
for (i = 51; i <= 100; i++)
131+
if (fcntl(open_fds[i], F_GETFL) == -1)
132+
exit(EXIT_FAILURE);
133+
134+
/* create a couple of gaps */
135+
close(57);
136+
close(78);
137+
close(81);
138+
close(82);
139+
close(84);
140+
close(90);
141+
142+
ret = sys_close_range(open_fds[51], open_fds[92],
143+
CLOSE_RANGE_UNSHARE);
144+
if (ret)
145+
exit(EXIT_FAILURE);
146+
147+
for (i = 51; i <= 92; i++)
148+
if (fcntl(open_fds[i], F_GETFL) != -1)
149+
exit(EXIT_FAILURE);
150+
151+
for (i = 93; i <= 100; i++)
152+
if (fcntl(open_fds[i], F_GETFL) == -1)
153+
exit(EXIT_FAILURE);
154+
155+
/* test that the kernel caps and still closes all fds */
156+
ret = sys_close_range(open_fds[93], open_fds[99],
157+
CLOSE_RANGE_UNSHARE);
158+
if (ret)
159+
exit(EXIT_FAILURE);
160+
161+
for (i = 93; i <= 99; i++)
162+
if (fcntl(open_fds[i], F_GETFL) != -1)
163+
exit(EXIT_FAILURE);
164+
165+
if (fcntl(open_fds[100], F_GETFL) == -1)
166+
exit(EXIT_FAILURE);
167+
168+
ret = sys_close_range(open_fds[100], open_fds[100],
169+
CLOSE_RANGE_UNSHARE);
170+
if (ret)
171+
exit(EXIT_FAILURE);
172+
173+
if (fcntl(open_fds[100], F_GETFL) != -1)
174+
exit(EXIT_FAILURE);
175+
176+
exit(EXIT_SUCCESS);
177+
}
178+
179+
EXPECT_EQ(waitpid(pid, &status, 0), pid);
180+
EXPECT_EQ(true, WIFEXITED(status));
181+
EXPECT_EQ(0, WEXITSTATUS(status));
182+
}
183+
184+
TEST(close_range_unshare_capped)
185+
{
186+
int i, ret, status;
187+
pid_t pid;
188+
int open_fds[101];
189+
struct clone_args args = {
190+
.flags = CLONE_FILES,
191+
.exit_signal = SIGCHLD,
192+
};
193+
194+
for (i = 0; i < ARRAY_SIZE(open_fds); i++) {
195+
int fd;
196+
197+
fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
198+
ASSERT_GE(fd, 0) {
199+
if (errno == ENOENT)
200+
XFAIL(return, "Skipping test since /dev/null does not exist");
201+
}
202+
203+
open_fds[i] = fd;
204+
}
205+
206+
pid = sys_clone3(&args, sizeof(args));
207+
ASSERT_GE(pid, 0);
208+
209+
if (pid == 0) {
210+
ret = sys_close_range(open_fds[0], UINT_MAX,
211+
CLOSE_RANGE_UNSHARE);
212+
if (ret)
213+
exit(EXIT_FAILURE);
214+
215+
for (i = 0; i <= 100; i++)
216+
if (fcntl(open_fds[i], F_GETFL) != -1)
217+
exit(EXIT_FAILURE);
218+
219+
exit(EXIT_SUCCESS);
220+
}
221+
222+
EXPECT_EQ(waitpid(pid, &status, 0), pid);
223+
EXPECT_EQ(true, WIFEXITED(status));
224+
EXPECT_EQ(0, WEXITSTATUS(status));
225+
}
226+
90227
TEST_HARNESS_MAIN

0 commit comments

Comments
 (0)