xref: /linux/tools/testing/selftests/filesystems/overlayfs/set_layers_via_fds.c (revision 9c27e5cc39bb7848051c42500207aa3a7f63558c)
1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #define __SANE_USERSPACE_TYPES__ // Use ll64
4 
5 #include <fcntl.h>
6 #include <sched.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/socket.h>
10 #include <sys/stat.h>
11 #include <sys/sysmacros.h>
12 #include <sys/mount.h>
13 #include <unistd.h>
14 
15 #include "../../kselftest_harness.h"
16 #include "../../pidfd/pidfd.h"
17 #include "log.h"
18 #include "../utils.h"
19 #include "wrappers.h"
20 
21 FIXTURE(set_layers_via_fds) {
22 	int pidfd;
23 };
24 
25 FIXTURE_SETUP(set_layers_via_fds)
26 {
27 	self->pidfd = -EBADF;
28 	EXPECT_EQ(mkdir("/set_layers_via_fds", 0755), 0);
29 }
30 
31 FIXTURE_TEARDOWN(set_layers_via_fds)
32 {
33 	if (self->pidfd >= 0) {
34 		EXPECT_EQ(sys_pidfd_send_signal(self->pidfd, SIGKILL, NULL, 0), 0);
35 		EXPECT_EQ(close(self->pidfd), 0);
36 	}
37 	umount2("/set_layers_via_fds", 0);
38 	EXPECT_EQ(rmdir("/set_layers_via_fds"), 0);
39 }
40 
41 TEST_F(set_layers_via_fds, set_layers_via_fds)
42 {
43 	int fd_context, fd_tmpfs, fd_overlay;
44 	int layer_fds[] = { [0 ... 8] = -EBADF };
45 	bool layers_found[] = { [0 ... 8] =  false };
46 	size_t len = 0;
47 	char *line = NULL;
48 	FILE *f_mountinfo;
49 
50 	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
51 	ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
52 
53 	fd_context = sys_fsopen("tmpfs", 0);
54 	ASSERT_GE(fd_context, 0);
55 
56 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
57 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
58 	ASSERT_GE(fd_tmpfs, 0);
59 	ASSERT_EQ(close(fd_context), 0);
60 
61 	ASSERT_EQ(mkdirat(fd_tmpfs, "w", 0755), 0);
62 	ASSERT_EQ(mkdirat(fd_tmpfs, "u", 0755), 0);
63 	ASSERT_EQ(mkdirat(fd_tmpfs, "l1", 0755), 0);
64 	ASSERT_EQ(mkdirat(fd_tmpfs, "l2", 0755), 0);
65 	ASSERT_EQ(mkdirat(fd_tmpfs, "l3", 0755), 0);
66 	ASSERT_EQ(mkdirat(fd_tmpfs, "l4", 0755), 0);
67 	ASSERT_EQ(mkdirat(fd_tmpfs, "d1", 0755), 0);
68 	ASSERT_EQ(mkdirat(fd_tmpfs, "d2", 0755), 0);
69 	ASSERT_EQ(mkdirat(fd_tmpfs, "d3", 0755), 0);
70 
71 	layer_fds[0] = openat(fd_tmpfs, "w", O_DIRECTORY);
72 	ASSERT_GE(layer_fds[0], 0);
73 
74 	layer_fds[1] = openat(fd_tmpfs, "u", O_DIRECTORY);
75 	ASSERT_GE(layer_fds[1], 0);
76 
77 	layer_fds[2] = openat(fd_tmpfs, "l1", O_DIRECTORY);
78 	ASSERT_GE(layer_fds[2], 0);
79 
80 	layer_fds[3] = openat(fd_tmpfs, "l2", O_DIRECTORY);
81 	ASSERT_GE(layer_fds[3], 0);
82 
83 	layer_fds[4] = openat(fd_tmpfs, "l3", O_DIRECTORY);
84 	ASSERT_GE(layer_fds[4], 0);
85 
86 	layer_fds[5] = openat(fd_tmpfs, "l4", O_DIRECTORY);
87 	ASSERT_GE(layer_fds[5], 0);
88 
89 	layer_fds[6] = openat(fd_tmpfs, "d1", O_DIRECTORY);
90 	ASSERT_GE(layer_fds[6], 0);
91 
92 	layer_fds[7] = openat(fd_tmpfs, "d2", O_DIRECTORY);
93 	ASSERT_GE(layer_fds[7], 0);
94 
95 	layer_fds[8] = openat(fd_tmpfs, "d3", O_DIRECTORY);
96 	ASSERT_GE(layer_fds[8], 0);
97 
98 	ASSERT_EQ(sys_move_mount(fd_tmpfs, "", -EBADF, "/tmp", MOVE_MOUNT_F_EMPTY_PATH), 0);
99 	ASSERT_EQ(close(fd_tmpfs), 0);
100 
101 	fd_context = sys_fsopen("overlay", 0);
102 	ASSERT_GE(fd_context, 0);
103 
104 	ASSERT_NE(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir", NULL, layer_fds[2]), 0);
105 
106 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "workdir",   NULL, layer_fds[0]), 0);
107 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "upperdir",  NULL, layer_fds[1]), 0);
108 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[2]), 0);
109 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[3]), 0);
110 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[4]), 0);
111 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[5]), 0);
112 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "datadir+",  NULL, layer_fds[6]), 0);
113 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "datadir+",  NULL, layer_fds[7]), 0);
114 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "datadir+",  NULL, layer_fds[8]), 0);
115 
116 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_STRING, "metacopy", "on", 0), 0);
117 
118 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
119 
120 	fd_overlay = sys_fsmount(fd_context, 0, 0);
121 	ASSERT_GE(fd_overlay, 0);
122 
123 	ASSERT_EQ(sys_move_mount(fd_overlay, "", -EBADF, "/set_layers_via_fds", MOVE_MOUNT_F_EMPTY_PATH), 0);
124 
125 	f_mountinfo = fopen("/proc/self/mountinfo", "r");
126 	ASSERT_NE(f_mountinfo, NULL);
127 
128 	while (getline(&line, &len, f_mountinfo) != -1) {
129 		char *haystack = line;
130 
131 		if (strstr(haystack, "workdir=/tmp/w"))
132 			layers_found[0] = true;
133 		if (strstr(haystack, "upperdir=/tmp/u"))
134 			layers_found[1] = true;
135 		if (strstr(haystack, "lowerdir+=/tmp/l1"))
136 			layers_found[2] = true;
137 		if (strstr(haystack, "lowerdir+=/tmp/l2"))
138 			layers_found[3] = true;
139 		if (strstr(haystack, "lowerdir+=/tmp/l3"))
140 			layers_found[4] = true;
141 		if (strstr(haystack, "lowerdir+=/tmp/l4"))
142 			layers_found[5] = true;
143 		if (strstr(haystack, "datadir+=/tmp/d1"))
144 			layers_found[6] = true;
145 		if (strstr(haystack, "datadir+=/tmp/d2"))
146 			layers_found[7] = true;
147 		if (strstr(haystack, "datadir+=/tmp/d3"))
148 			layers_found[8] = true;
149 	}
150 	free(line);
151 
152 	for (int i = 0; i < ARRAY_SIZE(layer_fds); i++) {
153 		ASSERT_EQ(layers_found[i], true);
154 		ASSERT_EQ(close(layer_fds[i]), 0);
155 	}
156 
157 	ASSERT_EQ(close(fd_context), 0);
158 	ASSERT_EQ(close(fd_overlay), 0);
159 	ASSERT_EQ(fclose(f_mountinfo), 0);
160 }
161 
162 TEST_F(set_layers_via_fds, set_500_layers_via_fds)
163 {
164 	int fd_context, fd_tmpfs, fd_overlay, fd_work, fd_upper, fd_lower;
165 	int layer_fds[500] = { [0 ... 499] = -EBADF };
166 
167 	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
168 	ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
169 
170 	fd_context = sys_fsopen("tmpfs", 0);
171 	ASSERT_GE(fd_context, 0);
172 
173 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
174 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
175 	ASSERT_GE(fd_tmpfs, 0);
176 	ASSERT_EQ(close(fd_context), 0);
177 
178 	for (int i = 0; i < ARRAY_SIZE(layer_fds); i++) {
179 		char path[100];
180 
181 		sprintf(path, "l%d", i);
182 		ASSERT_EQ(mkdirat(fd_tmpfs, path, 0755), 0);
183 		layer_fds[i] = openat(fd_tmpfs, path, O_DIRECTORY);
184 		ASSERT_GE(layer_fds[i], 0);
185 	}
186 
187 	ASSERT_EQ(mkdirat(fd_tmpfs, "w", 0755), 0);
188 	fd_work = openat(fd_tmpfs, "w", O_DIRECTORY);
189 	ASSERT_GE(fd_work, 0);
190 
191 	ASSERT_EQ(mkdirat(fd_tmpfs, "u", 0755), 0);
192 	fd_upper = openat(fd_tmpfs, "u", O_DIRECTORY);
193 	ASSERT_GE(fd_upper, 0);
194 
195 	ASSERT_EQ(mkdirat(fd_tmpfs, "l501", 0755), 0);
196 	fd_lower = openat(fd_tmpfs, "l501", O_DIRECTORY);
197 	ASSERT_GE(fd_lower, 0);
198 
199 	ASSERT_EQ(sys_move_mount(fd_tmpfs, "", -EBADF, "/tmp", MOVE_MOUNT_F_EMPTY_PATH), 0);
200 	ASSERT_EQ(close(fd_tmpfs), 0);
201 
202 	fd_context = sys_fsopen("overlay", 0);
203 	ASSERT_GE(fd_context, 0);
204 
205 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "workdir",   NULL, fd_work), 0);
206 	ASSERT_EQ(close(fd_work), 0);
207 
208 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "upperdir",  NULL, fd_upper), 0);
209 	ASSERT_EQ(close(fd_upper), 0);
210 
211 	for (int i = 0; i < ARRAY_SIZE(layer_fds); i++) {
212 		ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[i]), 0);
213 		ASSERT_EQ(close(layer_fds[i]), 0);
214 	}
215 
216 	ASSERT_NE(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, fd_lower), 0);
217 	ASSERT_EQ(close(fd_lower), 0);
218 
219 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
220 
221 	fd_overlay = sys_fsmount(fd_context, 0, 0);
222 	ASSERT_GE(fd_overlay, 0);
223 	ASSERT_EQ(close(fd_context), 0);
224 	ASSERT_EQ(close(fd_overlay), 0);
225 }
226 
227 TEST_F(set_layers_via_fds, set_override_creds)
228 {
229 	int fd_context, fd_tmpfs, fd_overlay;
230 	int layer_fds[] = { [0 ... 3] = -EBADF };
231 	pid_t pid;
232 	int pidfd;
233 
234 	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
235 	ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
236 
237 	fd_context = sys_fsopen("tmpfs", 0);
238 	ASSERT_GE(fd_context, 0);
239 
240 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
241 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
242 	ASSERT_GE(fd_tmpfs, 0);
243 	ASSERT_EQ(close(fd_context), 0);
244 
245 	ASSERT_EQ(mkdirat(fd_tmpfs, "w", 0755), 0);
246 	ASSERT_EQ(mkdirat(fd_tmpfs, "u", 0755), 0);
247 	ASSERT_EQ(mkdirat(fd_tmpfs, "l1", 0755), 0);
248 	ASSERT_EQ(mkdirat(fd_tmpfs, "l2", 0755), 0);
249 
250 	layer_fds[0] = openat(fd_tmpfs, "w", O_DIRECTORY);
251 	ASSERT_GE(layer_fds[0], 0);
252 
253 	layer_fds[1] = openat(fd_tmpfs, "u", O_DIRECTORY);
254 	ASSERT_GE(layer_fds[1], 0);
255 
256 	layer_fds[2] = openat(fd_tmpfs, "l1", O_DIRECTORY);
257 	ASSERT_GE(layer_fds[2], 0);
258 
259 	layer_fds[3] = openat(fd_tmpfs, "l2", O_DIRECTORY);
260 	ASSERT_GE(layer_fds[3], 0);
261 
262 	ASSERT_EQ(sys_move_mount(fd_tmpfs, "", -EBADF, "/tmp", MOVE_MOUNT_F_EMPTY_PATH), 0);
263 	ASSERT_EQ(close(fd_tmpfs), 0);
264 
265 	fd_context = sys_fsopen("overlay", 0);
266 	ASSERT_GE(fd_context, 0);
267 
268 	ASSERT_NE(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir", NULL, layer_fds[2]), 0);
269 
270 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "workdir",   NULL, layer_fds[0]), 0);
271 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "upperdir",  NULL, layer_fds[1]), 0);
272 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[2]), 0);
273 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[3]), 0);
274 
275 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_STRING, "metacopy", "on", 0), 0);
276 
277 	pid = create_child(&pidfd, 0);
278 	ASSERT_GE(pid, 0);
279 	if (pid == 0) {
280 		if (sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "override_creds", NULL, 0)) {
281 			TH_LOG("sys_fsconfig should have succeeded");
282 			_exit(EXIT_FAILURE);
283 		}
284 
285 		_exit(EXIT_SUCCESS);
286 	}
287 	ASSERT_GE(sys_waitid(P_PID, pid, NULL, WEXITED), 0);
288 	ASSERT_GE(close(pidfd), 0);
289 
290 	pid = create_child(&pidfd, 0);
291 	ASSERT_GE(pid, 0);
292 	if (pid == 0) {
293 		if (sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "nooverride_creds", NULL, 0)) {
294 			TH_LOG("sys_fsconfig should have succeeded");
295 			_exit(EXIT_FAILURE);
296 		}
297 
298 		_exit(EXIT_SUCCESS);
299 	}
300 	ASSERT_GE(sys_waitid(P_PID, pid, NULL, WEXITED), 0);
301 	ASSERT_GE(close(pidfd), 0);
302 
303 	pid = create_child(&pidfd, 0);
304 	ASSERT_GE(pid, 0);
305 	if (pid == 0) {
306 		if (sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "override_creds", NULL, 0)) {
307 			TH_LOG("sys_fsconfig should have succeeded");
308 			_exit(EXIT_FAILURE);
309 		}
310 
311 		_exit(EXIT_SUCCESS);
312 	}
313 	ASSERT_GE(sys_waitid(P_PID, pid, NULL, WEXITED), 0);
314 	ASSERT_GE(close(pidfd), 0);
315 
316 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
317 
318 	fd_overlay = sys_fsmount(fd_context, 0, 0);
319 	ASSERT_GE(fd_overlay, 0);
320 
321 	ASSERT_EQ(sys_move_mount(fd_overlay, "", -EBADF, "/set_layers_via_fds", MOVE_MOUNT_F_EMPTY_PATH), 0);
322 
323 	ASSERT_EQ(close(fd_context), 0);
324 	ASSERT_EQ(close(fd_overlay), 0);
325 }
326 
327 TEST_F(set_layers_via_fds, set_override_creds_invalid)
328 {
329 	int fd_context, fd_tmpfs, fd_overlay, ret;
330 	int layer_fds[] = { [0 ... 3] = -EBADF };
331 	pid_t pid;
332 	int fd_userns1, fd_userns2;
333 	int ipc_sockets[2];
334 	char c;
335 	const unsigned int predictable_fd_context_nr = 123;
336 
337 	fd_userns1 = get_userns_fd(0, 0, 10000);
338 	ASSERT_GE(fd_userns1, 0);
339 
340 	fd_userns2 = get_userns_fd(0, 1234, 10000);
341 	ASSERT_GE(fd_userns2, 0);
342 
343 	ret = socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ipc_sockets);
344 	ASSERT_GE(ret, 0);
345 
346 	pid = create_child(&self->pidfd, 0);
347 	ASSERT_GE(pid, 0);
348 	if (pid == 0) {
349 		if (close(ipc_sockets[0])) {
350 			TH_LOG("close should have succeeded");
351 			_exit(EXIT_FAILURE);
352 		}
353 
354 		if (!switch_userns(fd_userns2, 0, 0, false)) {
355 			TH_LOG("switch_userns should have succeeded");
356 			_exit(EXIT_FAILURE);
357 		}
358 
359 		if (read_nointr(ipc_sockets[1], &c, 1) != 1) {
360 			TH_LOG("read_nointr should have succeeded");
361 			_exit(EXIT_FAILURE);
362 		}
363 
364 		if (close(ipc_sockets[1])) {
365 			TH_LOG("close should have succeeded");
366 			_exit(EXIT_FAILURE);
367 		}
368 
369 		if (!sys_fsconfig(predictable_fd_context_nr, FSCONFIG_SET_FLAG, "override_creds", NULL, 0)) {
370 			TH_LOG("sys_fsconfig should have failed");
371 			_exit(EXIT_FAILURE);
372 		}
373 
374 		_exit(EXIT_SUCCESS);
375 	}
376 
377 	ASSERT_EQ(close(ipc_sockets[1]), 0);
378 	ASSERT_EQ(switch_userns(fd_userns1, 0, 0, false), true);
379 	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
380 	ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
381 
382 	fd_context = sys_fsopen("tmpfs", 0);
383 	ASSERT_GE(fd_context, 0);
384 
385 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
386 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
387 	ASSERT_GE(fd_tmpfs, 0);
388 	ASSERT_EQ(close(fd_context), 0);
389 
390 	ASSERT_EQ(mkdirat(fd_tmpfs, "w", 0755), 0);
391 	ASSERT_EQ(mkdirat(fd_tmpfs, "u", 0755), 0);
392 	ASSERT_EQ(mkdirat(fd_tmpfs, "l1", 0755), 0);
393 	ASSERT_EQ(mkdirat(fd_tmpfs, "l2", 0755), 0);
394 
395 	layer_fds[0] = openat(fd_tmpfs, "w", O_DIRECTORY);
396 	ASSERT_GE(layer_fds[0], 0);
397 
398 	layer_fds[1] = openat(fd_tmpfs, "u", O_DIRECTORY);
399 	ASSERT_GE(layer_fds[1], 0);
400 
401 	layer_fds[2] = openat(fd_tmpfs, "l1", O_DIRECTORY);
402 	ASSERT_GE(layer_fds[2], 0);
403 
404 	layer_fds[3] = openat(fd_tmpfs, "l2", O_DIRECTORY);
405 	ASSERT_GE(layer_fds[3], 0);
406 
407 	ASSERT_EQ(sys_move_mount(fd_tmpfs, "", -EBADF, "/tmp", MOVE_MOUNT_F_EMPTY_PATH), 0);
408 	ASSERT_EQ(close(fd_tmpfs), 0);
409 
410 	fd_context = sys_fsopen("overlay", 0);
411 	ASSERT_GE(fd_context, 0);
412 	ASSERT_EQ(dup3(fd_context, predictable_fd_context_nr, 0), predictable_fd_context_nr);
413 	ASSERT_EQ(close(fd_context), 0);
414 	fd_context = predictable_fd_context_nr;
415 	ASSERT_EQ(write_nointr(ipc_sockets[0], "1", 1), 1);
416 	ASSERT_EQ(close(ipc_sockets[0]), 0);
417 
418 	ASSERT_EQ(wait_for_pid(pid), 0);
419 	ASSERT_EQ(close(self->pidfd), 0);
420 	self->pidfd = -EBADF;
421 
422 	ASSERT_NE(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir", NULL, layer_fds[2]), 0);
423 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "workdir",   NULL, layer_fds[0]), 0);
424 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "upperdir",  NULL, layer_fds[1]), 0);
425 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[2]), 0);
426 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[3]), 0);
427 
428 	for (int i = 0; i < ARRAY_SIZE(layer_fds); i++)
429 		ASSERT_EQ(close(layer_fds[i]), 0);
430 
431 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "userxattr", NULL, 0), 0);
432 
433 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
434 
435 	fd_overlay = sys_fsmount(fd_context, 0, 0);
436 	ASSERT_GE(fd_overlay, 0);
437 
438 	ASSERT_EQ(sys_move_mount(fd_overlay, "", -EBADF, "/set_layers_via_fds", MOVE_MOUNT_F_EMPTY_PATH), 0);
439 
440 	ASSERT_EQ(close(fd_context), 0);
441 	ASSERT_EQ(close(fd_overlay), 0);
442 	ASSERT_EQ(close(fd_userns1), 0);
443 	ASSERT_EQ(close(fd_userns2), 0);
444 }
445 
446 TEST_F(set_layers_via_fds, set_override_creds_nomknod)
447 {
448 	int fd_context, fd_tmpfs, fd_overlay;
449 	int layer_fds[] = { [0 ... 3] = -EBADF };
450 	pid_t pid;
451 	int pidfd;
452 
453 	ASSERT_EQ(unshare(CLONE_NEWNS), 0);
454 	ASSERT_EQ(sys_mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL), 0);
455 
456 	fd_context = sys_fsopen("tmpfs", 0);
457 	ASSERT_GE(fd_context, 0);
458 
459 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
460 	fd_tmpfs = sys_fsmount(fd_context, 0, 0);
461 	ASSERT_GE(fd_tmpfs, 0);
462 	ASSERT_EQ(close(fd_context), 0);
463 
464 	ASSERT_EQ(mkdirat(fd_tmpfs, "w", 0755), 0);
465 	ASSERT_EQ(mkdirat(fd_tmpfs, "u", 0755), 0);
466 	ASSERT_EQ(mkdirat(fd_tmpfs, "l1", 0755), 0);
467 	ASSERT_EQ(mkdirat(fd_tmpfs, "l2", 0755), 0);
468 
469 	layer_fds[0] = openat(fd_tmpfs, "w", O_DIRECTORY);
470 	ASSERT_GE(layer_fds[0], 0);
471 
472 	layer_fds[1] = openat(fd_tmpfs, "u", O_DIRECTORY);
473 	ASSERT_GE(layer_fds[1], 0);
474 
475 	layer_fds[2] = openat(fd_tmpfs, "l1", O_DIRECTORY);
476 	ASSERT_GE(layer_fds[2], 0);
477 
478 	layer_fds[3] = openat(fd_tmpfs, "l2", O_DIRECTORY);
479 	ASSERT_GE(layer_fds[3], 0);
480 
481 	ASSERT_EQ(sys_move_mount(fd_tmpfs, "", -EBADF, "/tmp", MOVE_MOUNT_F_EMPTY_PATH), 0);
482 	ASSERT_EQ(close(fd_tmpfs), 0);
483 
484 	fd_context = sys_fsopen("overlay", 0);
485 	ASSERT_GE(fd_context, 0);
486 
487 	ASSERT_NE(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir", NULL, layer_fds[2]), 0);
488 
489 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "workdir",   NULL, layer_fds[0]), 0);
490 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "upperdir",  NULL, layer_fds[1]), 0);
491 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[2]), 0);
492 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FD, "lowerdir+", NULL, layer_fds[3]), 0);
493 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "userxattr", NULL, 0), 0);
494 
495 	pid = create_child(&pidfd, 0);
496 	ASSERT_GE(pid, 0);
497 	if (pid == 0) {
498 		if (!cap_down(CAP_MKNOD))
499 			_exit(EXIT_FAILURE);
500 
501 		if (!cap_down(CAP_SYS_ADMIN))
502 			_exit(EXIT_FAILURE);
503 
504 		if (sys_fsconfig(fd_context, FSCONFIG_SET_FLAG, "override_creds", NULL, 0))
505 			_exit(EXIT_FAILURE);
506 
507 		_exit(EXIT_SUCCESS);
508 	}
509 	ASSERT_EQ(sys_waitid(P_PID, pid, NULL, WEXITED), 0);
510 	ASSERT_GE(close(pidfd), 0);
511 
512 	ASSERT_EQ(sys_fsconfig(fd_context, FSCONFIG_CMD_CREATE, NULL, NULL, 0), 0);
513 
514 	fd_overlay = sys_fsmount(fd_context, 0, 0);
515 	ASSERT_GE(fd_overlay, 0);
516 
517 	ASSERT_EQ(sys_move_mount(fd_overlay, "", -EBADF, "/set_layers_via_fds", MOVE_MOUNT_F_EMPTY_PATH), 0);
518 	ASSERT_EQ(mknodat(fd_overlay, "dev-zero", S_IFCHR | 0644, makedev(1, 5)), -1);
519 	ASSERT_EQ(errno, EPERM);
520 
521 	ASSERT_EQ(close(fd_context), 0);
522 	ASSERT_EQ(close(fd_overlay), 0);
523 }
524 
525 TEST_HARNESS_MAIN
526