xref: /linux/tools/testing/selftests/landlock/fs_test.c (revision 7199989f3f3194d653b024ce8e79cea6b15e38b9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Landlock tests - Filesystem
4  *
5  * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
6  * Copyright © 2020 ANSSI
7  * Copyright © 2020-2022 Microsoft Corporation
8  */
9 
10 #define _GNU_SOURCE
11 #include <asm/termbits.h>
12 #include <fcntl.h>
13 #include <libgen.h>
14 #include <linux/fiemap.h>
15 #include <linux/landlock.h>
16 #include <linux/magic.h>
17 #include <sched.h>
18 #include <stddef.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/capability.h>
22 #include <sys/ioctl.h>
23 #include <sys/mount.h>
24 #include <sys/prctl.h>
25 #include <sys/resource.h>
26 #include <sys/sendfile.h>
27 #include <sys/socket.h>
28 #include <sys/stat.h>
29 #include <sys/sysmacros.h>
30 #include <sys/un.h>
31 #include <sys/vfs.h>
32 #include <unistd.h>
33 
34 /*
35  * Intentionally included last to work around header conflict.
36  * See https://sourceware.org/glibc/wiki/Synchronizing_Headers.
37  */
38 #include <linux/fs.h>
39 #include <linux/mount.h>
40 
41 /* Defines AT_EXECVE_CHECK without type conflicts. */
42 #define _ASM_GENERIC_FCNTL_H
43 #include <linux/fcntl.h>
44 
45 #include "audit.h"
46 #include "common.h"
47 #include "trace.h"
48 
49 #define TRACE_TASK "fs_test"
50 
51 #ifndef renameat2
52 int renameat2(int olddirfd, const char *oldpath, int newdirfd,
53 	      const char *newpath, unsigned int flags)
54 {
55 	return syscall(__NR_renameat2, olddirfd, oldpath, newdirfd, newpath,
56 		       flags);
57 }
58 #endif
59 
60 #ifndef open_tree
61 int open_tree(int dfd, const char *filename, unsigned int flags)
62 {
63 	return syscall(__NR_open_tree, dfd, filename, flags);
64 }
65 #endif
66 
67 static int sys_execveat(int dirfd, const char *pathname, char *const argv[],
68 			char *const envp[], int flags)
69 {
70 	return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags);
71 }
72 
73 #ifndef RENAME_EXCHANGE
74 #define RENAME_EXCHANGE (1 << 1)
75 #endif
76 
77 static const char bin_true[] = "./true";
78 
79 /* Paths (sibling number and depth) */
80 static const char dir_s1d1[] = TMP_DIR "/s1d1";
81 static const char file1_s1d1[] = TMP_DIR "/s1d1/f1";
82 static const char file2_s1d1[] = TMP_DIR "/s1d1/f2";
83 static const char dir_s1d2[] = TMP_DIR "/s1d1/s1d2";
84 static const char file1_s1d2[] = TMP_DIR "/s1d1/s1d2/f1";
85 static const char file2_s1d2[] = TMP_DIR "/s1d1/s1d2/f2";
86 static const char dir_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3";
87 static const char file1_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f1";
88 static const char file2_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f2";
89 
90 static const char dir_s2d1[] = TMP_DIR "/s2d1";
91 static const char file1_s2d1[] = TMP_DIR "/s2d1/f1";
92 static const char dir_s2d2[] = TMP_DIR "/s2d1/s2d2";
93 static const char file1_s2d2[] = TMP_DIR "/s2d1/s2d2/f1";
94 static const char dir_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3";
95 static const char file1_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f1";
96 static const char file2_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f2";
97 
98 static const char dir_s3d1[] = TMP_DIR "/s3d1";
99 static const char file1_s3d1[] = TMP_DIR "/s3d1/f1";
100 /* dir_s3d2 is a mount point. */
101 static const char dir_s3d2[] = TMP_DIR "/s3d1/s3d2";
102 static const char dir_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3";
103 static const char file1_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3/f1";
104 static const char dir_s3d4[] = TMP_DIR "/s3d1/s3d2/s3d4";
105 static const char file1_s3d4[] = TMP_DIR "/s3d1/s3d2/s3d4/f1";
106 
107 /*
108  * layout1 hierarchy:
109  *
110  * tmp
111  * ├── s1d1
112  * │   ├── f1
113  * │   ├── f2
114  * │   └── s1d2
115  * │       ├── f1
116  * │       ├── f2
117  * │       └── s1d3
118  * │           ├── f1
119  * │           └── f2
120  * ├── s2d1
121  * │   ├── f1
122  * │   └── s2d2
123  * │       ├── f1
124  * │       └── s2d3
125  * │           ├── f1
126  * │           └── f2
127  * └── s3d1
128  *     ├── f1
129  *     └── s3d2 [mount point]
130  *         ├── s3d3
131  *         │   └── f1
132  *         └── s3d4
133  *             └── f1
134  */
135 
136 static bool fgrep(FILE *const inf, const char *const str)
137 {
138 	char line[32];
139 	const int slen = strlen(str);
140 
141 	while (!feof(inf)) {
142 		if (!fgets(line, sizeof(line), inf))
143 			break;
144 		if (strncmp(line, str, slen))
145 			continue;
146 
147 		return true;
148 	}
149 
150 	return false;
151 }
152 
153 static bool supports_filesystem(const char *const filesystem)
154 {
155 	char str[32];
156 	int len;
157 	bool res = true;
158 	FILE *const inf = fopen("/proc/filesystems", "r");
159 
160 	/*
161 	 * Consider that the filesystem is supported if we cannot get the
162 	 * supported ones.
163 	 */
164 	if (!inf)
165 		return true;
166 
167 	/* filesystem can be null for bind mounts. */
168 	if (!filesystem)
169 		goto out;
170 
171 	len = snprintf(str, sizeof(str), "nodev\t%s\n", filesystem);
172 	if (len >= sizeof(str))
173 		/* Ignores too-long filesystem names. */
174 		goto out;
175 
176 	res = fgrep(inf, str);
177 
178 out:
179 	fclose(inf);
180 	return res;
181 }
182 
183 static bool cwd_matches_fs(unsigned int fs_magic)
184 {
185 	struct statfs statfs_buf;
186 
187 	if (!fs_magic)
188 		return true;
189 
190 	if (statfs(".", &statfs_buf))
191 		return true;
192 
193 	return statfs_buf.f_type == fs_magic;
194 }
195 
196 static void mkdir_parents(struct __test_metadata *const _metadata,
197 			  const char *const path)
198 {
199 	char *walker;
200 	const char *parent;
201 	int i, err;
202 
203 	ASSERT_NE(path[0], '\0');
204 	walker = strdup(path);
205 	ASSERT_NE(NULL, walker);
206 	parent = walker;
207 	for (i = 1; walker[i]; i++) {
208 		if (walker[i] != '/')
209 			continue;
210 		walker[i] = '\0';
211 		err = mkdir(parent, 0700);
212 		ASSERT_FALSE(err && errno != EEXIST)
213 		{
214 			TH_LOG("Failed to create directory \"%s\": %s", parent,
215 			       strerror(errno));
216 		}
217 		walker[i] = '/';
218 	}
219 	free(walker);
220 }
221 
222 static void create_directory(struct __test_metadata *const _metadata,
223 			     const char *const path)
224 {
225 	mkdir_parents(_metadata, path);
226 	ASSERT_EQ(0, mkdir(path, 0700))
227 	{
228 		TH_LOG("Failed to create directory \"%s\": %s", path,
229 		       strerror(errno));
230 	}
231 }
232 
233 static void create_file(struct __test_metadata *const _metadata,
234 			const char *const path)
235 {
236 	mkdir_parents(_metadata, path);
237 	ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0))
238 	{
239 		TH_LOG("Failed to create file \"%s\": %s", path,
240 		       strerror(errno));
241 	}
242 }
243 
244 static int remove_path(const char *const path)
245 {
246 	char *walker;
247 	int i, ret, err = 0;
248 
249 	walker = strdup(path);
250 	if (!walker) {
251 		err = ENOMEM;
252 		goto out;
253 	}
254 	if (unlink(path) && rmdir(path)) {
255 		if (errno != ENOENT && errno != ENOTDIR)
256 			err = errno;
257 		goto out;
258 	}
259 	for (i = strlen(walker); i > 0; i--) {
260 		if (walker[i] != '/')
261 			continue;
262 		walker[i] = '\0';
263 		ret = rmdir(walker);
264 		if (ret) {
265 			if (errno != ENOTEMPTY && errno != EBUSY)
266 				err = errno;
267 			goto out;
268 		}
269 		if (strcmp(walker, TMP_DIR) == 0)
270 			goto out;
271 	}
272 
273 out:
274 	free(walker);
275 	return err;
276 }
277 
278 struct mnt_opt {
279 	const char *const source;
280 	const char *const type;
281 	const unsigned long flags;
282 	const char *const data;
283 };
284 
285 #define MNT_TMP_DATA "size=4m,mode=700"
286 
287 static const struct mnt_opt mnt_tmp = {
288 	.type = "tmpfs",
289 	.data = MNT_TMP_DATA,
290 };
291 
292 static int mount_opt(const struct mnt_opt *const mnt, const char *const target)
293 {
294 	return mount(mnt->source ?: mnt->type, target, mnt->type, mnt->flags,
295 		     mnt->data);
296 }
297 
298 static void prepare_layout_opt(struct __test_metadata *const _metadata,
299 			       const struct mnt_opt *const mnt)
300 {
301 	disable_caps(_metadata);
302 	umask(0077);
303 	create_directory(_metadata, TMP_DIR);
304 
305 	/*
306 	 * Do not pollute the rest of the system: creates a private mount point
307 	 * for tests relying on pivot_root(2) and move_mount(2).
308 	 */
309 	set_cap(_metadata, CAP_SYS_ADMIN);
310 	ASSERT_EQ(0, unshare(CLONE_NEWNS | CLONE_NEWCGROUP));
311 	ASSERT_EQ(0, mount_opt(mnt, TMP_DIR))
312 	{
313 		TH_LOG("Failed to mount the %s filesystem: %s", mnt->type,
314 		       strerror(errno));
315 		/*
316 		 * FIXTURE_TEARDOWN() is not called when FIXTURE_SETUP()
317 		 * failed, so we need to explicitly do a minimal cleanup to
318 		 * avoid cascading errors with other tests that don't depend on
319 		 * the same filesystem.
320 		 */
321 		remove_path(TMP_DIR);
322 	}
323 	ASSERT_EQ(0, mount(NULL, TMP_DIR, NULL, MS_PRIVATE | MS_REC, NULL));
324 	clear_cap(_metadata, CAP_SYS_ADMIN);
325 }
326 
327 static void prepare_layout(struct __test_metadata *const _metadata)
328 {
329 	prepare_layout_opt(_metadata, &mnt_tmp);
330 }
331 
332 static void cleanup_layout(struct __test_metadata *const _metadata)
333 {
334 	set_cap(_metadata, CAP_SYS_ADMIN);
335 	if (umount(TMP_DIR)) {
336 		/*
337 		 * According to the test environment, the mount point of the
338 		 * current directory may be shared or not, which changes the
339 		 * visibility of the nested TMP_DIR mount point for the test's
340 		 * parent process doing this cleanup.
341 		 */
342 		ASSERT_EQ(EINVAL, errno);
343 	}
344 	clear_cap(_metadata, CAP_SYS_ADMIN);
345 	EXPECT_EQ(0, remove_path(TMP_DIR));
346 }
347 
348 /* clang-format off */
349 FIXTURE(layout0) {};
350 /* clang-format on */
351 
352 FIXTURE_SETUP(layout0)
353 {
354 	prepare_layout(_metadata);
355 }
356 
357 FIXTURE_TEARDOWN_PARENT(layout0)
358 {
359 	cleanup_layout(_metadata);
360 }
361 
362 static void create_layout1(struct __test_metadata *const _metadata)
363 {
364 	create_file(_metadata, file1_s1d1);
365 	create_file(_metadata, file1_s1d2);
366 	create_file(_metadata, file1_s1d3);
367 	create_file(_metadata, file2_s1d1);
368 	create_file(_metadata, file2_s1d2);
369 	create_file(_metadata, file2_s1d3);
370 
371 	create_file(_metadata, file1_s2d1);
372 	create_file(_metadata, file1_s2d2);
373 	create_file(_metadata, file1_s2d3);
374 	create_file(_metadata, file2_s2d3);
375 
376 	create_file(_metadata, file1_s3d1);
377 	create_directory(_metadata, dir_s3d2);
378 	set_cap(_metadata, CAP_SYS_ADMIN);
379 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
380 	clear_cap(_metadata, CAP_SYS_ADMIN);
381 
382 	create_file(_metadata, file1_s3d3);
383 	create_file(_metadata, file1_s3d4);
384 }
385 
386 static void remove_layout1(struct __test_metadata *const _metadata)
387 {
388 	EXPECT_EQ(0, remove_path(file2_s1d3));
389 	EXPECT_EQ(0, remove_path(file2_s1d2));
390 	EXPECT_EQ(0, remove_path(file2_s1d1));
391 	EXPECT_EQ(0, remove_path(file1_s1d3));
392 	EXPECT_EQ(0, remove_path(file1_s1d2));
393 	EXPECT_EQ(0, remove_path(file1_s1d1));
394 	EXPECT_EQ(0, remove_path(dir_s1d3));
395 
396 	EXPECT_EQ(0, remove_path(file2_s2d3));
397 	EXPECT_EQ(0, remove_path(file1_s2d3));
398 	EXPECT_EQ(0, remove_path(file1_s2d2));
399 	EXPECT_EQ(0, remove_path(file1_s2d1));
400 	EXPECT_EQ(0, remove_path(dir_s2d2));
401 
402 	EXPECT_EQ(0, remove_path(file1_s3d1));
403 	EXPECT_EQ(0, remove_path(file1_s3d3));
404 	EXPECT_EQ(0, remove_path(file1_s3d4));
405 	set_cap(_metadata, CAP_SYS_ADMIN);
406 	umount(dir_s3d2);
407 	clear_cap(_metadata, CAP_SYS_ADMIN);
408 	EXPECT_EQ(0, remove_path(dir_s3d2));
409 }
410 
411 /* clang-format off */
412 FIXTURE(layout1) {};
413 /* clang-format on */
414 
415 FIXTURE_SETUP(layout1)
416 {
417 	prepare_layout(_metadata);
418 
419 	create_layout1(_metadata);
420 }
421 
422 FIXTURE_TEARDOWN_PARENT(layout1)
423 {
424 	remove_layout1(_metadata);
425 
426 	cleanup_layout(_metadata);
427 }
428 
429 /*
430  * This helper enables to use the ASSERT_* macros and print the line number
431  * pointing to the test caller.
432  */
433 static int test_open_rel(const int dirfd, const char *const path,
434 			 const int flags)
435 {
436 	int fd;
437 
438 	/* Works with file and directories. */
439 	fd = openat(dirfd, path, flags | O_CLOEXEC);
440 	if (fd < 0)
441 		return errno;
442 	/*
443 	 * Mixing error codes from close(2) and open(2) should not lead to any
444 	 * (access type) confusion for this test.
445 	 */
446 	if (close(fd) != 0)
447 		return errno;
448 	return 0;
449 }
450 
451 static int test_open(const char *const path, const int flags)
452 {
453 	return test_open_rel(AT_FDCWD, path, flags);
454 }
455 
456 TEST_F_FORK(layout1, no_restriction)
457 {
458 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
459 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
460 	ASSERT_EQ(0, test_open(file2_s1d1, O_RDONLY));
461 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
462 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
463 	ASSERT_EQ(0, test_open(file2_s1d2, O_RDONLY));
464 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
465 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
466 
467 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
468 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
469 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
470 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
471 	ASSERT_EQ(0, test_open(dir_s2d3, O_RDONLY));
472 	ASSERT_EQ(0, test_open(file1_s2d3, O_RDONLY));
473 
474 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
475 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
476 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
477 }
478 
479 TEST_F_FORK(layout1, inval)
480 {
481 	struct landlock_path_beneath_attr path_beneath = {
482 		.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
483 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
484 		.parent_fd = -1,
485 	};
486 	struct landlock_ruleset_attr ruleset_attr = {
487 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
488 				     LANDLOCK_ACCESS_FS_WRITE_FILE,
489 	};
490 	int ruleset_fd;
491 
492 	path_beneath.parent_fd =
493 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
494 	ASSERT_LE(0, path_beneath.parent_fd);
495 
496 	ruleset_fd = open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
497 	ASSERT_LE(0, ruleset_fd);
498 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
499 					&path_beneath, 0));
500 	/* Returns EBADF because ruleset_fd is not a landlock-ruleset FD. */
501 	ASSERT_EQ(EBADF, errno);
502 	ASSERT_EQ(0, close(ruleset_fd));
503 
504 	ruleset_fd = open(dir_s1d1, O_DIRECTORY | O_CLOEXEC);
505 	ASSERT_LE(0, ruleset_fd);
506 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
507 					&path_beneath, 0));
508 	/* Returns EBADFD because ruleset_fd is not a valid ruleset. */
509 	ASSERT_EQ(EBADFD, errno);
510 	ASSERT_EQ(0, close(ruleset_fd));
511 
512 	/* Gets a real ruleset. */
513 	ruleset_fd =
514 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
515 	ASSERT_LE(0, ruleset_fd);
516 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
517 				       &path_beneath, 0));
518 	ASSERT_EQ(0, close(path_beneath.parent_fd));
519 
520 	/* Tests without O_PATH. */
521 	path_beneath.parent_fd = open(dir_s1d2, O_DIRECTORY | O_CLOEXEC);
522 	ASSERT_LE(0, path_beneath.parent_fd);
523 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
524 				       &path_beneath, 0));
525 	ASSERT_EQ(0, close(path_beneath.parent_fd));
526 
527 	/* Tests with a ruleset FD. */
528 	path_beneath.parent_fd = ruleset_fd;
529 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
530 					&path_beneath, 0));
531 	ASSERT_EQ(EBADFD, errno);
532 
533 	/* Checks unhandled allowed_access. */
534 	path_beneath.parent_fd =
535 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
536 	ASSERT_LE(0, path_beneath.parent_fd);
537 
538 	/* Test with legitimate values. */
539 	path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_EXECUTE;
540 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
541 					&path_beneath, 0));
542 	ASSERT_EQ(EINVAL, errno);
543 	path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_EXECUTE;
544 
545 	/* Tests with denied-by-default access right. */
546 	path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_REFER;
547 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
548 					&path_beneath, 0));
549 	ASSERT_EQ(EINVAL, errno);
550 	path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_REFER;
551 
552 	/* Test with unknown (64-bits) value. */
553 	path_beneath.allowed_access |= (1ULL << 60);
554 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
555 					&path_beneath, 0));
556 	ASSERT_EQ(EINVAL, errno);
557 	path_beneath.allowed_access &= ~(1ULL << 60);
558 
559 	/* Test with no access. */
560 	path_beneath.allowed_access = 0;
561 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
562 					&path_beneath, 0));
563 	ASSERT_EQ(ENOMSG, errno);
564 	path_beneath.allowed_access &= ~(1ULL << 60);
565 
566 	ASSERT_EQ(0, close(path_beneath.parent_fd));
567 
568 	/* Enforces the ruleset. */
569 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
570 	ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
571 
572 	ASSERT_EQ(0, close(ruleset_fd));
573 }
574 
575 /* clang-format off */
576 
577 #define ACCESS_FILE ( \
578 	LANDLOCK_ACCESS_FS_EXECUTE | \
579 	LANDLOCK_ACCESS_FS_WRITE_FILE | \
580 	LANDLOCK_ACCESS_FS_READ_FILE | \
581 	LANDLOCK_ACCESS_FS_TRUNCATE | \
582 	LANDLOCK_ACCESS_FS_IOCTL_DEV | \
583 	LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
584 
585 #define ACCESS_LAST LANDLOCK_ACCESS_FS_RESOLVE_UNIX
586 
587 #define ACCESS_ALL ( \
588 	ACCESS_FILE | \
589 	LANDLOCK_ACCESS_FS_READ_DIR | \
590 	LANDLOCK_ACCESS_FS_REMOVE_DIR | \
591 	LANDLOCK_ACCESS_FS_REMOVE_FILE | \
592 	LANDLOCK_ACCESS_FS_MAKE_CHAR | \
593 	LANDLOCK_ACCESS_FS_MAKE_DIR | \
594 	LANDLOCK_ACCESS_FS_MAKE_REG | \
595 	LANDLOCK_ACCESS_FS_MAKE_SOCK | \
596 	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
597 	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
598 	LANDLOCK_ACCESS_FS_MAKE_SYM | \
599 	LANDLOCK_ACCESS_FS_REFER)
600 
601 /* clang-format on */
602 
603 TEST_F_FORK(layout1, file_and_dir_access_rights)
604 {
605 	__u64 access;
606 	int err;
607 	struct landlock_path_beneath_attr path_beneath_file = {},
608 					  path_beneath_dir = {};
609 	struct landlock_ruleset_attr ruleset_attr = {
610 		.handled_access_fs = ACCESS_ALL,
611 	};
612 	const int ruleset_fd =
613 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
614 
615 	ASSERT_LE(0, ruleset_fd);
616 
617 	/* Tests access rights for files. */
618 	path_beneath_file.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
619 	ASSERT_LE(0, path_beneath_file.parent_fd);
620 
621 	/* Tests access rights for directories. */
622 	path_beneath_dir.parent_fd =
623 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
624 	ASSERT_LE(0, path_beneath_dir.parent_fd);
625 
626 	for (access = 1; access <= ACCESS_LAST; access <<= 1) {
627 		path_beneath_dir.allowed_access = access;
628 		ASSERT_EQ(0, landlock_add_rule(ruleset_fd,
629 					       LANDLOCK_RULE_PATH_BENEATH,
630 					       &path_beneath_dir, 0));
631 
632 		path_beneath_file.allowed_access = access;
633 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
634 					&path_beneath_file, 0);
635 		if (access & ACCESS_FILE) {
636 			ASSERT_EQ(0, err);
637 		} else {
638 			ASSERT_EQ(-1, err);
639 			ASSERT_EQ(EINVAL, errno);
640 		}
641 	}
642 	ASSERT_EQ(0, close(path_beneath_file.parent_fd));
643 	ASSERT_EQ(0, close(path_beneath_dir.parent_fd));
644 	ASSERT_EQ(0, close(ruleset_fd));
645 }
646 
647 TEST_F_FORK(layout0, ruleset_with_unknown_access)
648 {
649 	__u64 access_mask;
650 
651 	for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST;
652 	     access_mask >>= 1) {
653 		struct landlock_ruleset_attr ruleset_attr = {
654 			.handled_access_fs = access_mask,
655 		};
656 
657 		ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr,
658 						      sizeof(ruleset_attr), 0));
659 		ASSERT_EQ(EINVAL, errno);
660 	}
661 }
662 
663 TEST_F_FORK(layout0, rule_with_unknown_access)
664 {
665 	__u64 access;
666 	struct landlock_path_beneath_attr path_beneath = {};
667 	const struct landlock_ruleset_attr ruleset_attr = {
668 		.handled_access_fs = ACCESS_ALL,
669 	};
670 	const int ruleset_fd =
671 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
672 
673 	ASSERT_LE(0, ruleset_fd);
674 
675 	path_beneath.parent_fd =
676 		open(TMP_DIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
677 	ASSERT_LE(0, path_beneath.parent_fd);
678 
679 	for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
680 		path_beneath.allowed_access = access;
681 		EXPECT_EQ(-1, landlock_add_rule(ruleset_fd,
682 						LANDLOCK_RULE_PATH_BENEATH,
683 						&path_beneath, 0));
684 		EXPECT_EQ(EINVAL, errno);
685 	}
686 	ASSERT_EQ(0, close(path_beneath.parent_fd));
687 	ASSERT_EQ(0, close(ruleset_fd));
688 }
689 
690 TEST_F_FORK(layout1, rule_with_unhandled_access)
691 {
692 	struct landlock_ruleset_attr ruleset_attr = {
693 		.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
694 	};
695 	struct landlock_path_beneath_attr path_beneath = {};
696 	int ruleset_fd;
697 	__u64 access;
698 
699 	ruleset_fd =
700 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
701 	ASSERT_LE(0, ruleset_fd);
702 
703 	path_beneath.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
704 	ASSERT_LE(0, path_beneath.parent_fd);
705 
706 	for (access = 1; access > 0; access <<= 1) {
707 		int err;
708 
709 		path_beneath.allowed_access = access;
710 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
711 					&path_beneath, 0);
712 		if (access == ruleset_attr.handled_access_fs) {
713 			EXPECT_EQ(0, err);
714 		} else {
715 			EXPECT_EQ(-1, err);
716 			EXPECT_EQ(EINVAL, errno);
717 		}
718 	}
719 
720 	EXPECT_EQ(0, close(path_beneath.parent_fd));
721 	EXPECT_EQ(0, close(ruleset_fd));
722 }
723 
724 static void add_path_beneath(struct __test_metadata *const _metadata,
725 			     const int ruleset_fd, const __u64 allowed_access,
726 			     const char *const path, __u32 flags)
727 {
728 	struct landlock_path_beneath_attr path_beneath = {
729 		.allowed_access = allowed_access,
730 	};
731 
732 	path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC);
733 	ASSERT_LE(0, path_beneath.parent_fd)
734 	{
735 		TH_LOG("Failed to open directory \"%s\": %s", path,
736 		       strerror(errno));
737 	}
738 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
739 				       &path_beneath, flags))
740 	{
741 		TH_LOG("Failed to update the ruleset with \"%s\": %s", path,
742 		       strerror(errno));
743 	}
744 	ASSERT_EQ(0, close(path_beneath.parent_fd));
745 }
746 
747 struct rule {
748 	const char *path;
749 	__u64 access;
750 };
751 
752 /* clang-format off */
753 
754 #define ACCESS_RO ( \
755 	LANDLOCK_ACCESS_FS_READ_FILE | \
756 	LANDLOCK_ACCESS_FS_READ_DIR)
757 
758 #define ACCESS_RW ( \
759 	ACCESS_RO | \
760 	LANDLOCK_ACCESS_FS_WRITE_FILE)
761 
762 /* clang-format on */
763 
764 static int create_ruleset(struct __test_metadata *const _metadata,
765 			  const __u64 handled_access_fs,
766 			  const struct rule rules[])
767 {
768 	int ruleset_fd, i;
769 	struct landlock_ruleset_attr ruleset_attr = {
770 		.handled_access_fs = handled_access_fs,
771 	};
772 
773 	ruleset_fd =
774 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
775 	ASSERT_LE(0, ruleset_fd)
776 	{
777 		TH_LOG("Failed to create a ruleset: %s", strerror(errno));
778 	}
779 
780 	if (rules)
781 		for (i = 0; rules[i].path; i++) {
782 			if (!rules[i].access)
783 				continue;
784 
785 			add_path_beneath(_metadata, ruleset_fd, rules[i].access,
786 					 rules[i].path, 0);
787 		}
788 	return ruleset_fd;
789 }
790 
791 static void enforce_fs(struct __test_metadata *const _metadata,
792 		       const __u64 access_fs, const struct rule rules[])
793 {
794 	const int ruleset_fd = create_ruleset(_metadata, access_fs, rules);
795 
796 	enforce_ruleset(_metadata, ruleset_fd);
797 	EXPECT_EQ(0, close(ruleset_fd));
798 }
799 
800 TEST_F_FORK(layout0, proc_nsfs)
801 {
802 	const struct rule rules[] = {
803 		{
804 			.path = "/dev/null",
805 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
806 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
807 		},
808 		{},
809 	};
810 	struct landlock_path_beneath_attr path_beneath;
811 	const int ruleset_fd = create_ruleset(
812 		_metadata, rules[0].access | LANDLOCK_ACCESS_FS_READ_DIR,
813 		rules);
814 
815 	ASSERT_LE(0, ruleset_fd);
816 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
817 
818 	enforce_ruleset(_metadata, ruleset_fd);
819 
820 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
821 	ASSERT_EQ(EACCES, test_open("/dev", O_RDONLY));
822 	ASSERT_EQ(0, test_open("/dev/null", O_RDONLY));
823 	ASSERT_EQ(EACCES, test_open("/dev/full", O_RDONLY));
824 
825 	ASSERT_EQ(EACCES, test_open("/proc", O_RDONLY));
826 	ASSERT_EQ(EACCES, test_open("/proc/self", O_RDONLY));
827 	ASSERT_EQ(EACCES, test_open("/proc/self/ns", O_RDONLY));
828 	/*
829 	 * Because nsfs is an internal filesystem, /proc/self/ns/mnt is a
830 	 * disconnected path.  Such path cannot be identified and must then be
831 	 * allowed.
832 	 */
833 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
834 
835 	/*
836 	 * Checks that it is not possible to add nsfs-like filesystem
837 	 * references to a ruleset.
838 	 */
839 	path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
840 				      LANDLOCK_ACCESS_FS_WRITE_FILE,
841 	path_beneath.parent_fd = open("/proc/self/ns/mnt", O_PATH | O_CLOEXEC);
842 	ASSERT_LE(0, path_beneath.parent_fd);
843 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
844 					&path_beneath, 0));
845 	ASSERT_EQ(EBADFD, errno);
846 	ASSERT_EQ(0, close(path_beneath.parent_fd));
847 }
848 
849 TEST_F_FORK(layout0, unpriv)
850 {
851 	const struct rule rules[] = {
852 		{
853 			.path = TMP_DIR,
854 			.access = ACCESS_RO,
855 		},
856 		{},
857 	};
858 	int ruleset_fd;
859 
860 	drop_caps(_metadata);
861 
862 	ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules);
863 	ASSERT_LE(0, ruleset_fd);
864 	ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
865 	ASSERT_EQ(EPERM, errno);
866 
867 	/* enforce_ruleset() calls prctl(no_new_privs). */
868 	enforce_ruleset(_metadata, ruleset_fd);
869 	ASSERT_EQ(0, close(ruleset_fd));
870 }
871 
872 TEST_F_FORK(layout1, effective_access)
873 {
874 	const struct rule rules[] = {
875 		{
876 			.path = dir_s1d2,
877 			.access = ACCESS_RO,
878 		},
879 		{
880 			.path = file1_s2d2,
881 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
882 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
883 		},
884 		{},
885 	};
886 	char buf;
887 	int reg_fd;
888 
889 	enforce_fs(_metadata, ACCESS_RW, rules);
890 
891 	/* Tests on a directory (with or without O_PATH). */
892 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
893 	ASSERT_EQ(0, test_open("/", O_RDONLY | O_PATH));
894 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
895 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_PATH));
896 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
897 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY | O_PATH));
898 
899 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
900 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
901 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
902 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
903 
904 	/* Tests on a file (with or without O_PATH). */
905 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY));
906 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_PATH));
907 
908 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
909 
910 	/* Checks effective read and write actions. */
911 	reg_fd = open(file1_s2d2, O_RDWR | O_CLOEXEC);
912 	ASSERT_LE(0, reg_fd);
913 	ASSERT_EQ(1, write(reg_fd, ".", 1));
914 	ASSERT_LE(0, lseek(reg_fd, 0, SEEK_SET));
915 	ASSERT_EQ(1, read(reg_fd, &buf, 1));
916 	ASSERT_EQ('.', buf);
917 	ASSERT_EQ(0, close(reg_fd));
918 
919 	/* Just in case, double-checks effective actions. */
920 	reg_fd = open(file1_s2d2, O_RDONLY | O_CLOEXEC);
921 	ASSERT_LE(0, reg_fd);
922 	ASSERT_EQ(-1, write(reg_fd, &buf, 1));
923 	ASSERT_EQ(EBADF, errno);
924 	ASSERT_EQ(0, close(reg_fd));
925 }
926 
927 TEST_F_FORK(layout1, unhandled_access)
928 {
929 	const struct rule rules[] = {
930 		{
931 			.path = dir_s1d2,
932 			.access = ACCESS_RO,
933 		},
934 		{},
935 	};
936 
937 	/* Here, we only handle read accesses, not write accesses. */
938 	enforce_fs(_metadata, ACCESS_RO, rules);
939 
940 	/*
941 	 * Because the policy does not handle LANDLOCK_ACCESS_FS_WRITE_FILE,
942 	 * opening for write-only should be allowed, but not read-write.
943 	 */
944 	ASSERT_EQ(0, test_open(file1_s1d1, O_WRONLY));
945 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
946 
947 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
948 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
949 }
950 
951 TEST_F_FORK(layout1, ruleset_overlap)
952 {
953 	const struct rule rules[] = {
954 		/* These rules should be ORed among them. */
955 		{
956 			.path = dir_s1d2,
957 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
958 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
959 		},
960 		{
961 			.path = dir_s1d2,
962 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
963 				  LANDLOCK_ACCESS_FS_READ_DIR,
964 		},
965 		{},
966 	};
967 
968 	enforce_fs(_metadata, ACCESS_RW, rules);
969 
970 	/* Checks s1d1 hierarchy. */
971 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
972 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
973 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
974 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
975 
976 	/* Checks s1d2 hierarchy. */
977 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
978 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
979 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
980 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
981 
982 	/* Checks s1d3 hierarchy. */
983 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
984 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
985 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
986 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
987 }
988 
989 TEST_F_FORK(layout1, layer_rule_unions)
990 {
991 	const struct rule layer1[] = {
992 		{
993 			.path = dir_s1d2,
994 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
995 		},
996 		/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
997 		{
998 			.path = dir_s1d3,
999 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1000 		},
1001 		{},
1002 	};
1003 	const struct rule layer2[] = {
1004 		/* Doesn't change anything from layer1. */
1005 		{
1006 			.path = dir_s1d2,
1007 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1008 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
1009 		},
1010 		{},
1011 	};
1012 	const struct rule layer3[] = {
1013 		/* Only allows write (but not read) to dir_s1d3. */
1014 		{
1015 			.path = dir_s1d2,
1016 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1017 		},
1018 		{},
1019 	};
1020 
1021 	enforce_fs(_metadata, ACCESS_RW, layer1);
1022 
1023 	/* Checks s1d1 hierarchy with layer1. */
1024 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1025 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1026 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1027 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1028 
1029 	/* Checks s1d2 hierarchy with layer1. */
1030 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1031 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1032 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1033 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1034 
1035 	/* Checks s1d3 hierarchy with layer1. */
1036 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1037 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1038 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
1039 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1040 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1041 
1042 	/* Doesn't change anything from layer1. */
1043 	enforce_fs(_metadata, ACCESS_RW, layer2);
1044 
1045 	/* Checks s1d1 hierarchy with layer2. */
1046 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1047 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1048 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1049 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1050 
1051 	/* Checks s1d2 hierarchy with layer2. */
1052 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1053 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1054 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1055 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1056 
1057 	/* Checks s1d3 hierarchy with layer2. */
1058 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1059 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1060 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
1061 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1062 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1063 
1064 	/* Only allows write (but not read) to dir_s1d3. */
1065 	enforce_fs(_metadata, ACCESS_RW, layer3);
1066 
1067 	/* Checks s1d1 hierarchy with layer3. */
1068 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1069 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1070 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1071 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1072 
1073 	/* Checks s1d2 hierarchy with layer3. */
1074 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
1075 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1076 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1077 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1078 
1079 	/* Checks s1d3 hierarchy with layer3. */
1080 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
1081 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1082 	/* dir_s1d3 should now deny READ_FILE and WRITE_FILE (O_RDWR). */
1083 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDWR));
1084 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1085 }
1086 
1087 TEST_F_FORK(layout1, non_overlapping_accesses)
1088 {
1089 	const struct rule layer1[] = {
1090 		{
1091 			.path = dir_s1d2,
1092 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
1093 		},
1094 		{},
1095 	};
1096 	const struct rule layer2[] = {
1097 		{
1098 			.path = dir_s1d3,
1099 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1100 		},
1101 		{},
1102 	};
1103 
1104 	ASSERT_EQ(0, unlink(file1_s1d1));
1105 	ASSERT_EQ(0, unlink(file1_s1d2));
1106 
1107 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1);
1108 
1109 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
1110 	ASSERT_EQ(EACCES, errno);
1111 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
1112 	ASSERT_EQ(0, unlink(file1_s1d2));
1113 
1114 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE, layer2);
1115 
1116 	/* Unchanged accesses for file creation. */
1117 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
1118 	ASSERT_EQ(EACCES, errno);
1119 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
1120 
1121 	/* Checks file removing. */
1122 	ASSERT_EQ(-1, unlink(file1_s1d2));
1123 	ASSERT_EQ(EACCES, errno);
1124 	ASSERT_EQ(0, unlink(file1_s1d3));
1125 }
1126 
1127 TEST_F_FORK(layout1, interleaved_masked_accesses)
1128 {
1129 	/*
1130 	 * Checks overly restrictive rules:
1131 	 * layer 1: allows R   s1d1/s1d2/s1d3/file1
1132 	 * layer 2: allows RW  s1d1/s1d2/s1d3
1133 	 *          allows  W  s1d1/s1d2
1134 	 *          denies R   s1d1/s1d2
1135 	 * layer 3: allows R   s1d1
1136 	 * layer 4: allows R   s1d1/s1d2
1137 	 *          denies  W  s1d1/s1d2
1138 	 * layer 5: allows R   s1d1/s1d2
1139 	 * layer 6: allows   X ----
1140 	 * layer 7: allows  W  s1d1/s1d2
1141 	 *          denies R   s1d1/s1d2
1142 	 */
1143 	const struct rule layer1_read[] = {
1144 		/* Allows read access to file1_s1d3 with the first layer. */
1145 		{
1146 			.path = file1_s1d3,
1147 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1148 		},
1149 		{},
1150 	};
1151 	/* First rule with write restrictions. */
1152 	const struct rule layer2_read_write[] = {
1153 		/* Start by granting read-write access via its parent directory... */
1154 		{
1155 			.path = dir_s1d3,
1156 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1157 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
1158 		},
1159 		/* ...but also denies read access via its grandparent directory. */
1160 		{
1161 			.path = dir_s1d2,
1162 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1163 		},
1164 		{},
1165 	};
1166 	const struct rule layer3_read[] = {
1167 		/* Allows read access via its great-grandparent directory. */
1168 		{
1169 			.path = dir_s1d1,
1170 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1171 		},
1172 		{},
1173 	};
1174 	const struct rule layer4_read_write[] = {
1175 		/*
1176 		 * Try to confuse the deny access by denying write (but not
1177 		 * read) access via its grandparent directory.
1178 		 */
1179 		{
1180 			.path = dir_s1d2,
1181 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1182 		},
1183 		{},
1184 	};
1185 	const struct rule layer5_read[] = {
1186 		/*
1187 		 * Try to override layer2's deny read access by explicitly
1188 		 * allowing read access via file1_s1d3's grandparent.
1189 		 */
1190 		{
1191 			.path = dir_s1d2,
1192 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1193 		},
1194 		{},
1195 	};
1196 	const struct rule layer6_execute[] = {
1197 		/*
1198 		 * Restricts an unrelated file hierarchy with a new access
1199 		 * (non-overlapping) type.
1200 		 */
1201 		{
1202 			.path = dir_s2d1,
1203 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
1204 		},
1205 		{},
1206 	};
1207 	const struct rule layer7_read_write[] = {
1208 		/*
1209 		 * Finally, denies read access to file1_s1d3 via its
1210 		 * grandparent.
1211 		 */
1212 		{
1213 			.path = dir_s1d2,
1214 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1215 		},
1216 		{},
1217 	};
1218 
1219 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, layer1_read);
1220 
1221 	/* Checks that read access is granted for file1_s1d3 with layer 1. */
1222 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1223 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1224 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1225 
1226 	enforce_fs(_metadata,
1227 		   LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
1228 		   layer2_read_write);
1229 
1230 	/* Checks that previous access rights are unchanged with layer 2. */
1231 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1232 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1233 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1234 
1235 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, layer3_read);
1236 
1237 	/* Checks that previous access rights are unchanged with layer 3. */
1238 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1239 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1240 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1241 
1242 	/* This time, denies write access for the file hierarchy. */
1243 	enforce_fs(_metadata,
1244 		   LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
1245 		   layer4_read_write);
1246 
1247 	/*
1248 	 * Checks that the only change with layer 4 is that write access is
1249 	 * denied.
1250 	 */
1251 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1252 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1253 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1254 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1255 
1256 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, layer5_read);
1257 
1258 	/* Checks that previous access rights are unchanged with layer 5. */
1259 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1260 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1261 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1262 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1263 
1264 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, layer6_execute);
1265 
1266 	/* Checks that previous access rights are unchanged with layer 6. */
1267 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1268 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1269 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1270 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1271 
1272 	enforce_fs(_metadata,
1273 		   LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
1274 		   layer7_read_write);
1275 
1276 	/* Checks read access is now denied with layer 7. */
1277 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
1278 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1279 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1280 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1281 }
1282 
1283 TEST_F_FORK(layout1, inherit_subset)
1284 {
1285 	const struct rule rules[] = {
1286 		{
1287 			.path = dir_s1d2,
1288 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1289 				  LANDLOCK_ACCESS_FS_READ_DIR,
1290 		},
1291 		{},
1292 	};
1293 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1294 
1295 	enforce_ruleset(_metadata, ruleset_fd);
1296 
1297 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1298 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1299 
1300 	/* Write access is forbidden. */
1301 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1302 	/* Readdir access is allowed. */
1303 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1304 
1305 	/* Write access is forbidden. */
1306 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1307 	/* Readdir access is allowed. */
1308 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1309 
1310 	/*
1311 	 * Tests shared rule extension: the following rules should not grant
1312 	 * any new access, only remove some.  Once enforced, these rules are
1313 	 * ANDed with the previous ones.
1314 	 */
1315 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1316 			 dir_s1d2, 0);
1317 	/*
1318 	 * According to ruleset_fd, dir_s1d2 should now have the
1319 	 * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE
1320 	 * access rights (even if this directory is opened a second time).
1321 	 * However, when enforcing this updated ruleset, the ruleset tied to
1322 	 * the current process (i.e. its domain) will still only have the
1323 	 * dir_s1d2 with LANDLOCK_ACCESS_FS_READ_FILE and
1324 	 * LANDLOCK_ACCESS_FS_READ_DIR accesses, but
1325 	 * LANDLOCK_ACCESS_FS_WRITE_FILE must not be allowed because it would
1326 	 * be a privilege escalation.
1327 	 */
1328 	enforce_ruleset(_metadata, ruleset_fd);
1329 
1330 	/* Same tests and results as above. */
1331 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1332 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1333 
1334 	/* It is still forbidden to write in file1_s1d2. */
1335 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1336 	/* Readdir access is still allowed. */
1337 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1338 
1339 	/* It is still forbidden to write in file1_s1d3. */
1340 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1341 	/* Readdir access is still allowed. */
1342 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1343 
1344 	/*
1345 	 * Try to get more privileges by adding new access rights to the parent
1346 	 * directory: dir_s1d1.
1347 	 */
1348 	add_path_beneath(_metadata, ruleset_fd, ACCESS_RW, dir_s1d1, 0);
1349 	enforce_ruleset(_metadata, ruleset_fd);
1350 
1351 	/* Same tests and results as above. */
1352 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1353 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1354 
1355 	/* It is still forbidden to write in file1_s1d2. */
1356 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1357 	/* Readdir access is still allowed. */
1358 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1359 
1360 	/* It is still forbidden to write in file1_s1d3. */
1361 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1362 	/* Readdir access is still allowed. */
1363 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1364 
1365 	/*
1366 	 * Now, dir_s1d3 get a new rule tied to it, only allowing
1367 	 * LANDLOCK_ACCESS_FS_WRITE_FILE.  The (kernel internal) difference is
1368 	 * that there was no rule tied to it before.
1369 	 */
1370 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1371 			 dir_s1d3, 0);
1372 	enforce_ruleset(_metadata, ruleset_fd);
1373 	ASSERT_EQ(0, close(ruleset_fd));
1374 
1375 	/*
1376 	 * Same tests and results as above, except for open(dir_s1d3) which is
1377 	 * now denied because the new rule mask the rule previously inherited
1378 	 * from dir_s1d2.
1379 	 */
1380 
1381 	/* Same tests and results as above. */
1382 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1383 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1384 
1385 	/* It is still forbidden to write in file1_s1d2. */
1386 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1387 	/* Readdir access is still allowed. */
1388 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1389 
1390 	/* It is still forbidden to write in file1_s1d3. */
1391 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1392 	/*
1393 	 * Readdir of dir_s1d3 is still allowed because of the OR policy inside
1394 	 * the same layer.
1395 	 */
1396 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1397 }
1398 
1399 TEST_F_FORK(layout1, inherit_superset)
1400 {
1401 	const struct rule rules[] = {
1402 		{
1403 			.path = dir_s1d3,
1404 			.access = ACCESS_RO,
1405 		},
1406 		{},
1407 	};
1408 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1409 
1410 	enforce_ruleset(_metadata, ruleset_fd);
1411 
1412 	/* Readdir access is denied for dir_s1d2. */
1413 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1414 	/* Readdir access is allowed for dir_s1d3. */
1415 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1416 	/* File access is allowed for file1_s1d3. */
1417 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1418 
1419 	/* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */
1420 	add_path_beneath(_metadata, ruleset_fd,
1421 			 LANDLOCK_ACCESS_FS_READ_FILE |
1422 				 LANDLOCK_ACCESS_FS_READ_DIR,
1423 			 dir_s1d2, 0);
1424 	enforce_ruleset(_metadata, ruleset_fd);
1425 	EXPECT_EQ(0, close(ruleset_fd));
1426 
1427 	/* Readdir access is still denied for dir_s1d2. */
1428 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1429 	/* Readdir access is still allowed for dir_s1d3. */
1430 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1431 	/* File access is still allowed for file1_s1d3. */
1432 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1433 }
1434 
1435 TEST_F_FORK(layout0, max_layers)
1436 {
1437 	int i, err;
1438 	const struct rule rules[] = {
1439 		{
1440 			.path = TMP_DIR,
1441 			.access = ACCESS_RO,
1442 		},
1443 		{},
1444 	};
1445 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1446 
1447 	for (i = 0; i < LANDLOCK_MAX_NUM_LAYERS; i++)
1448 		enforce_ruleset(_metadata, ruleset_fd);
1449 
1450 	for (i = 0; i < 2; i++) {
1451 		err = landlock_restrict_self(ruleset_fd, 0);
1452 		ASSERT_EQ(-1, err);
1453 		ASSERT_EQ(E2BIG, errno);
1454 	}
1455 	EXPECT_EQ(0, close(ruleset_fd));
1456 }
1457 
1458 TEST_F_FORK(layout1, empty_or_same_ruleset)
1459 {
1460 	struct landlock_ruleset_attr ruleset_attr = {};
1461 	int ruleset_fd;
1462 
1463 	/* Tests empty handled_access_fs. */
1464 	ruleset_fd =
1465 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1466 	ASSERT_LE(-1, ruleset_fd);
1467 	ASSERT_EQ(ENOMSG, errno);
1468 
1469 	/* Enforces policy which denies read access to all files. */
1470 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, NULL);
1471 
1472 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1473 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1474 
1475 	/* Nests a policy which denies read access to all directories. */
1476 	ruleset_fd =
1477 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, NULL);
1478 	enforce_ruleset(_metadata, ruleset_fd);
1479 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1480 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1481 
1482 	/* Enforces a second time with the same ruleset. */
1483 	enforce_ruleset(_metadata, ruleset_fd);
1484 	ASSERT_EQ(0, close(ruleset_fd));
1485 }
1486 
1487 TEST_F_FORK(layout1, rule_on_mountpoint)
1488 {
1489 	const struct rule rules[] = {
1490 		{
1491 			.path = dir_s1d1,
1492 			.access = ACCESS_RO,
1493 		},
1494 		{
1495 			/* dir_s3d2 is a mount point. */
1496 			.path = dir_s3d2,
1497 			.access = ACCESS_RO,
1498 		},
1499 		{},
1500 	};
1501 
1502 	enforce_fs(_metadata, ACCESS_RW, rules);
1503 
1504 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1505 
1506 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1507 
1508 	ASSERT_EQ(EACCES, test_open(dir_s3d1, O_RDONLY));
1509 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1510 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1511 }
1512 
1513 TEST_F_FORK(layout1, rule_over_mountpoint)
1514 {
1515 	const struct rule rules[] = {
1516 		{
1517 			.path = dir_s1d1,
1518 			.access = ACCESS_RO,
1519 		},
1520 		{
1521 			/* dir_s3d2 is a mount point. */
1522 			.path = dir_s3d1,
1523 			.access = ACCESS_RO,
1524 		},
1525 		{},
1526 	};
1527 
1528 	enforce_fs(_metadata, ACCESS_RW, rules);
1529 
1530 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1531 
1532 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1533 
1534 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
1535 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1536 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1537 }
1538 
1539 /*
1540  * This test verifies that we can apply a landlock rule on the root directory
1541  * (which might require special handling).
1542  */
1543 TEST_F_FORK(layout1, rule_over_root_allow_then_deny)
1544 {
1545 	struct rule rules[] = {
1546 		{
1547 			.path = "/",
1548 			.access = ACCESS_RO,
1549 		},
1550 		{},
1551 	};
1552 
1553 	enforce_fs(_metadata, ACCESS_RW, rules);
1554 
1555 	/* Checks allowed access. */
1556 	ASSERT_EQ(0, test_open("/", O_RDONLY));
1557 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1558 
1559 	rules[0].access = LANDLOCK_ACCESS_FS_READ_FILE;
1560 	enforce_fs(_metadata, ACCESS_RW, rules);
1561 
1562 	/* Checks denied access (on a directory). */
1563 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1564 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1565 }
1566 
1567 TEST_F_FORK(layout1, rule_over_root_deny)
1568 {
1569 	const struct rule rules[] = {
1570 		{
1571 			.path = "/",
1572 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1573 		},
1574 		{},
1575 	};
1576 
1577 	enforce_fs(_metadata, ACCESS_RW, rules);
1578 
1579 	/* Checks denied access (on a directory). */
1580 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1581 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1582 }
1583 
1584 TEST_F_FORK(layout1, rule_inside_mount_ns)
1585 {
1586 	const struct rule rules[] = {
1587 		{
1588 			.path = "s3d3",
1589 			.access = ACCESS_RO,
1590 		},
1591 		{},
1592 	};
1593 
1594 	set_cap(_metadata, CAP_SYS_ADMIN);
1595 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3))
1596 	{
1597 		TH_LOG("Failed to pivot root: %s", strerror(errno));
1598 	};
1599 	ASSERT_EQ(0, chdir("/"));
1600 	clear_cap(_metadata, CAP_SYS_ADMIN);
1601 
1602 	enforce_fs(_metadata, ACCESS_RW, rules);
1603 
1604 	ASSERT_EQ(0, test_open("s3d3", O_RDONLY));
1605 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1606 }
1607 
1608 TEST_F_FORK(layout1, mount_and_pivot)
1609 {
1610 	const struct rule rules[] = {
1611 		{
1612 			.path = dir_s3d2,
1613 			.access = ACCESS_RO,
1614 		},
1615 		{},
1616 	};
1617 
1618 	enforce_fs(_metadata, ACCESS_RW, rules);
1619 
1620 	set_cap(_metadata, CAP_SYS_ADMIN);
1621 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
1622 	ASSERT_EQ(EPERM, errno);
1623 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1624 	ASSERT_EQ(EPERM, errno);
1625 	clear_cap(_metadata, CAP_SYS_ADMIN);
1626 }
1627 
1628 TEST_F_FORK(layout1, move_mount)
1629 {
1630 	const struct rule rules[] = {
1631 		{
1632 			.path = dir_s3d2,
1633 			.access = ACCESS_RO,
1634 		},
1635 		{},
1636 	};
1637 
1638 	set_cap(_metadata, CAP_SYS_ADMIN);
1639 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1640 			     dir_s1d2, 0))
1641 	{
1642 		TH_LOG("Failed to move mount: %s", strerror(errno));
1643 	}
1644 
1645 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1646 			     dir_s3d2, 0));
1647 	clear_cap(_metadata, CAP_SYS_ADMIN);
1648 
1649 	enforce_fs(_metadata, ACCESS_RW, rules);
1650 
1651 	set_cap(_metadata, CAP_SYS_ADMIN);
1652 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1653 			      dir_s1d2, 0));
1654 	ASSERT_EQ(EPERM, errno);
1655 	clear_cap(_metadata, CAP_SYS_ADMIN);
1656 }
1657 
1658 TEST_F_FORK(layout1, topology_changes_with_net_only)
1659 {
1660 	const struct landlock_ruleset_attr ruleset_net = {
1661 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1662 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1663 	};
1664 
1665 	/* Add network restrictions. */
1666 	drop_access_rights(_metadata, &ruleset_net);
1667 
1668 	/* Mount, remount, move_mount, umount, and pivot_root checks. */
1669 	set_cap(_metadata, CAP_SYS_ADMIN);
1670 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s1d2));
1671 	ASSERT_EQ(0, mount(NULL, dir_s1d2, NULL, MS_PRIVATE | MS_REC, NULL));
1672 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1673 			     dir_s2d2, 0));
1674 	ASSERT_EQ(0, umount(dir_s2d2));
1675 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1676 	ASSERT_EQ(0, chdir("/"));
1677 	clear_cap(_metadata, CAP_SYS_ADMIN);
1678 }
1679 
1680 TEST_F_FORK(layout1, topology_changes_with_net_and_fs)
1681 {
1682 	const struct landlock_ruleset_attr ruleset_net_fs = {
1683 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1684 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1685 		.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
1686 	};
1687 
1688 	/* Add network and filesystem restrictions. */
1689 	drop_access_rights(_metadata, &ruleset_net_fs);
1690 
1691 	/* Mount, remount, move_mount, umount, and pivot_root checks. */
1692 	set_cap(_metadata, CAP_SYS_ADMIN);
1693 	ASSERT_EQ(-1, mount_opt(&mnt_tmp, dir_s1d2));
1694 	ASSERT_EQ(EPERM, errno);
1695 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_PRIVATE | MS_REC, NULL));
1696 	ASSERT_EQ(EPERM, errno);
1697 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1698 			      dir_s2d2, 0));
1699 	ASSERT_EQ(EPERM, errno);
1700 	ASSERT_EQ(-1, umount(dir_s3d2));
1701 	ASSERT_EQ(EPERM, errno);
1702 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1703 	ASSERT_EQ(EPERM, errno);
1704 	clear_cap(_metadata, CAP_SYS_ADMIN);
1705 }
1706 
1707 TEST_F_FORK(layout1, release_inodes)
1708 {
1709 	const struct rule rules[] = {
1710 		{
1711 			.path = dir_s1d1,
1712 			.access = ACCESS_RO,
1713 		},
1714 		{
1715 			.path = dir_s3d2,
1716 			.access = ACCESS_RO,
1717 		},
1718 		{
1719 			.path = dir_s3d3,
1720 			.access = ACCESS_RO,
1721 		},
1722 		{},
1723 	};
1724 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1725 
1726 	/* Unmount a file hierarchy while it is being used by a ruleset. */
1727 	set_cap(_metadata, CAP_SYS_ADMIN);
1728 	ASSERT_EQ(0, umount(dir_s3d2));
1729 	clear_cap(_metadata, CAP_SYS_ADMIN);
1730 
1731 	enforce_ruleset(_metadata, ruleset_fd);
1732 	EXPECT_EQ(0, close(ruleset_fd));
1733 
1734 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1735 	ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
1736 	/* This dir_s3d3 would not be allowed and does not exist anyway. */
1737 	ASSERT_EQ(ENOENT, test_open(dir_s3d3, O_RDONLY));
1738 }
1739 
1740 /*
1741  * This test checks that a rule on a directory used as a mount point does not
1742  * grant access to the mount covering it.  It is a generalization of the bind
1743  * mount case in layout3_fs.hostfs.release_inodes that tests hidden mount points.
1744  */
1745 TEST_F_FORK(layout1, covered_rule)
1746 {
1747 	const struct rule layer1[] = {
1748 		{
1749 			.path = dir_s3d2,
1750 			.access = LANDLOCK_ACCESS_FS_READ_DIR,
1751 		},
1752 		{},
1753 	};
1754 	int ruleset_fd;
1755 
1756 	/* Unmount to simplify FIXTURE_TEARDOWN. */
1757 	set_cap(_metadata, CAP_SYS_ADMIN);
1758 	ASSERT_EQ(0, umount(dir_s3d2));
1759 	clear_cap(_metadata, CAP_SYS_ADMIN);
1760 
1761 	/* Creates a ruleset with the future hidden directory. */
1762 	ruleset_fd =
1763 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
1764 
1765 	/* Covers with a new mount point. */
1766 	set_cap(_metadata, CAP_SYS_ADMIN);
1767 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
1768 	clear_cap(_metadata, CAP_SYS_ADMIN);
1769 
1770 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1771 
1772 	enforce_ruleset(_metadata, ruleset_fd);
1773 	ASSERT_EQ(0, close(ruleset_fd));
1774 
1775 	/* Checks that access to the new mount point is denied. */
1776 	ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
1777 }
1778 
1779 enum relative_access {
1780 	REL_OPEN,
1781 	REL_CHDIR,
1782 	REL_CHROOT_ONLY,
1783 	REL_CHROOT_CHDIR,
1784 };
1785 
1786 static void test_relative_path(struct __test_metadata *const _metadata,
1787 			       const enum relative_access rel)
1788 {
1789 	/*
1790 	 * Common layer to check that chroot doesn't ignore it (i.e. a chroot
1791 	 * is not a disconnected root directory).
1792 	 */
1793 	const struct rule layer1_base[] = {
1794 		{
1795 			.path = TMP_DIR,
1796 			.access = ACCESS_RO,
1797 		},
1798 		{},
1799 	};
1800 	const struct rule layer2_subs[] = {
1801 		{
1802 			.path = dir_s1d2,
1803 			.access = ACCESS_RO,
1804 		},
1805 		{
1806 			.path = dir_s2d2,
1807 			.access = ACCESS_RO,
1808 		},
1809 		{},
1810 	};
1811 	int dirfd, ruleset_fd;
1812 
1813 	enforce_fs(_metadata, ACCESS_RW, layer1_base);
1814 
1815 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_subs);
1816 
1817 	ASSERT_LE(0, ruleset_fd);
1818 	switch (rel) {
1819 	case REL_OPEN:
1820 	case REL_CHDIR:
1821 		break;
1822 	case REL_CHROOT_ONLY:
1823 		ASSERT_EQ(0, chdir(dir_s2d2));
1824 		break;
1825 	case REL_CHROOT_CHDIR:
1826 		ASSERT_EQ(0, chdir(dir_s1d2));
1827 		break;
1828 	default:
1829 		ASSERT_TRUE(false);
1830 		return;
1831 	}
1832 
1833 	set_cap(_metadata, CAP_SYS_CHROOT);
1834 	enforce_ruleset(_metadata, ruleset_fd);
1835 
1836 	switch (rel) {
1837 	case REL_OPEN:
1838 		dirfd = open(dir_s1d2, O_DIRECTORY);
1839 		ASSERT_LE(0, dirfd);
1840 		break;
1841 	case REL_CHDIR:
1842 		ASSERT_EQ(0, chdir(dir_s1d2));
1843 		dirfd = AT_FDCWD;
1844 		break;
1845 	case REL_CHROOT_ONLY:
1846 		/* Do chroot into dir_s1d2 (relative to dir_s2d2). */
1847 		ASSERT_EQ(0, chroot("../../s1d1/s1d2"))
1848 		{
1849 			TH_LOG("Failed to chroot: %s", strerror(errno));
1850 		}
1851 		dirfd = AT_FDCWD;
1852 		break;
1853 	case REL_CHROOT_CHDIR:
1854 		/* Do chroot into dir_s1d2. */
1855 		ASSERT_EQ(0, chroot("."))
1856 		{
1857 			TH_LOG("Failed to chroot: %s", strerror(errno));
1858 		}
1859 		dirfd = AT_FDCWD;
1860 		break;
1861 	}
1862 
1863 	ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES,
1864 		  test_open_rel(dirfd, "..", O_RDONLY));
1865 	ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY));
1866 
1867 	if (rel == REL_CHROOT_ONLY) {
1868 		/* The current directory is dir_s2d2. */
1869 		ASSERT_EQ(0, test_open_rel(dirfd, "./s2d3", O_RDONLY));
1870 	} else {
1871 		/* The current directory is dir_s1d2. */
1872 		ASSERT_EQ(0, test_open_rel(dirfd, "./s1d3", O_RDONLY));
1873 	}
1874 
1875 	if (rel == REL_CHROOT_ONLY || rel == REL_CHROOT_CHDIR) {
1876 		/* Checks the root dir_s1d2. */
1877 		ASSERT_EQ(0, test_open_rel(dirfd, "/..", O_RDONLY));
1878 		ASSERT_EQ(0, test_open_rel(dirfd, "/", O_RDONLY));
1879 		ASSERT_EQ(0, test_open_rel(dirfd, "/f1", O_RDONLY));
1880 		ASSERT_EQ(0, test_open_rel(dirfd, "/s1d3", O_RDONLY));
1881 	}
1882 
1883 	if (rel != REL_CHROOT_CHDIR) {
1884 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY));
1885 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY));
1886 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3",
1887 					   O_RDONLY));
1888 
1889 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY));
1890 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY));
1891 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3",
1892 					   O_RDONLY));
1893 	}
1894 
1895 	if (rel == REL_OPEN)
1896 		ASSERT_EQ(0, close(dirfd));
1897 	ASSERT_EQ(0, close(ruleset_fd));
1898 }
1899 
1900 TEST_F_FORK(layout1, relative_open)
1901 {
1902 	test_relative_path(_metadata, REL_OPEN);
1903 }
1904 
1905 TEST_F_FORK(layout1, relative_chdir)
1906 {
1907 	test_relative_path(_metadata, REL_CHDIR);
1908 }
1909 
1910 TEST_F_FORK(layout1, relative_chroot_only)
1911 {
1912 	test_relative_path(_metadata, REL_CHROOT_ONLY);
1913 }
1914 
1915 TEST_F_FORK(layout1, relative_chroot_chdir)
1916 {
1917 	test_relative_path(_metadata, REL_CHROOT_CHDIR);
1918 }
1919 
1920 static void copy_file(struct __test_metadata *const _metadata,
1921 		      const char *const src_path, const char *const dst_path)
1922 {
1923 	int dst_fd, src_fd;
1924 	struct stat statbuf;
1925 
1926 	dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC);
1927 	ASSERT_LE(0, dst_fd)
1928 	{
1929 		TH_LOG("Failed to open \"%s\": %s", dst_path, strerror(errno));
1930 	}
1931 	src_fd = open(src_path, O_RDONLY | O_CLOEXEC);
1932 	ASSERT_LE(0, src_fd)
1933 	{
1934 		TH_LOG("Failed to open \"%s\": %s", src_path, strerror(errno));
1935 	}
1936 	ASSERT_EQ(0, fstat(src_fd, &statbuf));
1937 	ASSERT_EQ(statbuf.st_size,
1938 		  sendfile(dst_fd, src_fd, 0, statbuf.st_size));
1939 	ASSERT_EQ(0, close(src_fd));
1940 	ASSERT_EQ(0, close(dst_fd));
1941 }
1942 
1943 static void test_execute(struct __test_metadata *const _metadata, const int err,
1944 			 const char *const path)
1945 {
1946 	int status;
1947 	char *const argv[] = { (char *)path, NULL };
1948 	const pid_t child = fork();
1949 
1950 	ASSERT_LE(0, child);
1951 	if (child == 0) {
1952 		ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL))
1953 		{
1954 			TH_LOG("Failed to execute \"%s\": %s", path,
1955 			       strerror(errno));
1956 		};
1957 		ASSERT_EQ(err, errno);
1958 		_exit(__test_passed(_metadata) ? 2 : 1);
1959 		return;
1960 	}
1961 	ASSERT_EQ(child, waitpid(child, &status, 0));
1962 	ASSERT_EQ(1, WIFEXITED(status));
1963 	ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status))
1964 	{
1965 		TH_LOG("Unexpected return code for \"%s\"", path);
1966 	};
1967 }
1968 
1969 static void test_check_exec(struct __test_metadata *const _metadata,
1970 			    const int err, const char *const path)
1971 {
1972 	int ret;
1973 	char *const argv[] = { (char *)path, NULL };
1974 
1975 	ret = sys_execveat(AT_FDCWD, path, argv, NULL,
1976 			   AT_EMPTY_PATH | AT_EXECVE_CHECK);
1977 	if (err) {
1978 		EXPECT_EQ(-1, ret);
1979 		EXPECT_EQ(errno, err);
1980 	} else {
1981 		EXPECT_EQ(0, ret);
1982 	}
1983 }
1984 
1985 TEST_F_FORK(layout1, execute)
1986 {
1987 	const struct rule rules[] = {
1988 		{
1989 			.path = dir_s1d2,
1990 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
1991 		},
1992 		{},
1993 	};
1994 
1995 	copy_file(_metadata, bin_true, file1_s1d1);
1996 	copy_file(_metadata, bin_true, file1_s1d2);
1997 	copy_file(_metadata, bin_true, file1_s1d3);
1998 
1999 	/* Checks before file1_s1d1 being denied. */
2000 	test_execute(_metadata, 0, file1_s1d1);
2001 	test_check_exec(_metadata, 0, file1_s1d1);
2002 
2003 	enforce_fs(_metadata, rules[0].access, rules);
2004 
2005 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
2006 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2007 	test_execute(_metadata, EACCES, file1_s1d1);
2008 	test_check_exec(_metadata, EACCES, file1_s1d1);
2009 
2010 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
2011 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2012 	test_execute(_metadata, 0, file1_s1d2);
2013 	test_check_exec(_metadata, 0, file1_s1d2);
2014 
2015 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
2016 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2017 	test_execute(_metadata, 0, file1_s1d3);
2018 	test_check_exec(_metadata, 0, file1_s1d3);
2019 }
2020 
2021 TEST_F_FORK(layout1, umount_sandboxer)
2022 {
2023 	int pipe_child[2], pipe_parent[2];
2024 	char buf_parent;
2025 	pid_t child;
2026 	int status;
2027 
2028 	copy_file(_metadata, bin_sandbox_and_launch, file1_s3d3);
2029 	ASSERT_EQ(0, pipe2(pipe_child, 0));
2030 	ASSERT_EQ(0, pipe2(pipe_parent, 0));
2031 
2032 	child = fork();
2033 	ASSERT_LE(0, child);
2034 	if (child == 0) {
2035 		char pipe_child_str[12], pipe_parent_str[12];
2036 		char *const argv[] = { (char *)file1_s3d3,
2037 				       (char *)bin_wait_pipe, pipe_child_str,
2038 				       pipe_parent_str, NULL };
2039 
2040 		/* Passes the pipe FDs to the executed binary and its child. */
2041 		EXPECT_EQ(0, close(pipe_child[0]));
2042 		EXPECT_EQ(0, close(pipe_parent[1]));
2043 		snprintf(pipe_child_str, sizeof(pipe_child_str), "%d",
2044 			 pipe_child[1]);
2045 		snprintf(pipe_parent_str, sizeof(pipe_parent_str), "%d",
2046 			 pipe_parent[0]);
2047 
2048 		/*
2049 		 * We need bin_sandbox_and_launch (copied inside the mount as
2050 		 * file1_s3d3) to execute bin_wait_pipe (outside the mount) to
2051 		 * make sure the mount point will not be EBUSY because of
2052 		 * file1_s3d3 being in use.  This avoids a potential race
2053 		 * condition between the following read() and umount() calls.
2054 		 */
2055 		ASSERT_EQ(0, execve(argv[0], argv, NULL))
2056 		{
2057 			TH_LOG("Failed to execute \"%s\": %s", argv[0],
2058 			       strerror(errno));
2059 		};
2060 		_exit(1);
2061 		return;
2062 	}
2063 
2064 	EXPECT_EQ(0, close(pipe_child[1]));
2065 	EXPECT_EQ(0, close(pipe_parent[0]));
2066 
2067 	/* Waits for the child to sandbox itself. */
2068 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
2069 
2070 	/* Tests that the sandboxer is tied to its mount point. */
2071 	set_cap(_metadata, CAP_SYS_ADMIN);
2072 	EXPECT_EQ(-1, umount(dir_s3d2));
2073 	EXPECT_EQ(EBUSY, errno);
2074 	clear_cap(_metadata, CAP_SYS_ADMIN);
2075 
2076 	/* Signals the child to launch a grandchild. */
2077 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
2078 
2079 	/* Waits for the grandchild. */
2080 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
2081 
2082 	/* Tests that the domain's sandboxer is not tied to its mount point. */
2083 	set_cap(_metadata, CAP_SYS_ADMIN);
2084 	EXPECT_EQ(0, umount(dir_s3d2))
2085 	{
2086 		TH_LOG("Failed to umount \"%s\": %s", dir_s3d2,
2087 		       strerror(errno));
2088 	};
2089 	clear_cap(_metadata, CAP_SYS_ADMIN);
2090 
2091 	/* Signals the grandchild to terminate. */
2092 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
2093 	ASSERT_EQ(child, waitpid(child, &status, 0));
2094 	ASSERT_EQ(1, WIFEXITED(status));
2095 	ASSERT_EQ(0, WEXITSTATUS(status));
2096 }
2097 
2098 TEST_F_FORK(layout1, link)
2099 {
2100 	const struct rule layer1[] = {
2101 		{
2102 			.path = dir_s1d2,
2103 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2104 		},
2105 		{},
2106 	};
2107 	const struct rule layer2[] = {
2108 		{
2109 			.path = dir_s1d3,
2110 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2111 		},
2112 		{},
2113 	};
2114 
2115 	ASSERT_EQ(0, unlink(file1_s1d1));
2116 	ASSERT_EQ(0, unlink(file1_s1d2));
2117 	ASSERT_EQ(0, unlink(file1_s1d3));
2118 
2119 	enforce_fs(_metadata, layer1[0].access, layer1);
2120 
2121 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2122 	ASSERT_EQ(EACCES, errno);
2123 
2124 	/* Denies linking because of reparenting. */
2125 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
2126 	ASSERT_EQ(EXDEV, errno);
2127 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
2128 	ASSERT_EQ(EXDEV, errno);
2129 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
2130 	ASSERT_EQ(EXDEV, errno);
2131 
2132 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
2133 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
2134 
2135 	/* Prepares for next unlinks. */
2136 	ASSERT_EQ(0, unlink(file2_s1d2));
2137 	ASSERT_EQ(0, unlink(file2_s1d3));
2138 
2139 	enforce_fs(_metadata, layer2[0].access, layer2);
2140 
2141 	/* Checks that linkind doesn't require the ability to delete a file. */
2142 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
2143 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
2144 }
2145 
2146 static int test_rename(const char *const oldpath, const char *const newpath)
2147 {
2148 	if (rename(oldpath, newpath))
2149 		return errno;
2150 	return 0;
2151 }
2152 
2153 static int test_exchange(const char *const oldpath, const char *const newpath)
2154 {
2155 	if (renameat2(AT_FDCWD, oldpath, AT_FDCWD, newpath, RENAME_EXCHANGE))
2156 		return errno;
2157 	return 0;
2158 }
2159 
2160 static int test_renameat(int olddirfd, const char *oldpath, int newdirfd,
2161 			 const char *newpath)
2162 {
2163 	if (renameat2(olddirfd, oldpath, newdirfd, newpath, 0))
2164 		return errno;
2165 	return 0;
2166 }
2167 
2168 static int test_exchangeat(int olddirfd, const char *oldpath, int newdirfd,
2169 			   const char *newpath)
2170 {
2171 	if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_EXCHANGE))
2172 		return errno;
2173 	return 0;
2174 }
2175 
2176 TEST_F_FORK(layout1, rename_file)
2177 {
2178 	const struct rule rules[] = {
2179 		{
2180 			.path = dir_s1d3,
2181 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2182 		},
2183 		{
2184 			.path = dir_s2d2,
2185 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2186 		},
2187 		{},
2188 	};
2189 
2190 	ASSERT_EQ(0, unlink(file1_s1d2));
2191 
2192 	enforce_fs(_metadata, rules[0].access, rules);
2193 
2194 	/*
2195 	 * Tries to replace a file, from a directory that allows file removal,
2196 	 * but to a different directory (which also allows file removal).
2197 	 */
2198 	ASSERT_EQ(-1, rename(file1_s2d3, file1_s1d3));
2199 	ASSERT_EQ(EXDEV, errno);
2200 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d3,
2201 				RENAME_EXCHANGE));
2202 	ASSERT_EQ(EXDEV, errno);
2203 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
2204 				RENAME_EXCHANGE));
2205 	ASSERT_EQ(EXDEV, errno);
2206 
2207 	/*
2208 	 * Tries to replace a file, from a directory that denies file removal,
2209 	 * to a different directory (which allows file removal).
2210 	 */
2211 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2212 	ASSERT_EQ(EACCES, errno);
2213 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file1_s1d3,
2214 				RENAME_EXCHANGE));
2215 	ASSERT_EQ(EACCES, errno);
2216 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s1d3,
2217 				RENAME_EXCHANGE));
2218 	ASSERT_EQ(EXDEV, errno);
2219 
2220 	/* Exchanges files and directories that partially allow removal. */
2221 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
2222 				RENAME_EXCHANGE));
2223 	ASSERT_EQ(EACCES, errno);
2224 	/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
2225 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
2226 	ASSERT_EQ(EACCES, errno);
2227 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
2228 				RENAME_EXCHANGE));
2229 	ASSERT_EQ(EACCES, errno);
2230 	/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
2231 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
2232 	ASSERT_EQ(EACCES, errno);
2233 
2234 	/* Renames files with different parents. */
2235 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
2236 	ASSERT_EQ(EXDEV, errno);
2237 	ASSERT_EQ(0, unlink(file1_s1d3));
2238 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2239 	ASSERT_EQ(EACCES, errno);
2240 
2241 	/* Exchanges and renames files with same parent. */
2242 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3,
2243 			       RENAME_EXCHANGE));
2244 	ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3));
2245 
2246 	/* Exchanges files and directories with same parent, twice. */
2247 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
2248 			       RENAME_EXCHANGE));
2249 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
2250 			       RENAME_EXCHANGE));
2251 }
2252 
2253 TEST_F_FORK(layout1, rename_whiteout_denied)
2254 {
2255 	/* The affected file is a FIFO. */
2256 	ASSERT_EQ(0, unlink(file1_s3d3));
2257 	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
2258 
2259 	/* Deny MAKE_REG, but allow MAKE_FIFO. */
2260 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, NULL);
2261 
2262 	/*
2263 	 * Try to rename a file with RENAME_WHITEOUT.
2264 	 * file1_s3d3 is in dir_s3d2 (tmpfs), so it supports RENAME_WHITEOUT.
2265 	 * Denied, because whiteout creation is guarded with MAKE_REG.
2266 	 */
2267 	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
2268 				TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
2269 	EXPECT_EQ(EACCES, errno);
2270 }
2271 
2272 static bool is_whiteout(const char *const path)
2273 {
2274 	struct stat st;
2275 
2276 	if (stat(path, &st) == -1)
2277 		return false;
2278 
2279 	return S_ISCHR(st.st_mode) && st.st_rdev == makedev(0, 0);
2280 }
2281 
2282 static bool is_fifo(const char *const path)
2283 {
2284 	struct stat st;
2285 
2286 	return stat(path, &st) == 0 && S_ISFIFO(st.st_mode);
2287 }
2288 
2289 static bool is_missing(const char *const path)
2290 {
2291 	struct stat st;
2292 
2293 	return stat(path, &st) == -1 && errno == ENOENT;
2294 }
2295 
2296 TEST_F_FORK(layout1, rename_whiteout_allowed)
2297 {
2298 	const struct rule rules[] = {
2299 		{
2300 			.path = dir_s3d3,
2301 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2302 		},
2303 		{},
2304 	};
2305 
2306 	/* The affected file is a FIFO. */
2307 	ASSERT_EQ(0, unlink(file1_s3d3));
2308 	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
2309 
2310 	/* Allow MAKE_REG below dir_s3d3. */
2311 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, rules);
2312 
2313 	/*
2314 	 * Rename a file with RENAME_WHITEOUT within the same directory.
2315 	 * Allowed, because MAKE_REG is granted for the whiteout object which
2316 	 * gets created in the source location.
2317 	 */
2318 	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
2319 			       TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
2320 
2321 	/* A whiteout object took the place of the moved FIFO. */
2322 	EXPECT_TRUE(is_whiteout(file1_s3d3));
2323 	EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d3/f2"));
2324 }
2325 
2326 TEST_F_FORK(layout1, rename_whiteout_reparenting)
2327 {
2328 	const struct rule rules[] = {
2329 		{
2330 			.path = dir_s3d2,
2331 			.access = LANDLOCK_ACCESS_FS_REFER,
2332 		},
2333 		{
2334 			.path = dir_s3d3,
2335 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2336 		},
2337 		{},
2338 	};
2339 
2340 	/* The moved files are FIFOs. */
2341 	ASSERT_EQ(0, unlink(file1_s3d3));
2342 	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
2343 	ASSERT_EQ(0, unlink(file1_s3d4));
2344 	ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
2345 
2346 	/* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
2347 	enforce_fs(_metadata,
2348 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
2349 		   rules);
2350 
2351 	/*
2352 	 * The whiteout object is created in the source directory: Moving the
2353 	 * FIFO out of dir_s3d4 is denied because MAKE_REG is not granted
2354 	 * there, even though it is granted in the destination directory
2355 	 * dir_s3d3.
2356 	 */
2357 	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD,
2358 				TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
2359 	EXPECT_EQ(EACCES, errno);
2360 
2361 	/*
2362 	 * Moving the FIFO out of dir_s3d3 is allowed, because MAKE_REG is
2363 	 * granted there for the created whiteout object.
2364 	 */
2365 	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
2366 			       TMP_DIR "/s3d1/s3d2/s3d4/f2", RENAME_WHITEOUT));
2367 
2368 	/* A whiteout object took the place of the moved FIFO. */
2369 	EXPECT_TRUE(is_whiteout(file1_s3d3));
2370 	EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d4/f2"));
2371 }
2372 
2373 TEST_F_FORK(layout1, rename_whiteout_exchange)
2374 {
2375 	const char *const whiteout_s3d3 = TMP_DIR "/s3d1/s3d2/s3d3/f2";
2376 	const struct rule rules[] = {
2377 		{
2378 			.path = dir_s3d2,
2379 			.access = LANDLOCK_ACCESS_FS_REFER,
2380 		},
2381 		{
2382 			.path = dir_s3d3,
2383 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2384 		},
2385 		{},
2386 	};
2387 
2388 	/* The exchanged files are FIFOs and an existing whiteout object. */
2389 	ASSERT_EQ(0, unlink(file1_s3d3));
2390 	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
2391 	ASSERT_EQ(0, mknod(whiteout_s3d3, S_IFCHR | 0600, makedev(0, 0)));
2392 	ASSERT_EQ(0, unlink(file1_s3d4));
2393 	ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
2394 
2395 	/* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
2396 	enforce_fs(_metadata,
2397 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
2398 		   rules);
2399 
2400 	/*
2401 	 * With RENAME_EXCHANGE, the whiteout object moves into the source
2402 	 * directory of the rename: Exchanging the FIFO in dir_s3d4 with the
2403 	 * whiteout object is denied because MAKE_REG is not granted in
2404 	 * dir_s3d4, even though it is granted in the whiteout object's own
2405 	 * directory dir_s3d3.
2406 	 */
2407 	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD, whiteout_s3d3,
2408 				RENAME_EXCHANGE));
2409 	EXPECT_EQ(EACCES, errno);
2410 
2411 	/*
2412 	 * Exchanging the FIFO in dir_s3d3 with the whiteout object is
2413 	 * allowed, because MAKE_REG is granted in the directory into which
2414 	 * the whiteout object moves.
2415 	 */
2416 	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD, whiteout_s3d3,
2417 			       RENAME_EXCHANGE));
2418 
2419 	/* The FIFO and the whiteout object swapped places. */
2420 	EXPECT_TRUE(is_whiteout(file1_s3d3));
2421 	EXPECT_TRUE(is_fifo(whiteout_s3d3));
2422 }
2423 
2424 TEST_F_FORK(layout1, rename_dir)
2425 {
2426 	const struct rule rules[] = {
2427 		{
2428 			.path = dir_s1d2,
2429 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
2430 		},
2431 		{
2432 			.path = dir_s2d1,
2433 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
2434 		},
2435 		{},
2436 	};
2437 
2438 	/* Empties dir_s1d3 to allow renaming. */
2439 	ASSERT_EQ(0, unlink(file1_s1d3));
2440 	ASSERT_EQ(0, unlink(file2_s1d3));
2441 
2442 	enforce_fs(_metadata, rules[0].access, rules);
2443 
2444 	/* Exchanges and renames directory to a different parent. */
2445 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
2446 				RENAME_EXCHANGE));
2447 	ASSERT_EQ(EXDEV, errno);
2448 	ASSERT_EQ(-1, rename(dir_s2d3, dir_s1d3));
2449 	ASSERT_EQ(EXDEV, errno);
2450 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
2451 				RENAME_EXCHANGE));
2452 	ASSERT_EQ(EXDEV, errno);
2453 
2454 	/*
2455 	 * Exchanges directory to the same parent, which doesn't allow
2456 	 * directory removal.
2457 	 */
2458 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
2459 				RENAME_EXCHANGE));
2460 	ASSERT_EQ(EACCES, errno);
2461 	/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
2462 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
2463 	ASSERT_EQ(EACCES, errno);
2464 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
2465 				RENAME_EXCHANGE));
2466 	ASSERT_EQ(EACCES, errno);
2467 	/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
2468 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
2469 	ASSERT_EQ(EACCES, errno);
2470 
2471 	/*
2472 	 * Exchanges and renames directory to the same parent, which allows
2473 	 * directory removal.
2474 	 */
2475 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2,
2476 			       RENAME_EXCHANGE));
2477 	ASSERT_EQ(0, unlink(dir_s1d3));
2478 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
2479 	ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3));
2480 	ASSERT_EQ(0, rmdir(dir_s1d3));
2481 }
2482 
2483 TEST_F_FORK(layout1, reparent_refer)
2484 {
2485 	const struct rule layer1[] = {
2486 		{
2487 			.path = dir_s1d2,
2488 			.access = LANDLOCK_ACCESS_FS_REFER,
2489 		},
2490 		{
2491 			.path = dir_s2d2,
2492 			.access = LANDLOCK_ACCESS_FS_REFER,
2493 		},
2494 		{},
2495 	};
2496 
2497 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REFER, layer1);
2498 
2499 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d1));
2500 	ASSERT_EQ(EXDEV, errno);
2501 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d2));
2502 	ASSERT_EQ(EXDEV, errno);
2503 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d3));
2504 	ASSERT_EQ(EXDEV, errno);
2505 
2506 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d1));
2507 	ASSERT_EQ(EXDEV, errno);
2508 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d2));
2509 	ASSERT_EQ(EXDEV, errno);
2510 	/*
2511 	 * Moving should only be allowed when the source and the destination
2512 	 * parent directory have REFER.
2513 	 */
2514 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d3));
2515 	ASSERT_EQ(ENOTEMPTY, errno);
2516 	ASSERT_EQ(0, unlink(file1_s2d3));
2517 	ASSERT_EQ(0, unlink(file2_s2d3));
2518 	ASSERT_EQ(0, rename(dir_s1d3, dir_s2d3));
2519 }
2520 
2521 /* Checks renames beneath dir_s1d1. */
2522 static void refer_denied_by_default(struct __test_metadata *const _metadata,
2523 				    const struct rule layer1[],
2524 				    const int layer1_err,
2525 				    const struct rule layer2[])
2526 {
2527 	ASSERT_EQ(0, unlink(file1_s1d2));
2528 
2529 	enforce_fs(_metadata, layer1[0].access, layer1);
2530 
2531 	/*
2532 	 * If the first layer handles LANDLOCK_ACCESS_FS_REFER (according to
2533 	 * layer1_err), then it allows some different-parent renames and links.
2534 	 */
2535 	ASSERT_EQ(layer1_err, test_rename(file1_s1d1, file1_s1d2));
2536 	if (layer1_err == 0)
2537 		ASSERT_EQ(layer1_err, test_rename(file1_s1d2, file1_s1d1));
2538 	ASSERT_EQ(layer1_err, test_exchange(file2_s1d1, file2_s1d2));
2539 	ASSERT_EQ(layer1_err, test_exchange(file2_s1d2, file2_s1d1));
2540 
2541 	enforce_fs(_metadata, layer2[0].access, layer2);
2542 
2543 	/*
2544 	 * Now, either the first or the second layer does not handle
2545 	 * LANDLOCK_ACCESS_FS_REFER, which means that any different-parent
2546 	 * renames and links are denied, thus making the layer handling
2547 	 * LANDLOCK_ACCESS_FS_REFER null and void.
2548 	 */
2549 	ASSERT_EQ(EXDEV, test_rename(file1_s1d1, file1_s1d2));
2550 	ASSERT_EQ(EXDEV, test_exchange(file2_s1d1, file2_s1d2));
2551 	ASSERT_EQ(EXDEV, test_exchange(file2_s1d2, file2_s1d1));
2552 }
2553 
2554 const struct rule layer_dir_s1d1_refer[] = {
2555 	{
2556 		.path = dir_s1d1,
2557 		.access = LANDLOCK_ACCESS_FS_REFER,
2558 	},
2559 	{},
2560 };
2561 
2562 const struct rule layer_dir_s1d1_execute[] = {
2563 	{
2564 		/* Matches a parent directory. */
2565 		.path = dir_s1d1,
2566 		.access = LANDLOCK_ACCESS_FS_EXECUTE,
2567 	},
2568 	{},
2569 };
2570 
2571 const struct rule layer_dir_s2d1_execute[] = {
2572 	{
2573 		/* Does not match a parent directory. */
2574 		.path = dir_s2d1,
2575 		.access = LANDLOCK_ACCESS_FS_EXECUTE,
2576 	},
2577 	{},
2578 };
2579 
2580 /*
2581  * Tests precedence over renames: denied by default for different parent
2582  * directories, *with* a rule matching a parent directory, but not directly
2583  * denying access (with MAKE_REG nor REMOVE).
2584  */
2585 TEST_F_FORK(layout1, refer_denied_by_default1)
2586 {
2587 	refer_denied_by_default(_metadata, layer_dir_s1d1_refer, 0,
2588 				layer_dir_s1d1_execute);
2589 }
2590 
2591 /*
2592  * Same test but this time turning around the ABI version order: the first
2593  * layer does not handle LANDLOCK_ACCESS_FS_REFER.
2594  */
2595 TEST_F_FORK(layout1, refer_denied_by_default2)
2596 {
2597 	refer_denied_by_default(_metadata, layer_dir_s1d1_execute, EXDEV,
2598 				layer_dir_s1d1_refer);
2599 }
2600 
2601 /*
2602  * Tests precedence over renames: denied by default for different parent
2603  * directories, *without* a rule matching a parent directory, but not directly
2604  * denying access (with MAKE_REG nor REMOVE).
2605  */
2606 TEST_F_FORK(layout1, refer_denied_by_default3)
2607 {
2608 	refer_denied_by_default(_metadata, layer_dir_s1d1_refer, 0,
2609 				layer_dir_s2d1_execute);
2610 }
2611 
2612 /*
2613  * Same test but this time turning around the ABI version order: the first
2614  * layer does not handle LANDLOCK_ACCESS_FS_REFER.
2615  */
2616 TEST_F_FORK(layout1, refer_denied_by_default4)
2617 {
2618 	refer_denied_by_default(_metadata, layer_dir_s2d1_execute, EXDEV,
2619 				layer_dir_s1d1_refer);
2620 }
2621 
2622 /*
2623  * Tests walking through a denied root mount.
2624  */
2625 TEST_F_FORK(layout1, refer_mount_root_deny)
2626 {
2627 	int root_fd;
2628 
2629 	/* Creates a mount object from a non-mount point. */
2630 	set_cap(_metadata, CAP_SYS_ADMIN);
2631 	root_fd =
2632 		open_tree(AT_FDCWD, dir_s1d1,
2633 			  AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
2634 	clear_cap(_metadata, CAP_SYS_ADMIN);
2635 	ASSERT_LE(0, root_fd);
2636 
2637 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_DIR, NULL);
2638 
2639 	/* Link denied by Landlock: EACCES. */
2640 	EXPECT_EQ(-1, linkat(root_fd, ".", root_fd, "does_not_exist", 0));
2641 	EXPECT_EQ(EACCES, errno);
2642 
2643 	/* renameat2() always returns EBUSY. */
2644 	EXPECT_EQ(-1, renameat2(root_fd, ".", root_fd, "does_not_exist", 0));
2645 	EXPECT_EQ(EBUSY, errno);
2646 
2647 	EXPECT_EQ(0, close(root_fd));
2648 }
2649 
2650 TEST_F_FORK(layout1, refer_part_mount_tree_is_allowed)
2651 {
2652 	const struct rule layer1[] = {
2653 		{
2654 			/* Parent mount point. */
2655 			.path = dir_s3d1,
2656 			.access = LANDLOCK_ACCESS_FS_REFER |
2657 				  LANDLOCK_ACCESS_FS_MAKE_REG,
2658 		},
2659 		{
2660 			/*
2661 			 * Removing the source file is allowed because its
2662 			 * access rights are already a superset of the
2663 			 * destination.
2664 			 */
2665 			.path = dir_s3d4,
2666 			.access = LANDLOCK_ACCESS_FS_REFER |
2667 				  LANDLOCK_ACCESS_FS_MAKE_REG |
2668 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
2669 		},
2670 		{},
2671 	};
2672 
2673 	ASSERT_EQ(0, unlink(file1_s3d3));
2674 	enforce_fs(_metadata,
2675 		   LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
2676 			   LANDLOCK_ACCESS_FS_REMOVE_FILE,
2677 		   layer1);
2678 
2679 	ASSERT_EQ(0, rename(file1_s3d4, file1_s3d3));
2680 }
2681 
2682 TEST_F_FORK(layout1, reparent_link)
2683 {
2684 	const struct rule layer1[] = {
2685 		{
2686 			.path = dir_s1d2,
2687 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2688 		},
2689 		{
2690 			.path = dir_s1d3,
2691 			.access = LANDLOCK_ACCESS_FS_REFER,
2692 		},
2693 		{
2694 			.path = dir_s2d2,
2695 			.access = LANDLOCK_ACCESS_FS_REFER,
2696 		},
2697 		{
2698 			.path = dir_s2d3,
2699 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2700 		},
2701 		{},
2702 	};
2703 
2704 	enforce_fs(_metadata,
2705 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
2706 		   layer1);
2707 
2708 	ASSERT_EQ(0, unlink(file1_s1d1));
2709 	ASSERT_EQ(0, unlink(file1_s1d2));
2710 	ASSERT_EQ(0, unlink(file1_s1d3));
2711 
2712 	/* Denies linking because of missing MAKE_REG. */
2713 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2714 	ASSERT_EQ(EACCES, errno);
2715 	/* Denies linking because of missing source and destination REFER. */
2716 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
2717 	ASSERT_EQ(EXDEV, errno);
2718 	/* Denies linking because of missing source REFER. */
2719 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d3));
2720 	ASSERT_EQ(EXDEV, errno);
2721 
2722 	/* Denies linking because of missing MAKE_REG. */
2723 	ASSERT_EQ(-1, link(file1_s2d2, file1_s1d1));
2724 	ASSERT_EQ(EACCES, errno);
2725 	/* Denies linking because of missing destination REFER. */
2726 	ASSERT_EQ(-1, link(file1_s2d2, file1_s1d2));
2727 	ASSERT_EQ(EXDEV, errno);
2728 
2729 	/* Allows linking because of REFER and MAKE_REG. */
2730 	ASSERT_EQ(0, link(file1_s2d2, file1_s1d3));
2731 	ASSERT_EQ(0, unlink(file1_s2d2));
2732 	/* Reverse linking denied because of missing MAKE_REG. */
2733 	ASSERT_EQ(-1, link(file1_s1d3, file1_s2d2));
2734 	ASSERT_EQ(EACCES, errno);
2735 	ASSERT_EQ(0, unlink(file1_s2d3));
2736 	/* Checks reverse linking. */
2737 	ASSERT_EQ(0, link(file1_s1d3, file1_s2d3));
2738 	ASSERT_EQ(0, unlink(file1_s1d3));
2739 
2740 	/*
2741 	 * This is OK for a file link, but it should not be allowed for a
2742 	 * directory rename (because of the superset of access rights.
2743 	 */
2744 	ASSERT_EQ(0, link(file1_s2d3, file1_s1d3));
2745 	ASSERT_EQ(0, unlink(file1_s1d3));
2746 
2747 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
2748 	ASSERT_EQ(EXDEV, errno);
2749 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
2750 	ASSERT_EQ(EXDEV, errno);
2751 
2752 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
2753 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
2754 }
2755 
2756 TEST_F_FORK(layout1, reparent_rename)
2757 {
2758 	/* Same rules as for reparent_link. */
2759 	const struct rule layer1[] = {
2760 		{
2761 			.path = dir_s1d2,
2762 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2763 		},
2764 		{
2765 			.path = dir_s1d3,
2766 			.access = LANDLOCK_ACCESS_FS_REFER,
2767 		},
2768 		{
2769 			.path = dir_s2d2,
2770 			.access = LANDLOCK_ACCESS_FS_REFER,
2771 		},
2772 		{
2773 			.path = dir_s2d3,
2774 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2775 		},
2776 		{},
2777 	};
2778 
2779 	enforce_fs(_metadata,
2780 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
2781 		   layer1);
2782 
2783 	ASSERT_EQ(0, unlink(file1_s1d2));
2784 	ASSERT_EQ(0, unlink(file1_s1d3));
2785 
2786 	/* Denies renaming because of missing MAKE_REG. */
2787 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file1_s1d1,
2788 				RENAME_EXCHANGE));
2789 	ASSERT_EQ(EACCES, errno);
2790 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1,
2791 				RENAME_EXCHANGE));
2792 	ASSERT_EQ(EACCES, errno);
2793 	ASSERT_EQ(0, unlink(file1_s1d1));
2794 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
2795 	ASSERT_EQ(EACCES, errno);
2796 	/* Even denies same file exchange. */
2797 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file2_s1d1,
2798 				RENAME_EXCHANGE));
2799 	ASSERT_EQ(EACCES, errno);
2800 
2801 	/* Denies renaming because of missing source and destination REFER. */
2802 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d2));
2803 	ASSERT_EQ(EXDEV, errno);
2804 	/*
2805 	 * Denies renaming because of missing MAKE_REG, source and destination
2806 	 * REFER.
2807 	 */
2808 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file2_s1d1,
2809 				RENAME_EXCHANGE));
2810 	ASSERT_EQ(EACCES, errno);
2811 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file1_s2d1,
2812 				RENAME_EXCHANGE));
2813 	ASSERT_EQ(EACCES, errno);
2814 
2815 	/* Denies renaming because of missing source REFER. */
2816 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2817 	ASSERT_EQ(EXDEV, errno);
2818 	/* Denies renaming because of missing MAKE_REG. */
2819 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file2_s1d3,
2820 				RENAME_EXCHANGE));
2821 	ASSERT_EQ(EACCES, errno);
2822 
2823 	/* Denies renaming because of missing MAKE_REG. */
2824 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d1));
2825 	ASSERT_EQ(EACCES, errno);
2826 	/* Denies renaming because of missing destination REFER*/
2827 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
2828 	ASSERT_EQ(EXDEV, errno);
2829 
2830 	/* Denies exchange because of one missing MAKE_REG. */
2831 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, file2_s1d3,
2832 				RENAME_EXCHANGE));
2833 	ASSERT_EQ(EACCES, errno);
2834 	/* Allows renaming because of REFER and MAKE_REG. */
2835 	ASSERT_EQ(0, rename(file1_s2d2, file1_s1d3));
2836 
2837 	/* Reverse renaming denied because of missing MAKE_REG. */
2838 	ASSERT_EQ(-1, rename(file1_s1d3, file1_s2d2));
2839 	ASSERT_EQ(EACCES, errno);
2840 	ASSERT_EQ(0, unlink(file1_s2d3));
2841 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2842 
2843 	/* Tests reverse renaming. */
2844 	ASSERT_EQ(0, rename(file1_s2d3, file1_s1d3));
2845 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s1d3,
2846 			       RENAME_EXCHANGE));
2847 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2848 
2849 	/*
2850 	 * This is OK for a file rename, but it should not be allowed for a
2851 	 * directory rename (because of the superset of access rights).
2852 	 */
2853 	ASSERT_EQ(0, rename(file1_s2d3, file1_s1d3));
2854 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2855 
2856 	/*
2857 	 * Tests superset restrictions applied to directories.  Not only the
2858 	 * dir_s2d3's parent (dir_s2d2) should be taken into account but also
2859 	 * access rights tied to dir_s2d3. dir_s2d2 is missing one access right
2860 	 * compared to dir_s1d3/file1_s1d3 (MAKE_REG) but it is provided
2861 	 * directly by the moved dir_s2d3.
2862 	 */
2863 	ASSERT_EQ(0, rename(dir_s2d3, file1_s1d3));
2864 	ASSERT_EQ(0, rename(file1_s1d3, dir_s2d3));
2865 	/*
2866 	 * The first rename is allowed but not the exchange because dir_s1d3's
2867 	 * parent (dir_s1d2) doesn't have REFER.
2868 	 */
2869 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
2870 				RENAME_EXCHANGE));
2871 	ASSERT_EQ(EXDEV, errno);
2872 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s2d3,
2873 				RENAME_EXCHANGE));
2874 	ASSERT_EQ(EXDEV, errno);
2875 	ASSERT_EQ(-1, rename(file1_s2d3, dir_s1d3));
2876 	ASSERT_EQ(EXDEV, errno);
2877 
2878 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s1d3));
2879 	ASSERT_EQ(EXDEV, errno);
2880 	ASSERT_EQ(-1, rename(file2_s1d3, file1_s1d2));
2881 	ASSERT_EQ(EXDEV, errno);
2882 
2883 	/* Renaming in the same directory is always allowed. */
2884 	ASSERT_EQ(0, rename(file2_s1d2, file1_s1d2));
2885 	ASSERT_EQ(0, rename(file2_s1d3, file1_s1d3));
2886 
2887 	ASSERT_EQ(0, unlink(file1_s1d2));
2888 	/* Denies because of missing source MAKE_REG and destination REFER. */
2889 	ASSERT_EQ(-1, rename(dir_s2d3, file1_s1d2));
2890 	ASSERT_EQ(EXDEV, errno);
2891 
2892 	ASSERT_EQ(0, unlink(file1_s1d3));
2893 	/* Denies because of missing source MAKE_REG and REFER. */
2894 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s1d3));
2895 	ASSERT_EQ(EXDEV, errno);
2896 }
2897 
2898 static void
2899 reparent_exdev_layers_enforce1(struct __test_metadata *const _metadata)
2900 {
2901 	const struct rule layer1[] = {
2902 		{
2903 			.path = dir_s1d2,
2904 			.access = LANDLOCK_ACCESS_FS_REFER,
2905 		},
2906 		{
2907 			/* Interesting for the layer2 tests. */
2908 			.path = dir_s1d3,
2909 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2910 		},
2911 		{
2912 			.path = dir_s2d2,
2913 			.access = LANDLOCK_ACCESS_FS_REFER,
2914 		},
2915 		{
2916 			.path = dir_s2d3,
2917 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2918 		},
2919 		{},
2920 	};
2921 	enforce_fs(_metadata,
2922 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
2923 		   layer1);
2924 }
2925 
2926 static void
2927 reparent_exdev_layers_enforce2(struct __test_metadata *const _metadata)
2928 {
2929 	const struct rule layer2[] = {
2930 		{
2931 			.path = dir_s2d3,
2932 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
2933 		},
2934 		{},
2935 	};
2936 	/*
2937 	 * Same checks as before but with a second layer and a new MAKE_DIR
2938 	 * rule (and no explicit handling of REFER).
2939 	 */
2940 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_DIR, layer2);
2941 }
2942 
2943 TEST_F_FORK(layout1, reparent_exdev_layers_rename1)
2944 {
2945 	ASSERT_EQ(0, unlink(file1_s2d2));
2946 	ASSERT_EQ(0, unlink(file1_s2d3));
2947 
2948 	reparent_exdev_layers_enforce1(_metadata);
2949 
2950 	/*
2951 	 * Moving the dir_s1d3 directory below dir_s2d2 is allowed by Landlock
2952 	 * because it doesn't inherit new access rights.
2953 	 */
2954 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d2));
2955 	ASSERT_EQ(0, rename(file1_s2d2, dir_s1d3));
2956 
2957 	/*
2958 	 * Moving the dir_s1d3 directory below dir_s2d3 is allowed, even if it
2959 	 * gets a new inherited access rights (MAKE_REG), because MAKE_REG is
2960 	 * already allowed for dir_s1d3.
2961 	 */
2962 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d3));
2963 	ASSERT_EQ(0, rename(file1_s2d3, dir_s1d3));
2964 
2965 	/*
2966 	 * However, moving the file1_s1d3 file below dir_s2d3 is allowed
2967 	 * because it cannot inherit MAKE_REG right (which is dedicated to
2968 	 * directories).
2969 	 */
2970 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2971 
2972 	reparent_exdev_layers_enforce2(_metadata);
2973 
2974 	/*
2975 	 * Moving the dir_s1d3 directory below dir_s2d2 is now denied because
2976 	 * MAKE_DIR is not tied to dir_s2d2.
2977 	 */
2978 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d2));
2979 	ASSERT_EQ(EACCES, errno);
2980 
2981 	/*
2982 	 * Moving the dir_s1d3 directory below dir_s2d3 is forbidden because it
2983 	 * would grants MAKE_REG and MAKE_DIR rights to it.
2984 	 */
2985 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d3));
2986 	ASSERT_EQ(EXDEV, errno);
2987 
2988 	/*
2989 	 * Moving the file2_s1d3 file below dir_s2d3 is denied because the
2990 	 * second layer does not handle REFER, which is always denied by
2991 	 * default.
2992 	 */
2993 	ASSERT_EQ(-1, rename(file2_s1d3, file1_s2d3));
2994 	ASSERT_EQ(EXDEV, errno);
2995 }
2996 
2997 TEST_F_FORK(layout1, reparent_exdev_layers_rename2)
2998 {
2999 	reparent_exdev_layers_enforce1(_metadata);
3000 
3001 	/* Checks EACCES predominance over EXDEV. */
3002 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d2));
3003 	ASSERT_EQ(EACCES, errno);
3004 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d2));
3005 	ASSERT_EQ(EACCES, errno);
3006 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d3));
3007 	ASSERT_EQ(EXDEV, errno);
3008 	/* Modify layout! */
3009 	ASSERT_EQ(0, rename(file1_s1d2, file1_s2d3));
3010 
3011 	/* Without REFER source. */
3012 	ASSERT_EQ(-1, rename(dir_s1d1, file1_s2d2));
3013 	ASSERT_EQ(EXDEV, errno);
3014 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d2));
3015 	ASSERT_EQ(EXDEV, errno);
3016 
3017 	reparent_exdev_layers_enforce2(_metadata);
3018 
3019 	/* Checks EACCES predominance over EXDEV. */
3020 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d2));
3021 	ASSERT_EQ(EACCES, errno);
3022 	/* Checks with actual file2_s1d2. */
3023 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d2));
3024 	ASSERT_EQ(EACCES, errno);
3025 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d3));
3026 	ASSERT_EQ(EXDEV, errno);
3027 	/*
3028 	 * Modifying the layout is now denied because the second layer does not
3029 	 * handle REFER, which is always denied by default.
3030 	 */
3031 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d3));
3032 	ASSERT_EQ(EXDEV, errno);
3033 
3034 	/* Without REFER source, EACCES wins over EXDEV. */
3035 	ASSERT_EQ(-1, rename(dir_s1d1, file1_s2d2));
3036 	ASSERT_EQ(EACCES, errno);
3037 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d2));
3038 	ASSERT_EQ(EACCES, errno);
3039 }
3040 
3041 TEST_F_FORK(layout1, reparent_exdev_layers_exchange1)
3042 {
3043 	const char *const dir_file1_s1d2 = file1_s1d2, *const dir_file2_s2d3 =
3044 							       file2_s2d3;
3045 
3046 	ASSERT_EQ(0, unlink(file1_s1d2));
3047 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
3048 	ASSERT_EQ(0, unlink(file2_s2d3));
3049 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
3050 
3051 	reparent_exdev_layers_enforce1(_metadata);
3052 
3053 	/* Error predominance with file exchange: returns EXDEV and EACCES. */
3054 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d3,
3055 				RENAME_EXCHANGE));
3056 	ASSERT_EQ(EACCES, errno);
3057 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d1,
3058 				RENAME_EXCHANGE));
3059 	ASSERT_EQ(EACCES, errno);
3060 
3061 	/*
3062 	 * Checks with directories which creation could be allowed, but denied
3063 	 * because of access rights that would be inherited.
3064 	 */
3065 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD,
3066 				dir_file2_s2d3, RENAME_EXCHANGE));
3067 	ASSERT_EQ(EXDEV, errno);
3068 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD,
3069 				dir_file1_s1d2, RENAME_EXCHANGE));
3070 	ASSERT_EQ(EXDEV, errno);
3071 
3072 	/* Checks with same access rights. */
3073 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s2d3,
3074 			       RENAME_EXCHANGE));
3075 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
3076 			       RENAME_EXCHANGE));
3077 
3078 	/* Checks with different (child-only) access rights. */
3079 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_file1_s1d2,
3080 			       RENAME_EXCHANGE));
3081 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD, dir_s2d3,
3082 			       RENAME_EXCHANGE));
3083 
3084 	/*
3085 	 * Checks that exchange between file and directory are consistent.
3086 	 *
3087 	 * Moving a file (file1_s2d2) to a directory which only grants more
3088 	 * directory-related access rights is allowed, and at the same time
3089 	 * moving a directory (dir_file2_s2d3) to another directory which
3090 	 * grants less access rights is allowed too.
3091 	 *
3092 	 * See layout1.reparent_exdev_layers_exchange3 for inverted arguments.
3093 	 */
3094 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
3095 			       RENAME_EXCHANGE));
3096 	/*
3097 	 * However, moving back the directory is denied because it would get
3098 	 * more access rights than the current state and because file creation
3099 	 * is forbidden (in dir_s2d2).
3100 	 */
3101 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
3102 				RENAME_EXCHANGE));
3103 	ASSERT_EQ(EACCES, errno);
3104 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
3105 				RENAME_EXCHANGE));
3106 	ASSERT_EQ(EACCES, errno);
3107 
3108 	reparent_exdev_layers_enforce2(_metadata);
3109 
3110 	/* Error predominance with file exchange: returns EXDEV and EACCES. */
3111 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d3,
3112 				RENAME_EXCHANGE));
3113 	ASSERT_EQ(EACCES, errno);
3114 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d1,
3115 				RENAME_EXCHANGE));
3116 	ASSERT_EQ(EACCES, errno);
3117 
3118 	/* Checks with directories which creation is now denied. */
3119 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD,
3120 				dir_file2_s2d3, RENAME_EXCHANGE));
3121 	ASSERT_EQ(EACCES, errno);
3122 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD,
3123 				dir_file1_s1d2, RENAME_EXCHANGE));
3124 	ASSERT_EQ(EACCES, errno);
3125 
3126 	/* Checks with different (child-only) access rights. */
3127 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s2d3,
3128 				RENAME_EXCHANGE));
3129 	/* Denied because of MAKE_DIR. */
3130 	ASSERT_EQ(EACCES, errno);
3131 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
3132 				RENAME_EXCHANGE));
3133 	ASSERT_EQ(EACCES, errno);
3134 
3135 	/* Checks with different (child-only) access rights. */
3136 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_file1_s1d2,
3137 				RENAME_EXCHANGE));
3138 	/* Denied because of MAKE_DIR. */
3139 	ASSERT_EQ(EACCES, errno);
3140 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD, dir_s2d3,
3141 				RENAME_EXCHANGE));
3142 	ASSERT_EQ(EACCES, errno);
3143 
3144 	/* See layout1.reparent_exdev_layers_exchange2 for complement. */
3145 }
3146 
3147 TEST_F_FORK(layout1, reparent_exdev_layers_exchange2)
3148 {
3149 	const char *const dir_file2_s2d3 = file2_s2d3;
3150 
3151 	ASSERT_EQ(0, unlink(file2_s2d3));
3152 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
3153 
3154 	reparent_exdev_layers_enforce1(_metadata);
3155 	reparent_exdev_layers_enforce2(_metadata);
3156 
3157 	/* Checks that exchange between file and directory are consistent. */
3158 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
3159 				RENAME_EXCHANGE));
3160 	ASSERT_EQ(EACCES, errno);
3161 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
3162 				RENAME_EXCHANGE));
3163 	ASSERT_EQ(EACCES, errno);
3164 }
3165 
3166 TEST_F_FORK(layout1, reparent_exdev_layers_exchange3)
3167 {
3168 	const char *const dir_file2_s2d3 = file2_s2d3;
3169 
3170 	ASSERT_EQ(0, unlink(file2_s2d3));
3171 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
3172 
3173 	reparent_exdev_layers_enforce1(_metadata);
3174 
3175 	/*
3176 	 * Checks that exchange between file and directory are consistent,
3177 	 * including with inverted arguments (see
3178 	 * layout1.reparent_exdev_layers_exchange1).
3179 	 */
3180 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
3181 			       RENAME_EXCHANGE));
3182 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
3183 				RENAME_EXCHANGE));
3184 	ASSERT_EQ(EACCES, errno);
3185 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
3186 				RENAME_EXCHANGE));
3187 	ASSERT_EQ(EACCES, errno);
3188 }
3189 
3190 TEST_F_FORK(layout1, reparent_remove)
3191 {
3192 	const struct rule layer1[] = {
3193 		{
3194 			.path = dir_s1d1,
3195 			.access = LANDLOCK_ACCESS_FS_REFER |
3196 				  LANDLOCK_ACCESS_FS_REMOVE_DIR,
3197 		},
3198 		{
3199 			.path = dir_s1d2,
3200 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
3201 		},
3202 		{
3203 			.path = dir_s2d1,
3204 			.access = LANDLOCK_ACCESS_FS_REFER |
3205 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
3206 		},
3207 		{},
3208 	};
3209 
3210 	enforce_fs(_metadata,
3211 		   LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_REMOVE_DIR |
3212 			   LANDLOCK_ACCESS_FS_REMOVE_FILE,
3213 		   layer1);
3214 
3215 	/* Access denied because of wrong/swapped remove file/dir. */
3216 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s2d2));
3217 	ASSERT_EQ(EACCES, errno);
3218 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s1d1));
3219 	ASSERT_EQ(EACCES, errno);
3220 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s2d2,
3221 				RENAME_EXCHANGE));
3222 	ASSERT_EQ(EACCES, errno);
3223 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s2d3,
3224 				RENAME_EXCHANGE));
3225 	ASSERT_EQ(EACCES, errno);
3226 
3227 	/* Access allowed thanks to the matching rights. */
3228 	ASSERT_EQ(-1, rename(file1_s2d1, dir_s1d2));
3229 	ASSERT_EQ(EISDIR, errno);
3230 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d1));
3231 	ASSERT_EQ(ENOTDIR, errno);
3232 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d1));
3233 	ASSERT_EQ(ENOTDIR, errno);
3234 	ASSERT_EQ(0, unlink(file1_s2d1));
3235 	ASSERT_EQ(0, unlink(file1_s1d3));
3236 	ASSERT_EQ(0, unlink(file2_s1d3));
3237 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d1));
3238 
3239 	/* Effectively removes a file and a directory by exchanging them. */
3240 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
3241 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
3242 			       RENAME_EXCHANGE));
3243 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
3244 				RENAME_EXCHANGE));
3245 	ASSERT_EQ(EACCES, errno);
3246 }
3247 
3248 TEST_F_FORK(layout1, reparent_dom_superset)
3249 {
3250 	const struct rule layer1[] = {
3251 		{
3252 			.path = dir_s1d2,
3253 			.access = LANDLOCK_ACCESS_FS_REFER,
3254 		},
3255 		{
3256 			.path = file1_s1d2,
3257 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
3258 		},
3259 		{
3260 			.path = dir_s1d3,
3261 			.access = LANDLOCK_ACCESS_FS_MAKE_SOCK |
3262 				  LANDLOCK_ACCESS_FS_EXECUTE,
3263 		},
3264 		{
3265 			.path = dir_s2d2,
3266 			.access = LANDLOCK_ACCESS_FS_REFER |
3267 				  LANDLOCK_ACCESS_FS_EXECUTE |
3268 				  LANDLOCK_ACCESS_FS_MAKE_SOCK,
3269 		},
3270 		{
3271 			.path = dir_s2d3,
3272 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3273 				  LANDLOCK_ACCESS_FS_MAKE_FIFO,
3274 		},
3275 		{},
3276 	};
3277 
3278 	enforce_fs(_metadata,
3279 		   LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_EXECUTE |
3280 			   LANDLOCK_ACCESS_FS_MAKE_SOCK |
3281 			   LANDLOCK_ACCESS_FS_READ_FILE |
3282 			   LANDLOCK_ACCESS_FS_MAKE_FIFO,
3283 		   layer1);
3284 
3285 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d1));
3286 	ASSERT_EQ(EXDEV, errno);
3287 	/*
3288 	 * Moving file1_s1d2 beneath dir_s2d3 would grant it the READ_FILE
3289 	 * access right.
3290 	 */
3291 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d3));
3292 	ASSERT_EQ(EXDEV, errno);
3293 	/*
3294 	 * Moving file1_s1d2 should be allowed even if dir_s2d2 grants a
3295 	 * superset of access rights compared to dir_s1d2, because file1_s1d2
3296 	 * already has these access rights anyway.
3297 	 */
3298 	ASSERT_EQ(0, rename(file1_s1d2, file1_s2d2));
3299 	ASSERT_EQ(0, rename(file1_s2d2, file1_s1d2));
3300 
3301 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d1));
3302 	ASSERT_EQ(EXDEV, errno);
3303 	/*
3304 	 * Moving dir_s1d3 beneath dir_s2d3 would grant it the MAKE_FIFO access
3305 	 * right.
3306 	 */
3307 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d3));
3308 	ASSERT_EQ(EXDEV, errno);
3309 	/*
3310 	 * Moving dir_s1d3 should be allowed even if dir_s2d2 grants a superset
3311 	 * of access rights compared to dir_s1d2, because dir_s1d3 already has
3312 	 * these access rights anyway.
3313 	 */
3314 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d2));
3315 	ASSERT_EQ(0, rename(file1_s2d2, dir_s1d3));
3316 
3317 	/*
3318 	 * Moving file1_s2d3 beneath dir_s1d2 is allowed, but moving it back
3319 	 * will be denied because the new inherited access rights from dir_s1d2
3320 	 * will be less than the destination (original) dir_s2d3.  This is a
3321 	 * sinkhole scenario where we cannot move back files or directories.
3322 	 */
3323 	ASSERT_EQ(0, rename(file1_s2d3, file2_s1d2));
3324 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d3));
3325 	ASSERT_EQ(EXDEV, errno);
3326 	ASSERT_EQ(0, unlink(file2_s1d2));
3327 	ASSERT_EQ(0, unlink(file2_s2d3));
3328 	/*
3329 	 * Checks similar directory one-way move: dir_s2d3 loses EXECUTE and
3330 	 * MAKE_SOCK which were inherited from dir_s1d3.
3331 	 */
3332 	ASSERT_EQ(0, rename(dir_s2d3, file2_s1d2));
3333 	ASSERT_EQ(-1, rename(file2_s1d2, dir_s2d3));
3334 	ASSERT_EQ(EXDEV, errno);
3335 }
3336 
3337 TEST_F_FORK(layout1, remove_dir)
3338 {
3339 	const struct rule rules[] = {
3340 		{
3341 			.path = dir_s1d2,
3342 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
3343 		},
3344 		{},
3345 	};
3346 
3347 	ASSERT_EQ(0, unlink(file1_s1d1));
3348 	ASSERT_EQ(0, unlink(file1_s1d2));
3349 	ASSERT_EQ(0, unlink(file1_s1d3));
3350 	ASSERT_EQ(0, unlink(file2_s1d3));
3351 
3352 	enforce_fs(_metadata, rules[0].access, rules);
3353 
3354 	ASSERT_EQ(0, rmdir(dir_s1d3));
3355 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
3356 	ASSERT_EQ(0, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
3357 
3358 	/* dir_s1d2 itself cannot be removed. */
3359 	ASSERT_EQ(-1, rmdir(dir_s1d2));
3360 	ASSERT_EQ(EACCES, errno);
3361 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d2, AT_REMOVEDIR));
3362 	ASSERT_EQ(EACCES, errno);
3363 	ASSERT_EQ(-1, rmdir(dir_s1d1));
3364 	ASSERT_EQ(EACCES, errno);
3365 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d1, AT_REMOVEDIR));
3366 	ASSERT_EQ(EACCES, errno);
3367 }
3368 
3369 TEST_F_FORK(layout1, remove_file)
3370 {
3371 	const struct rule rules[] = {
3372 		{
3373 			.path = dir_s1d2,
3374 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
3375 		},
3376 		{},
3377 	};
3378 
3379 	enforce_fs(_metadata, rules[0].access, rules);
3380 
3381 	ASSERT_EQ(-1, unlink(file1_s1d1));
3382 	ASSERT_EQ(EACCES, errno);
3383 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, file1_s1d1, 0));
3384 	ASSERT_EQ(EACCES, errno);
3385 	ASSERT_EQ(0, unlink(file1_s1d2));
3386 	ASSERT_EQ(0, unlinkat(AT_FDCWD, file1_s1d3, 0));
3387 }
3388 
3389 static void test_make_file(struct __test_metadata *const _metadata,
3390 			   const __u64 access, const mode_t mode,
3391 			   const dev_t dev)
3392 {
3393 	const struct rule rules[] = {
3394 		{
3395 			.path = dir_s1d2,
3396 			.access = access,
3397 		},
3398 		{},
3399 	};
3400 
3401 	ASSERT_EQ(0, unlink(file1_s1d1));
3402 	ASSERT_EQ(0, unlink(file2_s1d1));
3403 	ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev))
3404 	{
3405 		TH_LOG("Failed to make file \"%s\": %s", file2_s1d1,
3406 		       strerror(errno));
3407 	};
3408 
3409 	ASSERT_EQ(0, unlink(file1_s1d2));
3410 	ASSERT_EQ(0, unlink(file2_s1d2));
3411 
3412 	ASSERT_EQ(0, unlink(file1_s1d3));
3413 	ASSERT_EQ(0, unlink(file2_s1d3));
3414 
3415 	enforce_fs(_metadata, access, rules);
3416 
3417 	ASSERT_EQ(-1, mknod(file1_s1d1, mode | 0400, dev));
3418 	ASSERT_EQ(EACCES, errno);
3419 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
3420 	ASSERT_EQ(EACCES, errno);
3421 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
3422 	ASSERT_EQ(EACCES, errno);
3423 
3424 	ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev))
3425 	{
3426 		TH_LOG("Failed to make file \"%s\": %s", file1_s1d2,
3427 		       strerror(errno));
3428 	};
3429 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
3430 	ASSERT_EQ(0, unlink(file2_s1d2));
3431 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
3432 
3433 	ASSERT_EQ(0, mknod(file1_s1d3, mode | 0400, dev));
3434 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
3435 	ASSERT_EQ(0, unlink(file2_s1d3));
3436 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
3437 }
3438 
3439 TEST_F_FORK(layout1, make_char)
3440 {
3441 	/* Creates a /dev/null device. */
3442 	set_cap(_metadata, CAP_MKNOD);
3443 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR,
3444 		       makedev(1, 3));
3445 }
3446 
3447 TEST_F_FORK(layout1, make_whiteout)
3448 {
3449 	/*
3450 	 * Creates a whiteout object (creation guarded by MAKE_REG).
3451 	 *
3452 	 * Contrary to the other character devices, this does not require
3453 	 * CAP_MKNOD, cf. vfs_mknod().
3454 	 */
3455 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFCHR,
3456 		       makedev(0, 0));
3457 }
3458 
3459 TEST_F_FORK(layout1, make_block)
3460 {
3461 	/* Creates a /dev/loop0 device. */
3462 	set_cap(_metadata, CAP_MKNOD);
3463 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK,
3464 		       makedev(7, 0));
3465 }
3466 
3467 TEST_F_FORK(layout1, make_reg_1)
3468 {
3469 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFREG, 0);
3470 }
3471 
3472 TEST_F_FORK(layout1, make_reg_2)
3473 {
3474 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, 0, 0);
3475 }
3476 
3477 TEST_F_FORK(layout1, make_sock)
3478 {
3479 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_SOCK, S_IFSOCK, 0);
3480 }
3481 
3482 TEST_F_FORK(layout1, make_fifo)
3483 {
3484 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_FIFO, S_IFIFO, 0);
3485 }
3486 
3487 TEST_F_FORK(layout1, make_sym)
3488 {
3489 	const struct rule rules[] = {
3490 		{
3491 			.path = dir_s1d2,
3492 			.access = LANDLOCK_ACCESS_FS_MAKE_SYM,
3493 		},
3494 		{},
3495 	};
3496 
3497 	ASSERT_EQ(0, unlink(file1_s1d1));
3498 	ASSERT_EQ(0, unlink(file2_s1d1));
3499 	ASSERT_EQ(0, symlink("none", file2_s1d1));
3500 
3501 	ASSERT_EQ(0, unlink(file1_s1d2));
3502 	ASSERT_EQ(0, unlink(file2_s1d2));
3503 
3504 	ASSERT_EQ(0, unlink(file1_s1d3));
3505 	ASSERT_EQ(0, unlink(file2_s1d3));
3506 
3507 	enforce_fs(_metadata, rules[0].access, rules);
3508 
3509 	ASSERT_EQ(-1, symlink("none", file1_s1d1));
3510 	ASSERT_EQ(EACCES, errno);
3511 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
3512 	ASSERT_EQ(EACCES, errno);
3513 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
3514 	ASSERT_EQ(EACCES, errno);
3515 
3516 	ASSERT_EQ(0, symlink("none", file1_s1d2));
3517 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
3518 	ASSERT_EQ(0, unlink(file2_s1d2));
3519 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
3520 
3521 	ASSERT_EQ(0, symlink("none", file1_s1d3));
3522 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
3523 	ASSERT_EQ(0, unlink(file2_s1d3));
3524 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
3525 }
3526 
3527 TEST_F_FORK(layout1, make_dir)
3528 {
3529 	const struct rule rules[] = {
3530 		{
3531 			.path = dir_s1d2,
3532 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
3533 		},
3534 		{},
3535 	};
3536 
3537 	ASSERT_EQ(0, unlink(file1_s1d1));
3538 	ASSERT_EQ(0, unlink(file1_s1d2));
3539 	ASSERT_EQ(0, unlink(file1_s1d3));
3540 
3541 	enforce_fs(_metadata, rules[0].access, rules);
3542 
3543 	/* Uses file_* as directory names. */
3544 	ASSERT_EQ(-1, mkdir(file1_s1d1, 0700));
3545 	ASSERT_EQ(EACCES, errno);
3546 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
3547 	ASSERT_EQ(0, mkdir(file1_s1d3, 0700));
3548 }
3549 
3550 static int open_proc_fd(struct __test_metadata *const _metadata, const int fd,
3551 			const int open_flags)
3552 {
3553 	static const char path_template[] = "/proc/self/fd/%d";
3554 	char procfd_path[sizeof(path_template) + 10];
3555 	const int procfd_path_size =
3556 		snprintf(procfd_path, sizeof(procfd_path), path_template, fd);
3557 
3558 	ASSERT_LT(procfd_path_size, sizeof(procfd_path));
3559 	return open(procfd_path, open_flags);
3560 }
3561 
3562 TEST_F_FORK(layout1, proc_unlinked_file)
3563 {
3564 	const struct rule rules[] = {
3565 		{
3566 			.path = file1_s1d2,
3567 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
3568 		},
3569 		{},
3570 	};
3571 	int reg_fd, proc_fd;
3572 
3573 	enforce_fs(_metadata,
3574 		   LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
3575 		   rules);
3576 
3577 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
3578 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
3579 	reg_fd = open(file1_s1d2, O_RDONLY | O_CLOEXEC);
3580 	ASSERT_LE(0, reg_fd);
3581 	ASSERT_EQ(0, unlink(file1_s1d2));
3582 
3583 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDONLY | O_CLOEXEC);
3584 	ASSERT_LE(0, proc_fd);
3585 	ASSERT_EQ(0, close(proc_fd));
3586 
3587 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC);
3588 	ASSERT_EQ(-1, proc_fd)
3589 	{
3590 		TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd,
3591 		       strerror(errno));
3592 	}
3593 	ASSERT_EQ(EACCES, errno);
3594 
3595 	ASSERT_EQ(0, close(reg_fd));
3596 }
3597 
3598 TEST_F_FORK(layout1, proc_pipe)
3599 {
3600 	int proc_fd;
3601 	int pipe_fds[2];
3602 	char buf = '\0';
3603 	const struct rule rules[] = {
3604 		{
3605 			.path = dir_s1d2,
3606 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3607 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
3608 		},
3609 		{},
3610 	};
3611 
3612 	/* Limits read and write access to files tied to the filesystem. */
3613 	enforce_fs(_metadata, rules[0].access, rules);
3614 
3615 	/* Checks enforcement for normal files. */
3616 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
3617 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
3618 
3619 	/* Checks access to pipes through FD. */
3620 	ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC));
3621 	ASSERT_EQ(1, write(pipe_fds[1], ".", 1))
3622 	{
3623 		TH_LOG("Failed to write in pipe: %s", strerror(errno));
3624 	}
3625 	ASSERT_EQ(1, read(pipe_fds[0], &buf, 1));
3626 	ASSERT_EQ('.', buf);
3627 
3628 	/* Checks write access to pipe through /proc/self/fd . */
3629 	proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC);
3630 	ASSERT_LE(0, proc_fd);
3631 	ASSERT_EQ(1, write(proc_fd, ".", 1))
3632 	{
3633 		TH_LOG("Failed to write through /proc/self/fd/%d: %s",
3634 		       pipe_fds[1], strerror(errno));
3635 	}
3636 	ASSERT_EQ(0, close(proc_fd));
3637 
3638 	/* Checks read access to pipe through /proc/self/fd . */
3639 	proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC);
3640 	ASSERT_LE(0, proc_fd);
3641 	buf = '\0';
3642 	ASSERT_EQ(1, read(proc_fd, &buf, 1))
3643 	{
3644 		TH_LOG("Failed to read through /proc/self/fd/%d: %s",
3645 		       pipe_fds[1], strerror(errno));
3646 	}
3647 	ASSERT_EQ(0, close(proc_fd));
3648 
3649 	ASSERT_EQ(0, close(pipe_fds[0]));
3650 	ASSERT_EQ(0, close(pipe_fds[1]));
3651 }
3652 
3653 /* Invokes truncate(2) and returns its errno or 0. */
3654 static int test_truncate(const char *const path)
3655 {
3656 	if (truncate(path, 10) < 0)
3657 		return errno;
3658 	return 0;
3659 }
3660 
3661 /*
3662  * Invokes creat(2) and returns its errno or 0.
3663  * Closes the opened file descriptor on success.
3664  */
3665 static int test_creat(const char *const path)
3666 {
3667 	int fd = creat(path, 0600);
3668 
3669 	if (fd < 0)
3670 		return errno;
3671 
3672 	/*
3673 	 * Mixing error codes from close(2) and creat(2) should not lead to any
3674 	 * (access type) confusion for this test.
3675 	 */
3676 	if (close(fd) < 0)
3677 		return errno;
3678 	return 0;
3679 }
3680 
3681 /*
3682  * Exercises file truncation when it's not restricted,
3683  * as it was the case before LANDLOCK_ACCESS_FS_TRUNCATE existed.
3684  */
3685 TEST_F_FORK(layout1, truncate_unhandled)
3686 {
3687 	const char *const file_r = file1_s1d1;
3688 	const char *const file_w = file2_s1d1;
3689 	const char *const file_none = file1_s1d2;
3690 	const struct rule rules[] = {
3691 		{
3692 			.path = file_r,
3693 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
3694 		},
3695 		{
3696 			.path = file_w,
3697 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3698 		},
3699 		/* Implicitly: No rights for file_none. */
3700 		{},
3701 	};
3702 
3703 	/* Enables Landlock. */
3704 	enforce_fs(_metadata,
3705 		   LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
3706 		   rules);
3707 
3708 	/*
3709 	 * Checks read right: truncate and open with O_TRUNC work, unless the
3710 	 * file is attempted to be opened for writing.
3711 	 */
3712 	EXPECT_EQ(0, test_truncate(file_r));
3713 	EXPECT_EQ(0, test_open(file_r, O_RDONLY | O_TRUNC));
3714 	EXPECT_EQ(EACCES, test_open(file_r, O_WRONLY | O_TRUNC));
3715 	EXPECT_EQ(EACCES, test_creat(file_r));
3716 
3717 	/*
3718 	 * Checks write right: truncate and open with O_TRUNC work, unless the
3719 	 * file is attempted to be opened for reading.
3720 	 */
3721 	EXPECT_EQ(0, test_truncate(file_w));
3722 	EXPECT_EQ(EACCES, test_open(file_w, O_RDONLY | O_TRUNC));
3723 	EXPECT_EQ(0, test_open(file_w, O_WRONLY | O_TRUNC));
3724 	EXPECT_EQ(0, test_creat(file_w));
3725 
3726 	/*
3727 	 * Checks "no rights" case: truncate works but all open attempts fail,
3728 	 * including creat.
3729 	 */
3730 	EXPECT_EQ(0, test_truncate(file_none));
3731 	EXPECT_EQ(EACCES, test_open(file_none, O_RDONLY | O_TRUNC));
3732 	EXPECT_EQ(EACCES, test_open(file_none, O_WRONLY | O_TRUNC));
3733 	EXPECT_EQ(EACCES, test_creat(file_none));
3734 }
3735 
3736 TEST_F_FORK(layout1, truncate)
3737 {
3738 	const char *const file_rwt = file1_s1d1;
3739 	const char *const file_rw = file2_s1d1;
3740 	const char *const file_rt = file1_s1d2;
3741 	const char *const file_t = file2_s1d2;
3742 	const char *const file_none = file1_s1d3;
3743 	const char *const dir_t = dir_s2d1;
3744 	const char *const file_in_dir_t = file1_s2d1;
3745 	const char *const dir_w = dir_s3d1;
3746 	const char *const file_in_dir_w = file1_s3d1;
3747 	const struct rule rules[] = {
3748 		{
3749 			.path = file_rwt,
3750 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3751 				  LANDLOCK_ACCESS_FS_WRITE_FILE |
3752 				  LANDLOCK_ACCESS_FS_TRUNCATE,
3753 		},
3754 		{
3755 			.path = file_rw,
3756 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3757 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
3758 		},
3759 		{
3760 			.path = file_rt,
3761 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3762 				  LANDLOCK_ACCESS_FS_TRUNCATE,
3763 		},
3764 		{
3765 			.path = file_t,
3766 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3767 		},
3768 		/* Implicitly: No access rights for file_none. */
3769 		{
3770 			.path = dir_t,
3771 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3772 		},
3773 		{
3774 			.path = dir_w,
3775 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3776 		},
3777 		{},
3778 	};
3779 
3780 	/* Enables Landlock. */
3781 	enforce_fs(_metadata,
3782 		   LANDLOCK_ACCESS_FS_READ_FILE |
3783 			   LANDLOCK_ACCESS_FS_WRITE_FILE |
3784 			   LANDLOCK_ACCESS_FS_TRUNCATE,
3785 		   rules);
3786 
3787 	/* Checks read, write and truncate rights: truncation works. */
3788 	EXPECT_EQ(0, test_truncate(file_rwt));
3789 	EXPECT_EQ(0, test_open(file_rwt, O_RDONLY | O_TRUNC));
3790 	EXPECT_EQ(0, test_open(file_rwt, O_WRONLY | O_TRUNC));
3791 
3792 	/* Checks read and write rights: no truncate variant works. */
3793 	EXPECT_EQ(EACCES, test_truncate(file_rw));
3794 	EXPECT_EQ(EACCES, test_open(file_rw, O_RDONLY | O_TRUNC));
3795 	EXPECT_EQ(EACCES, test_open(file_rw, O_WRONLY | O_TRUNC));
3796 
3797 	/*
3798 	 * Checks read and truncate rights: truncation works.
3799 	 *
3800 	 * Note: Files can get truncated using open() even with O_RDONLY.
3801 	 */
3802 	EXPECT_EQ(0, test_truncate(file_rt));
3803 	EXPECT_EQ(0, test_open(file_rt, O_RDONLY | O_TRUNC));
3804 	EXPECT_EQ(EACCES, test_open(file_rt, O_WRONLY | O_TRUNC));
3805 
3806 	/* Checks truncate right: truncate works, but can't open file. */
3807 	EXPECT_EQ(0, test_truncate(file_t));
3808 	EXPECT_EQ(EACCES, test_open(file_t, O_RDONLY | O_TRUNC));
3809 	EXPECT_EQ(EACCES, test_open(file_t, O_WRONLY | O_TRUNC));
3810 
3811 	/* Checks "no rights" case: No form of truncation works. */
3812 	EXPECT_EQ(EACCES, test_truncate(file_none));
3813 	EXPECT_EQ(EACCES, test_open(file_none, O_RDONLY | O_TRUNC));
3814 	EXPECT_EQ(EACCES, test_open(file_none, O_WRONLY | O_TRUNC));
3815 
3816 	/*
3817 	 * Checks truncate right on directory: truncate works on contained
3818 	 * files.
3819 	 */
3820 	EXPECT_EQ(0, test_truncate(file_in_dir_t));
3821 	EXPECT_EQ(EACCES, test_open(file_in_dir_t, O_RDONLY | O_TRUNC));
3822 	EXPECT_EQ(EACCES, test_open(file_in_dir_t, O_WRONLY | O_TRUNC));
3823 
3824 	/*
3825 	 * Checks creat in dir_w: This requires the truncate right when
3826 	 * overwriting an existing file, but does not require it when the file
3827 	 * is new.
3828 	 */
3829 	EXPECT_EQ(EACCES, test_creat(file_in_dir_w));
3830 
3831 	ASSERT_EQ(0, unlink(file_in_dir_w));
3832 	EXPECT_EQ(0, test_creat(file_in_dir_w));
3833 }
3834 
3835 /* Invokes ftruncate(2) and returns its errno or 0. */
3836 static int test_ftruncate(int fd)
3837 {
3838 	if (ftruncate(fd, 10) < 0)
3839 		return errno;
3840 	return 0;
3841 }
3842 
3843 TEST_F_FORK(layout1, ftruncate)
3844 {
3845 	/*
3846 	 * This test opens a new file descriptor at different stages of
3847 	 * Landlock restriction:
3848 	 *
3849 	 * without restriction:                    ftruncate works
3850 	 * something else but truncate restricted: ftruncate works
3851 	 * truncate restricted and permitted:      ftruncate works
3852 	 * truncate restricted and not permitted:  ftruncate fails
3853 	 *
3854 	 * Whether this works or not is expected to depend on the time when the
3855 	 * FD was opened, not to depend on the time when ftruncate() was
3856 	 * called.
3857 	 */
3858 	const char *const path = file1_s1d1;
3859 	const __u64 handled1 = LANDLOCK_ACCESS_FS_READ_FILE |
3860 			       LANDLOCK_ACCESS_FS_WRITE_FILE;
3861 	const struct rule layer1[] = {
3862 		{
3863 			.path = path,
3864 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3865 		},
3866 		{},
3867 	};
3868 	const __u64 handled2 = LANDLOCK_ACCESS_FS_TRUNCATE;
3869 	const struct rule layer2[] = {
3870 		{
3871 			.path = path,
3872 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3873 		},
3874 		{},
3875 	};
3876 	const __u64 handled3 = LANDLOCK_ACCESS_FS_TRUNCATE |
3877 			       LANDLOCK_ACCESS_FS_WRITE_FILE;
3878 	const struct rule layer3[] = {
3879 		{
3880 			.path = path,
3881 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3882 		},
3883 		{},
3884 	};
3885 	int fd_layer0, fd_layer1, fd_layer2, fd_layer3;
3886 
3887 	fd_layer0 = open(path, O_WRONLY);
3888 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3889 
3890 	enforce_fs(_metadata, handled1, layer1);
3891 
3892 	fd_layer1 = open(path, O_WRONLY);
3893 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3894 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3895 
3896 	enforce_fs(_metadata, handled2, layer2);
3897 
3898 	fd_layer2 = open(path, O_WRONLY);
3899 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3900 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3901 	EXPECT_EQ(0, test_ftruncate(fd_layer2));
3902 
3903 	enforce_fs(_metadata, handled3, layer3);
3904 
3905 	fd_layer3 = open(path, O_WRONLY);
3906 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3907 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3908 	EXPECT_EQ(0, test_ftruncate(fd_layer2));
3909 	EXPECT_EQ(EACCES, test_ftruncate(fd_layer3));
3910 
3911 	ASSERT_EQ(0, close(fd_layer0));
3912 	ASSERT_EQ(0, close(fd_layer1));
3913 	ASSERT_EQ(0, close(fd_layer2));
3914 	ASSERT_EQ(0, close(fd_layer3));
3915 }
3916 
3917 /* clang-format off */
3918 FIXTURE(ftruncate) {};
3919 /* clang-format on */
3920 
3921 FIXTURE_SETUP(ftruncate)
3922 {
3923 	prepare_layout(_metadata);
3924 	create_file(_metadata, file1_s1d1);
3925 }
3926 
3927 FIXTURE_TEARDOWN_PARENT(ftruncate)
3928 {
3929 	EXPECT_EQ(0, remove_path(file1_s1d1));
3930 	cleanup_layout(_metadata);
3931 }
3932 
3933 FIXTURE_VARIANT(ftruncate)
3934 {
3935 	const __u64 handled;
3936 	const __u64 allowed;
3937 	const int expected_open_result;
3938 	const int expected_ftruncate_result;
3939 };
3940 
3941 /* clang-format off */
3942 FIXTURE_VARIANT_ADD(ftruncate, w_w) {
3943 	/* clang-format on */
3944 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE,
3945 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
3946 	.expected_open_result = 0,
3947 	.expected_ftruncate_result = 0,
3948 };
3949 
3950 /* clang-format off */
3951 FIXTURE_VARIANT_ADD(ftruncate, t_t) {
3952 	/* clang-format on */
3953 	.handled = LANDLOCK_ACCESS_FS_TRUNCATE,
3954 	.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
3955 	.expected_open_result = 0,
3956 	.expected_ftruncate_result = 0,
3957 };
3958 
3959 /* clang-format off */
3960 FIXTURE_VARIANT_ADD(ftruncate, wt_w) {
3961 	/* clang-format on */
3962 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3963 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
3964 	.expected_open_result = 0,
3965 	.expected_ftruncate_result = EACCES,
3966 };
3967 
3968 /* clang-format off */
3969 FIXTURE_VARIANT_ADD(ftruncate, wt_wt) {
3970 	/* clang-format on */
3971 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3972 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3973 	.expected_open_result = 0,
3974 	.expected_ftruncate_result = 0,
3975 };
3976 
3977 /* clang-format off */
3978 FIXTURE_VARIANT_ADD(ftruncate, wt_t) {
3979 	/* clang-format on */
3980 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3981 	.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
3982 	.expected_open_result = EACCES,
3983 };
3984 
3985 TEST_F_FORK(ftruncate, open_and_ftruncate)
3986 {
3987 	const char *const path = file1_s1d1;
3988 	const struct rule rules[] = {
3989 		{
3990 			.path = path,
3991 			.access = variant->allowed,
3992 		},
3993 		{},
3994 	};
3995 	int fd;
3996 
3997 	/* Enables Landlock. */
3998 	enforce_fs(_metadata, variant->handled, rules);
3999 
4000 	fd = open(path, O_WRONLY);
4001 	EXPECT_EQ(variant->expected_open_result, (fd < 0 ? errno : 0));
4002 	if (fd >= 0) {
4003 		EXPECT_EQ(variant->expected_ftruncate_result,
4004 			  test_ftruncate(fd));
4005 		ASSERT_EQ(0, close(fd));
4006 	}
4007 }
4008 
4009 TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes)
4010 {
4011 	int child, fd, status;
4012 	int socket_fds[2];
4013 
4014 	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0,
4015 				socket_fds));
4016 
4017 	child = fork();
4018 	ASSERT_LE(0, child);
4019 	if (child == 0) {
4020 		/*
4021 		 * Enables Landlock in the child process, open a file descriptor
4022 		 * where truncation is forbidden and send it to the
4023 		 * non-landlocked parent process.
4024 		 */
4025 		const char *const path = file1_s1d1;
4026 		const struct rule rules[] = {
4027 			{
4028 				.path = path,
4029 				.access = variant->allowed,
4030 			},
4031 			{},
4032 		};
4033 		int fd;
4034 
4035 		enforce_fs(_metadata, variant->handled, rules);
4036 
4037 		fd = open(path, O_WRONLY);
4038 		ASSERT_EQ(variant->expected_open_result, (fd < 0 ? errno : 0));
4039 
4040 		if (fd >= 0) {
4041 			ASSERT_EQ(0, send_fd(socket_fds[0], fd));
4042 			ASSERT_EQ(0, close(fd));
4043 		}
4044 
4045 		ASSERT_EQ(0, close(socket_fds[0]));
4046 
4047 		_exit(_metadata->exit_code);
4048 		return;
4049 	}
4050 
4051 	if (variant->expected_open_result == 0) {
4052 		fd = recv_fd(socket_fds[1]);
4053 		ASSERT_LE(0, fd);
4054 
4055 		EXPECT_EQ(variant->expected_ftruncate_result,
4056 			  test_ftruncate(fd));
4057 		ASSERT_EQ(0, close(fd));
4058 	}
4059 
4060 	ASSERT_EQ(child, waitpid(child, &status, 0));
4061 	ASSERT_EQ(1, WIFEXITED(status));
4062 	ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
4063 
4064 	ASSERT_EQ(0, close(socket_fds[0]));
4065 	ASSERT_EQ(0, close(socket_fds[1]));
4066 }
4067 
4068 /* Invokes the FS_IOC_GETFLAGS IOCTL and returns its errno or 0. */
4069 static int test_fs_ioc_getflags_ioctl(int fd)
4070 {
4071 	uint32_t flags;
4072 
4073 	if (ioctl(fd, FS_IOC_GETFLAGS, &flags) < 0)
4074 		return errno;
4075 	return 0;
4076 }
4077 
4078 TEST(memfd_ftruncate_and_ioctl)
4079 {
4080 	int fd, i;
4081 
4082 	/*
4083 	 * We exercise the same test both with and without Landlock enabled, to
4084 	 * ensure that it behaves the same in both cases.
4085 	 */
4086 	for (i = 0; i < 2; i++) {
4087 		/* Creates a new memfd. */
4088 		fd = memfd_create("name", MFD_CLOEXEC);
4089 		ASSERT_LE(0, fd);
4090 
4091 		/*
4092 		 * Checks that operations associated with the opened file
4093 		 * (ftruncate, ioctl) are permitted on file descriptors that are
4094 		 * created in ways other than open(2).
4095 		 */
4096 		EXPECT_EQ(0, test_ftruncate(fd));
4097 		EXPECT_EQ(0, test_fs_ioc_getflags_ioctl(fd));
4098 
4099 		ASSERT_EQ(0, close(fd));
4100 
4101 		/* Enables Landlock. */
4102 		enforce_fs(_metadata, ACCESS_ALL, NULL);
4103 	}
4104 }
4105 
4106 static int test_fionread_ioctl(int fd)
4107 {
4108 	size_t sz = 0;
4109 
4110 	if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES)
4111 		return errno;
4112 	return 0;
4113 }
4114 
4115 TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl)
4116 {
4117 	int fd;
4118 
4119 	/*
4120 	 * Checks that for files opened with O_PATH, both ioctl(2) and
4121 	 * ftruncate(2) yield EBADF, as it is documented in open(2) for the
4122 	 * O_PATH flag.
4123 	 */
4124 	fd = open(dir_s1d1, O_PATH | O_CLOEXEC);
4125 	ASSERT_LE(0, fd);
4126 
4127 	EXPECT_EQ(EBADF, test_ftruncate(fd));
4128 	EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd));
4129 
4130 	ASSERT_EQ(0, close(fd));
4131 
4132 	/* Enables Landlock. */
4133 	enforce_fs(_metadata, ACCESS_ALL, NULL);
4134 
4135 	/*
4136 	 * Checks that after enabling Landlock,
4137 	 * - the file can still be opened with O_PATH
4138 	 * - both ioctl and truncate still yield EBADF (not EACCES).
4139 	 */
4140 	fd = open(dir_s1d1, O_PATH | O_CLOEXEC);
4141 	ASSERT_LE(0, fd);
4142 
4143 	EXPECT_EQ(EBADF, test_ftruncate(fd));
4144 	EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd));
4145 
4146 	ASSERT_EQ(0, close(fd));
4147 }
4148 
4149 /*
4150  * ioctl_error - generically call the given ioctl with a pointer to a
4151  * sufficiently large zeroed-out memory region.
4152  *
4153  * Returns the IOCTLs error, or 0.
4154  */
4155 static int ioctl_error(struct __test_metadata *const _metadata, int fd,
4156 		       unsigned int cmd)
4157 {
4158 	char buf[128]; /* sufficiently large */
4159 	int res, stdinbak_fd, err;
4160 
4161 	/*
4162 	 * Depending on the IOCTL command, parts of the zeroed-out buffer might
4163 	 * be interpreted as file descriptor numbers.  We do not want to
4164 	 * accidentally operate on file descriptor 0 (stdin), so we temporarily
4165 	 * move stdin to a different FD and close FD 0 for the IOCTL call.
4166 	 */
4167 	stdinbak_fd = dup(0);
4168 	ASSERT_LT(0, stdinbak_fd);
4169 	ASSERT_EQ(0, close(0));
4170 
4171 	/* Invokes the IOCTL with a zeroed-out buffer. */
4172 	bzero(&buf, sizeof(buf));
4173 	res = ioctl(fd, cmd, &buf);
4174 	err = errno;
4175 
4176 	/* Restores the old FD 0 and closes the backup FD. */
4177 	ASSERT_EQ(0, dup2(stdinbak_fd, 0));
4178 	ASSERT_EQ(0, close(stdinbak_fd));
4179 
4180 	if (res < 0)
4181 		return err;
4182 
4183 	return 0;
4184 }
4185 
4186 /* Define some linux/falloc.h IOCTL commands which are not available in uapi headers. */
4187 struct space_resv {
4188 	__s16 l_type;
4189 	__s16 l_whence;
4190 	__s64 l_start;
4191 	__s64 l_len; /* len == 0 means until end of file */
4192 	__s32 l_sysid;
4193 	__u32 l_pid;
4194 	__s32 l_pad[4]; /* reserved area */
4195 };
4196 
4197 #define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
4198 #define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv)
4199 #define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
4200 #define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv)
4201 #define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv)
4202 
4203 /*
4204  * Tests a series of blanket-permitted and denied IOCTLs.
4205  */
4206 TEST_F_FORK(layout1, blanket_permitted_ioctls)
4207 {
4208 	int fd;
4209 
4210 	/* Enables Landlock. */
4211 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4212 
4213 	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
4214 	ASSERT_LE(0, fd);
4215 
4216 	/*
4217 	 * Checks permitted commands.
4218 	 * These ones may return errors, but should not be blocked by Landlock.
4219 	 */
4220 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOCLEX));
4221 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONCLEX));
4222 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONBIO));
4223 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOASYNC));
4224 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOQSIZE));
4225 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIFREEZE));
4226 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FITHAW));
4227 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_FIEMAP));
4228 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIGETBSZ));
4229 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONE));
4230 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONERANGE));
4231 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIDEDUPERANGE));
4232 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSUUID));
4233 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSSYSFSPATH));
4234 
4235 	/*
4236 	 * Checks blocked commands.
4237 	 * A call to a blocked IOCTL command always returns EACCES.
4238 	 */
4239 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIONREAD));
4240 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFLAGS));
4241 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_SETFLAGS));
4242 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSGETXATTR));
4243 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSSETXATTR));
4244 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIBMAP));
4245 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP));
4246 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP64));
4247 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP));
4248 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP64));
4249 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_ZERO_RANGE));
4250 
4251 	/* Default case is also blocked. */
4252 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, 0xc00ffeee));
4253 
4254 	ASSERT_EQ(0, close(fd));
4255 }
4256 
4257 /*
4258  * Named pipes are not governed by the LANDLOCK_ACCESS_FS_IOCTL_DEV right,
4259  * because they are not character or block devices.
4260  */
4261 TEST_F_FORK(layout1, named_pipe_ioctl)
4262 {
4263 	pid_t child_pid;
4264 	int fd;
4265 	const char *const path = file1_s1d1;
4266 
4267 	ASSERT_EQ(0, unlink(path));
4268 	ASSERT_EQ(0, mkfifo(path, 0600));
4269 
4270 	/* Enables Landlock. */
4271 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4272 
4273 	/* The child process opens the pipe for writing. */
4274 	child_pid = fork();
4275 	ASSERT_NE(-1, child_pid);
4276 	if (child_pid == 0) {
4277 		fd = open(path, O_WRONLY);
4278 		close(fd);
4279 		exit(0);
4280 	}
4281 
4282 	fd = open(path, O_RDONLY);
4283 	ASSERT_LE(0, fd);
4284 
4285 	/* FIONREAD is implemented by pipefifo_fops. */
4286 	EXPECT_EQ(0, test_fionread_ioctl(fd));
4287 
4288 	ASSERT_EQ(0, close(fd));
4289 	ASSERT_EQ(0, unlink(path));
4290 
4291 	ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0));
4292 }
4293 
4294 /*
4295  * set_up_named_unix_server - Create a pathname unix socket
4296  *
4297  * If the socket type is not SOCK_DGRAM, also invoke listen(2).
4298  *
4299  * Return: The listening FD - it is the caller responsibility to close it.
4300  */
4301 static int set_up_named_unix_server(struct __test_metadata *const _metadata,
4302 				    int type, const char *const path)
4303 {
4304 	int fd;
4305 	struct sockaddr_un addr = {
4306 		.sun_family = AF_UNIX,
4307 	};
4308 
4309 	fd = socket(AF_UNIX, type, 0);
4310 	ASSERT_LE(0, fd);
4311 
4312 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4313 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4314 
4315 	ASSERT_EQ(0, bind(fd, (struct sockaddr *)&addr, sizeof(addr)));
4316 
4317 	if (type != SOCK_DGRAM)
4318 		ASSERT_EQ(0, listen(fd, 10 /* qlen */));
4319 	return fd;
4320 }
4321 
4322 /*
4323  * test_connect_named_unix - connect to the given named UNIX socket
4324  *
4325  * Return: The errno from connect(), or 0
4326  */
4327 static int test_connect_named_unix(struct __test_metadata *const _metadata,
4328 				   int fd, const char *const path)
4329 {
4330 	struct sockaddr_un addr = {
4331 		.sun_family = AF_UNIX,
4332 	};
4333 
4334 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4335 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4336 
4337 	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
4338 		return errno;
4339 	return 0;
4340 }
4341 
4342 /* For named UNIX domain sockets, no IOCTL restrictions apply. */
4343 TEST_F_FORK(layout1, named_unix_domain_socket_ioctl)
4344 {
4345 	const char *const path = file1_s1d1;
4346 	int srv_fd, cli_fd;
4347 
4348 	/* Sets up a server */
4349 	ASSERT_EQ(0, unlink(path));
4350 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, path);
4351 
4352 	/* Enables Landlock. */
4353 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4354 
4355 	/* Sets up a client connection to it */
4356 	cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
4357 	ASSERT_LE(0, cli_fd);
4358 
4359 	ASSERT_EQ(0, test_connect_named_unix(_metadata, cli_fd, path));
4360 
4361 	/* FIONREAD and other IOCTLs should not be forbidden. */
4362 	EXPECT_EQ(0, test_fionread_ioctl(cli_fd));
4363 
4364 	EXPECT_EQ(0, close(cli_fd));
4365 	EXPECT_EQ(0, close(srv_fd));
4366 }
4367 
4368 /* clang-format off */
4369 FIXTURE(ioctl) {};
4370 
4371 FIXTURE_SETUP(ioctl) {};
4372 
4373 FIXTURE_TEARDOWN(ioctl) {};
4374 /* clang-format on */
4375 
4376 FIXTURE_VARIANT(ioctl)
4377 {
4378 	const __u64 handled;
4379 	const __u64 allowed;
4380 	const mode_t open_mode;
4381 	/*
4382 	 * FIONREAD is used as a characteristic device-specific IOCTL command.
4383 	 * It is implemented in fs/ioctl.c for regular files,
4384 	 * but we do not blanket-permit it for devices.
4385 	 */
4386 	const int expected_fionread_result;
4387 };
4388 
4389 /* clang-format off */
4390 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_none) {
4391 	/* clang-format on */
4392 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4393 	.allowed = 0,
4394 	.open_mode = O_RDWR,
4395 	.expected_fionread_result = EACCES,
4396 };
4397 
4398 /* clang-format off */
4399 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_i) {
4400 	/* clang-format on */
4401 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4402 	.allowed = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4403 	.open_mode = O_RDWR,
4404 	.expected_fionread_result = 0,
4405 };
4406 
4407 /* clang-format off */
4408 FIXTURE_VARIANT_ADD(ioctl, unhandled) {
4409 	/* clang-format on */
4410 	.handled = LANDLOCK_ACCESS_FS_EXECUTE,
4411 	.allowed = LANDLOCK_ACCESS_FS_EXECUTE,
4412 	.open_mode = O_RDWR,
4413 	.expected_fionread_result = 0,
4414 };
4415 
4416 TEST_F_FORK(ioctl, handle_dir_access_file)
4417 {
4418 	const int flag = 0;
4419 	const struct rule rules[] = {
4420 		{
4421 			.path = "/dev",
4422 			.access = variant->allowed,
4423 		},
4424 		{},
4425 	};
4426 	int fd;
4427 
4428 	/* Enables Landlock. */
4429 	enforce_fs(_metadata, variant->handled, rules);
4430 
4431 	fd = open("/dev/zero", variant->open_mode);
4432 	ASSERT_LE(0, fd);
4433 
4434 	/* Checks that IOCTL commands return the expected errors. */
4435 	EXPECT_EQ(variant->expected_fionread_result, test_fionread_ioctl(fd));
4436 
4437 	/* Checks that unrestrictable commands are unrestricted. */
4438 	EXPECT_EQ(0, ioctl(fd, FIOCLEX));
4439 	EXPECT_EQ(0, ioctl(fd, FIONCLEX));
4440 	EXPECT_EQ(0, ioctl(fd, FIONBIO, &flag));
4441 	EXPECT_EQ(0, ioctl(fd, FIOASYNC, &flag));
4442 	EXPECT_EQ(0, ioctl(fd, FIGETBSZ, &flag));
4443 
4444 	ASSERT_EQ(0, close(fd));
4445 }
4446 
4447 TEST_F_FORK(ioctl, handle_dir_access_dir)
4448 {
4449 	const int flag = 0;
4450 	const struct rule rules[] = {
4451 		{
4452 			.path = "/dev",
4453 			.access = variant->allowed,
4454 		},
4455 		{},
4456 	};
4457 	int dir_fd;
4458 
4459 	/* Enables Landlock. */
4460 	enforce_fs(_metadata, variant->handled, rules);
4461 
4462 	/*
4463 	 * Ignore variant->open_mode for this test, as we intend to open a
4464 	 * directory.  If the directory can not be opened, the variant is
4465 	 * infeasible to test with an opened directory.
4466 	 */
4467 	dir_fd = open("/dev", O_RDONLY);
4468 	if (dir_fd < 0)
4469 		return;
4470 
4471 	/*
4472 	 * Checks that IOCTL commands return the expected errors.
4473 	 * We do not use the expected values from the fixture here.
4474 	 *
4475 	 * When using IOCTL on a directory, no Landlock restrictions apply.
4476 	 */
4477 	EXPECT_EQ(0, test_fionread_ioctl(dir_fd));
4478 
4479 	/* Checks that unrestrictable commands are unrestricted. */
4480 	EXPECT_EQ(0, ioctl(dir_fd, FIOCLEX));
4481 	EXPECT_EQ(0, ioctl(dir_fd, FIONCLEX));
4482 	EXPECT_EQ(0, ioctl(dir_fd, FIONBIO, &flag));
4483 	EXPECT_EQ(0, ioctl(dir_fd, FIOASYNC, &flag));
4484 	EXPECT_EQ(0, ioctl(dir_fd, FIGETBSZ, &flag));
4485 
4486 	ASSERT_EQ(0, close(dir_fd));
4487 }
4488 
4489 TEST_F_FORK(ioctl, handle_file_access_file)
4490 {
4491 	const int flag = 0;
4492 	const struct rule rules[] = {
4493 		{
4494 			.path = "/dev/zero",
4495 			.access = variant->allowed,
4496 		},
4497 		{},
4498 	};
4499 	int fd;
4500 
4501 	/* Enables Landlock. */
4502 	enforce_fs(_metadata, variant->handled, rules);
4503 
4504 	fd = open("/dev/zero", variant->open_mode);
4505 	ASSERT_LE(0, fd)
4506 	{
4507 		TH_LOG("Failed to open /dev/zero: %s", strerror(errno));
4508 	}
4509 
4510 	/* Checks that IOCTL commands return the expected errors. */
4511 	EXPECT_EQ(variant->expected_fionread_result, test_fionread_ioctl(fd));
4512 
4513 	/* Checks that unrestrictable commands are unrestricted. */
4514 	EXPECT_EQ(0, ioctl(fd, FIOCLEX));
4515 	EXPECT_EQ(0, ioctl(fd, FIONCLEX));
4516 	EXPECT_EQ(0, ioctl(fd, FIONBIO, &flag));
4517 	EXPECT_EQ(0, ioctl(fd, FIOASYNC, &flag));
4518 	EXPECT_EQ(0, ioctl(fd, FIGETBSZ, &flag));
4519 
4520 	ASSERT_EQ(0, close(fd));
4521 }
4522 
4523 /*
4524  * test_sendto_named_unix - sendto to the given named UNIX socket
4525  *
4526  * sendto() is equivalent to sendmsg() in this respect.
4527  *
4528  * Return: The errno from sendto(), or 0
4529  */
4530 static int test_sendto_named_unix(struct __test_metadata *const _metadata,
4531 				  int fd, const char *const path)
4532 {
4533 	static const char buf[] = "dummy";
4534 	struct sockaddr_un addr = {
4535 		.sun_family = AF_UNIX,
4536 	};
4537 
4538 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4539 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4540 
4541 	if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
4542 		   sizeof(addr)) == -1)
4543 		return errno;
4544 	return 0;
4545 }
4546 
4547 /* clang-format off */
4548 FIXTURE(scoped_domains) {};
4549 /* clang-format on */
4550 
4551 #include "scoped_base_variants.h"
4552 
4553 FIXTURE_SETUP(scoped_domains)
4554 {
4555 	drop_caps(_metadata);
4556 };
4557 
4558 FIXTURE_TEARDOWN(scoped_domains)
4559 {
4560 }
4561 
4562 /*
4563  * Flags for test_connect_to_parent and test_connect_to_child:
4564  *
4565  * USE_SENDTO: Use sendto() instead of connect() (for SOCK_DGRAM only)
4566  * ENFORCE_ALL: Enforce a Landlock domain even when the variant says
4567  *   we shouldn't.  We enforce a domain where the path is allow-listed,
4568  *   and expect the behavior to be the same as if none was used.
4569  */
4570 #define USE_SENDTO (1 << 0)
4571 #define ENFORCE_ALL (1 << 1)
4572 
4573 static void test_connect_to_parent(struct __test_metadata *const _metadata,
4574 				   const FIXTURE_VARIANT(scoped_domains) *
4575 					   variant,
4576 				   int sock_type, int flags)
4577 {
4578 	const char *const path = "sock";
4579 	const struct rule rules[] = {
4580 		{
4581 			.path = ".",
4582 			.access = LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4583 		},
4584 		{},
4585 	};
4586 	int cli_fd, srv_fd, res, status;
4587 	pid_t child_pid;
4588 	int readiness_pipe[2];
4589 	char buf[1];
4590 
4591 	if (variant->domain_both)
4592 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4593 	else if (flags & ENFORCE_ALL)
4594 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4595 
4596 	unlink(path);
4597 	ASSERT_EQ(0, pipe2(readiness_pipe, O_CLOEXEC));
4598 
4599 	child_pid = fork();
4600 	ASSERT_LE(0, child_pid);
4601 
4602 	if (child_pid == 0) {
4603 		if (variant->domain_child)
4604 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4605 				   NULL);
4606 		else if (flags & ENFORCE_ALL)
4607 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4608 				   rules);
4609 
4610 		/* Wait for server to be available. */
4611 		EXPECT_EQ(0, close(readiness_pipe[1]));
4612 		EXPECT_EQ(1, read(readiness_pipe[0], &buf, 1));
4613 		EXPECT_EQ(0, close(readiness_pipe[0]));
4614 
4615 		/* Talk to server. */
4616 		cli_fd = socket(AF_UNIX, sock_type, 0);
4617 		ASSERT_LE(0, cli_fd);
4618 
4619 		if (flags & USE_SENDTO)
4620 			res = test_sendto_named_unix(_metadata, cli_fd, path);
4621 		else
4622 			res = test_connect_named_unix(_metadata, cli_fd, path);
4623 
4624 		EXPECT_EQ(variant->domain_child ? EACCES : 0, res);
4625 
4626 		/* Clean up. */
4627 		EXPECT_EQ(0, close(cli_fd));
4628 
4629 		_exit(_metadata->exit_code);
4630 		return;
4631 	}
4632 
4633 	if (variant->domain_parent)
4634 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4635 	else if (flags & ENFORCE_ALL)
4636 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4637 
4638 	srv_fd = set_up_named_unix_server(_metadata, sock_type, path);
4639 
4640 	/* Tell the child that it can connect. */
4641 	EXPECT_EQ(0, close(readiness_pipe[0]));
4642 	EXPECT_EQ(sizeof(buf), write(readiness_pipe[1], buf, sizeof(buf)));
4643 	EXPECT_EQ(0, close(readiness_pipe[1]));
4644 
4645 	/* Wait for child. */
4646 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4647 	EXPECT_EQ(1, WIFEXITED(status));
4648 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
4649 
4650 	/* Clean up. */
4651 	EXPECT_EQ(0, close(srv_fd));
4652 	EXPECT_EQ(0, unlink(path));
4653 }
4654 
4655 static void test_connect_to_child(struct __test_metadata *const _metadata,
4656 				  const FIXTURE_VARIANT(scoped_domains) *
4657 					  variant,
4658 				  int sock_type, int flags)
4659 {
4660 	const char *const path = "sock";
4661 	const struct rule rules[] = {
4662 		{
4663 			.path = ".",
4664 			.access = LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4665 		},
4666 		{},
4667 	};
4668 	int readiness_pipe[2];
4669 	int shutdown_pipe[2];
4670 	int cli_fd, srv_fd, res, status;
4671 	pid_t child_pid;
4672 	char buf[1];
4673 
4674 	if (variant->domain_both)
4675 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4676 	else if (flags & ENFORCE_ALL)
4677 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4678 
4679 	unlink(path);
4680 	ASSERT_EQ(0, pipe2(readiness_pipe, O_CLOEXEC));
4681 	ASSERT_EQ(0, pipe2(shutdown_pipe, O_CLOEXEC));
4682 
4683 	child_pid = fork();
4684 	ASSERT_LE(0, child_pid);
4685 
4686 	if (child_pid == 0) {
4687 		if (variant->domain_child)
4688 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4689 				   NULL);
4690 		else if (flags & ENFORCE_ALL)
4691 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4692 				   rules);
4693 
4694 		srv_fd = set_up_named_unix_server(_metadata, sock_type, path);
4695 
4696 		/* Tell the parent that it can connect. */
4697 		EXPECT_EQ(0, close(readiness_pipe[0]));
4698 		EXPECT_EQ(sizeof(buf),
4699 			  write(readiness_pipe[1], buf, sizeof(buf)));
4700 		EXPECT_EQ(0, close(readiness_pipe[1]));
4701 
4702 		/* Wait until it is time to shut down. */
4703 		EXPECT_EQ(0, close(shutdown_pipe[1]));
4704 		EXPECT_EQ(1, read(shutdown_pipe[0], &buf, 1));
4705 		EXPECT_EQ(0, close(shutdown_pipe[0]));
4706 
4707 		/* Cleanup */
4708 		EXPECT_EQ(0, close(srv_fd));
4709 		EXPECT_EQ(0, unlink(path));
4710 
4711 		_exit(_metadata->exit_code);
4712 		return;
4713 	}
4714 
4715 	if (variant->domain_parent)
4716 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4717 	else if (flags & ENFORCE_ALL)
4718 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4719 
4720 	/* Wait for server to be available. */
4721 	EXPECT_EQ(0, close(readiness_pipe[1]));
4722 	EXPECT_EQ(1, read(readiness_pipe[0], &buf, 1));
4723 	EXPECT_EQ(0, close(readiness_pipe[0]));
4724 
4725 	/* Talk to server. */
4726 	cli_fd = socket(AF_UNIX, sock_type, 0);
4727 	ASSERT_LE(0, cli_fd);
4728 
4729 	if (flags & USE_SENDTO)
4730 		res = test_sendto_named_unix(_metadata, cli_fd, path);
4731 	else
4732 		res = test_connect_named_unix(_metadata, cli_fd, path);
4733 
4734 	EXPECT_EQ(variant->domain_parent ? EACCES : 0, res);
4735 
4736 	/* Clean up. */
4737 	EXPECT_EQ(0, close(cli_fd));
4738 
4739 	/* Tell the server to shut down. */
4740 	EXPECT_EQ(0, close(shutdown_pipe[0]));
4741 	EXPECT_EQ(sizeof(buf), write(shutdown_pipe[1], buf, sizeof(buf)));
4742 	EXPECT_EQ(0, close(shutdown_pipe[1]));
4743 
4744 	/* Wait for child. */
4745 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4746 	EXPECT_EQ(1, WIFEXITED(status));
4747 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
4748 }
4749 
4750 TEST_F(scoped_domains, unix_stream_connect_to_parent)
4751 {
4752 	test_connect_to_parent(_metadata, variant, SOCK_STREAM, 0);
4753 }
4754 
4755 TEST_F(scoped_domains, unix_dgram_connect_to_parent)
4756 {
4757 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, 0);
4758 }
4759 
4760 TEST_F(scoped_domains, unix_dgram_sendmsg_to_parent)
4761 {
4762 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, USE_SENDTO);
4763 }
4764 
4765 TEST_F(scoped_domains, unix_seqpacket_connect_to_parent)
4766 {
4767 	test_connect_to_parent(_metadata, variant, SOCK_SEQPACKET, 0);
4768 }
4769 
4770 TEST_F(scoped_domains, unix_stream_connect_to_parent_full)
4771 {
4772 	test_connect_to_parent(_metadata, variant, SOCK_STREAM, ENFORCE_ALL);
4773 }
4774 
4775 TEST_F(scoped_domains, unix_dgram_connect_to_parent_full)
4776 {
4777 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, ENFORCE_ALL);
4778 }
4779 
4780 TEST_F(scoped_domains, unix_dgram_sendmsg_to_parent_full)
4781 {
4782 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM,
4783 			       USE_SENDTO | ENFORCE_ALL);
4784 }
4785 
4786 TEST_F(scoped_domains, unix_seqpacket_connect_to_parent_full)
4787 {
4788 	test_connect_to_parent(_metadata, variant, SOCK_SEQPACKET, ENFORCE_ALL);
4789 }
4790 
4791 TEST_F(scoped_domains, unix_stream_connect_to_child)
4792 {
4793 	test_connect_to_child(_metadata, variant, SOCK_STREAM, 0);
4794 }
4795 
4796 TEST_F(scoped_domains, unix_dgram_connect_to_child)
4797 {
4798 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, 0);
4799 }
4800 
4801 TEST_F(scoped_domains, unix_dgram_sendmsg_to_child)
4802 {
4803 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, USE_SENDTO);
4804 }
4805 
4806 TEST_F(scoped_domains, unix_seqpacket_connect_to_child)
4807 {
4808 	test_connect_to_child(_metadata, variant, SOCK_SEQPACKET, 0);
4809 }
4810 
4811 TEST_F(scoped_domains, unix_stream_connect_to_child_full)
4812 {
4813 	test_connect_to_child(_metadata, variant, SOCK_STREAM, ENFORCE_ALL);
4814 }
4815 
4816 TEST_F(scoped_domains, unix_dgram_connect_to_child_full)
4817 {
4818 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, ENFORCE_ALL);
4819 }
4820 
4821 TEST_F(scoped_domains, unix_dgram_sendmsg_to_child_full)
4822 {
4823 	test_connect_to_child(_metadata, variant, SOCK_DGRAM,
4824 			      USE_SENDTO | ENFORCE_ALL);
4825 }
4826 
4827 TEST_F(scoped_domains, unix_seqpacket_connect_to_child_full)
4828 {
4829 	test_connect_to_child(_metadata, variant, SOCK_SEQPACKET, ENFORCE_ALL);
4830 }
4831 
4832 #undef USE_SENDTO
4833 #undef ENFORCE_ALL
4834 
4835 static void read_core_pattern(struct __test_metadata *const _metadata,
4836 			      char *buf, size_t buf_size)
4837 {
4838 	int fd;
4839 	ssize_t ret;
4840 
4841 	fd = open("/proc/sys/kernel/core_pattern", O_RDONLY | O_CLOEXEC);
4842 	ASSERT_LE(0, fd);
4843 
4844 	ret = read(fd, buf, buf_size - 1);
4845 	ASSERT_LE(0, ret);
4846 	EXPECT_EQ(0, close(fd));
4847 
4848 	buf[ret] = '\0';
4849 }
4850 
4851 static void set_core_pattern(struct __test_metadata *const _metadata,
4852 			     const char *pattern)
4853 {
4854 	int fd;
4855 	size_t len = strlen(pattern);
4856 
4857 	/*
4858 	 * Writing to /proc/sys/kernel/core_pattern requires EUID 0 because
4859 	 * sysctl_perm() checks that, ignoring capabilities like
4860 	 * CAP_SYS_ADMIN or CAP_DAC_OVERRIDE.
4861 	 *
4862 	 * Switching EUID clears the dumpable flag, which must be restored
4863 	 * afterwards to allow coredumps.
4864 	 */
4865 	set_cap(_metadata, CAP_SETUID);
4866 	ASSERT_EQ(0, seteuid(0));
4867 	clear_cap(_metadata, CAP_SETUID);
4868 
4869 	fd = open("/proc/sys/kernel/core_pattern", O_WRONLY | O_CLOEXEC);
4870 	ASSERT_LE(0, fd)
4871 	{
4872 		TH_LOG("Failed to open core_pattern for writing: %s",
4873 		       strerror(errno));
4874 	}
4875 
4876 	ASSERT_EQ(len, write(fd, pattern, len));
4877 	EXPECT_EQ(0, close(fd));
4878 
4879 	set_cap(_metadata, CAP_SETUID);
4880 	ASSERT_EQ(0, seteuid(getuid()));
4881 	clear_cap(_metadata, CAP_SETUID);
4882 
4883 	/* Restore dumpable flag cleared by seteuid(). */
4884 	ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1, 0, 0, 0));
4885 }
4886 
4887 FIXTURE(coredump)
4888 {
4889 	char original_core_pattern[256];
4890 };
4891 
4892 FIXTURE_SETUP(coredump)
4893 {
4894 	disable_caps(_metadata);
4895 	read_core_pattern(_metadata, self->original_core_pattern,
4896 			  sizeof(self->original_core_pattern));
4897 }
4898 
4899 FIXTURE_TEARDOWN_PARENT(coredump)
4900 {
4901 	set_core_pattern(_metadata, self->original_core_pattern);
4902 }
4903 
4904 /*
4905  * Test that even when a process is restricted with
4906  * LANDLOCK_ACCESS_FS_RESOLVE_UNIX, the kernel can still initiate a connection
4907  * to the coredump socket on the processes' behalf.
4908  */
4909 TEST_F_FORK(coredump, socket_not_restricted)
4910 {
4911 	static const char core_pattern[] = "@/tmp/landlock_coredump_test.sock";
4912 	const char *const sock_path = core_pattern + 1;
4913 	int srv_fd, conn_fd, status;
4914 	pid_t child_pid;
4915 	struct ucred cred;
4916 	socklen_t cred_len = sizeof(cred);
4917 	char buf[4096];
4918 
4919 	/* Set up the coredump server socket. */
4920 	unlink(sock_path);
4921 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, sock_path);
4922 
4923 	/* Point coredumps at our socket. */
4924 	set_core_pattern(_metadata, core_pattern);
4925 
4926 	/* Restrict LANDLOCK_ACCESS_FS_RESOLVE_UNIX. */
4927 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4928 
4929 	/* Fork a child that crashes. */
4930 	child_pid = fork();
4931 	ASSERT_LE(0, child_pid);
4932 	if (child_pid == 0) {
4933 		struct rlimit rl = {
4934 			.rlim_cur = RLIM_INFINITY,
4935 			.rlim_max = RLIM_INFINITY,
4936 		};
4937 
4938 		ASSERT_EQ(0, setrlimit(RLIMIT_CORE, &rl));
4939 
4940 		/* Crash on purpose. */
4941 		kill(getpid(), SIGSEGV);
4942 		_exit(1);
4943 	}
4944 
4945 	/*
4946 	 * Accept the coredump connection.  If Landlock incorrectly denies the
4947 	 * kernel's coredump connect, accept() will block forever, so the test
4948 	 * would time out.
4949 	 */
4950 	conn_fd = accept(srv_fd, NULL, NULL);
4951 	ASSERT_LE(0, conn_fd);
4952 
4953 	/* Check that the connection came from the crashing child. */
4954 	ASSERT_EQ(0, getsockopt(conn_fd, SOL_SOCKET, SO_PEERCRED, &cred,
4955 				&cred_len));
4956 	EXPECT_EQ(child_pid, cred.pid);
4957 
4958 	/* Drain the coredump data so the kernel can finish. */
4959 	while (read(conn_fd, buf, sizeof(buf)) > 0)
4960 		;
4961 
4962 	EXPECT_EQ(0, close(conn_fd));
4963 
4964 	/* Wait for the child and verify it coredumped. */
4965 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4966 	ASSERT_TRUE(WIFSIGNALED(status));
4967 	ASSERT_TRUE(WCOREDUMP(status));
4968 
4969 	EXPECT_EQ(0, close(srv_fd));
4970 	EXPECT_EQ(0, unlink(sock_path));
4971 }
4972 
4973 /* clang-format off */
4974 FIXTURE(layout1_bind) {};
4975 /* clang-format on */
4976 
4977 static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
4978 static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
4979 static const char bind_file2_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f2";
4980 
4981 /* Move targets for disconnected path tests. */
4982 static const char dir_s4d1[] = TMP_DIR "/s4d1";
4983 static const char file1_s4d1[] = TMP_DIR "/s4d1/f1";
4984 static const char file2_s4d1[] = TMP_DIR "/s4d1/f2";
4985 static const char dir_s4d2[] = TMP_DIR "/s4d1/s4d2";
4986 static const char file1_s4d2[] = TMP_DIR "/s4d1/s4d2/f1";
4987 static const char file1_name[] = "f1";
4988 static const char file2_name[] = "f2";
4989 
4990 FIXTURE_SETUP(layout1_bind)
4991 {
4992 	prepare_layout(_metadata);
4993 
4994 	create_layout1(_metadata);
4995 
4996 	set_cap(_metadata, CAP_SYS_ADMIN);
4997 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
4998 	clear_cap(_metadata, CAP_SYS_ADMIN);
4999 }
5000 
5001 FIXTURE_TEARDOWN_PARENT(layout1_bind)
5002 {
5003 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
5004 
5005 	remove_path(file1_s4d1);
5006 	remove_path(file2_s4d1);
5007 
5008 	remove_layout1(_metadata);
5009 
5010 	cleanup_layout(_metadata);
5011 }
5012 
5013 /*
5014  * layout1_bind hierarchy:
5015  *
5016  * tmp
5017  * ├── s1d1
5018  * │   ├── f1
5019  * │   ├── f2
5020  * │   └── s1d2
5021  * │       ├── f1
5022  * │       ├── f2
5023  * │       └── s1d3 [disconnected by path_disconnected]
5024  * │           ├── f1
5025  * │           └── f2
5026  * ├── s2d1
5027  * │   ├── f1
5028  * │   └── s2d2 [bind mount from s1d2]
5029  * │       ├── f1
5030  * │       ├── f2
5031  * │       └── s1d3
5032  * │           ├── f1
5033  * │           └── f2
5034  * ├── s3d1
5035  * │   └── s3d2
5036  * │       └── s3d3
5037  * └── s4d1 [renamed from s1d3 by path_disconnected]
5038  *     ├── f1
5039  *     ├── f2
5040  *     └── s4d2
5041  *         └── f1
5042  */
5043 
5044 TEST_F_FORK(layout1_bind, no_restriction)
5045 {
5046 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
5047 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
5048 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
5049 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5050 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
5051 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5052 
5053 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
5054 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
5055 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
5056 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
5057 	ASSERT_EQ(ENOENT, test_open(dir_s2d3, O_RDONLY));
5058 	ASSERT_EQ(ENOENT, test_open(file1_s2d3, O_RDONLY));
5059 
5060 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY));
5061 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
5062 
5063 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
5064 }
5065 
5066 TEST_F_FORK(layout1_bind, same_content_same_file)
5067 {
5068 	/*
5069 	 * Sets access right on parent directories of both source and
5070 	 * destination mount points.
5071 	 */
5072 	const struct rule layer1_parent[] = {
5073 		{
5074 			.path = dir_s1d1,
5075 			.access = ACCESS_RO,
5076 		},
5077 		{
5078 			.path = dir_s2d1,
5079 			.access = ACCESS_RW,
5080 		},
5081 		{},
5082 	};
5083 	/*
5084 	 * Sets access rights on the same bind-mounted directories.  The result
5085 	 * should be ACCESS_RW for both directories, but not both hierarchies
5086 	 * because of the first layer.
5087 	 */
5088 	const struct rule layer2_mount_point[] = {
5089 		{
5090 			.path = dir_s1d2,
5091 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5092 		},
5093 		{
5094 			.path = dir_s2d2,
5095 			.access = ACCESS_RW,
5096 		},
5097 		{},
5098 	};
5099 	/* Only allow read-access to the s1d3 hierarchies. */
5100 	const struct rule layer3_source[] = {
5101 		{
5102 			.path = dir_s1d3,
5103 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5104 		},
5105 		{},
5106 	};
5107 	/* Removes all access rights. */
5108 	const struct rule layer4_destination[] = {
5109 		{
5110 			.path = bind_file1_s1d3,
5111 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
5112 		},
5113 		{},
5114 	};
5115 
5116 	/* Sets rules for the parent directories. */
5117 	enforce_fs(_metadata, ACCESS_RW, layer1_parent);
5118 
5119 	/* Checks source hierarchy. */
5120 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
5121 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
5122 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
5123 
5124 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5125 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5126 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5127 
5128 	/* Checks destination hierarchy. */
5129 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDWR));
5130 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
5131 
5132 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
5133 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5134 
5135 	/* Sets rules for the mount points. */
5136 	enforce_fs(_metadata, ACCESS_RW, layer2_mount_point);
5137 
5138 	/* Checks source hierarchy. */
5139 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
5140 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
5141 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
5142 
5143 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5144 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5145 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5146 
5147 	/* Checks destination hierarchy. */
5148 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_RDONLY));
5149 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_WRONLY));
5150 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
5151 
5152 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
5153 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5154 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
5155 
5156 	/* Sets a (shared) rule only on the source. */
5157 	enforce_fs(_metadata, ACCESS_RW, layer3_source);
5158 
5159 	/* Checks source hierarchy. */
5160 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
5161 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5162 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5163 
5164 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5165 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
5166 	ASSERT_EQ(EACCES, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
5167 
5168 	/* Checks destination hierarchy. */
5169 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_RDONLY));
5170 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_WRONLY));
5171 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5172 
5173 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
5174 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
5175 	ASSERT_EQ(EACCES, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
5176 
5177 	/* Sets a (shared) rule only on the destination. */
5178 	enforce_fs(_metadata, ACCESS_RW, layer4_destination);
5179 
5180 	/* Checks source hierarchy. */
5181 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
5182 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
5183 
5184 	/* Checks destination hierarchy. */
5185 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_RDONLY));
5186 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
5187 }
5188 
5189 TEST_F_FORK(layout1_bind, reparent_cross_mount)
5190 {
5191 	const struct rule layer1[] = {
5192 		{
5193 			/* dir_s2d1 is beneath the dir_s2d2 mount point. */
5194 			.path = dir_s2d1,
5195 			.access = LANDLOCK_ACCESS_FS_REFER,
5196 		},
5197 		{
5198 			.path = bind_dir_s1d3,
5199 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
5200 		},
5201 		{},
5202 	};
5203 
5204 	enforce_fs(_metadata,
5205 		   LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_EXECUTE,
5206 		   layer1);
5207 
5208 	/* Checks basic denied move. */
5209 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s1d2));
5210 	ASSERT_EQ(EXDEV, errno);
5211 
5212 	/* Checks real cross-mount move (Landlock is not involved). */
5213 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s2d2));
5214 	ASSERT_EQ(EXDEV, errno);
5215 
5216 	/* Checks move that will give more accesses. */
5217 	ASSERT_EQ(-1, rename(file1_s2d2, bind_file1_s1d3));
5218 	ASSERT_EQ(EXDEV, errno);
5219 
5220 	/* Checks legitimate downgrade move. */
5221 	ASSERT_EQ(0, rename(bind_file1_s1d3, file1_s2d2));
5222 }
5223 
5224 /*
5225  * Make sure access to file through a disconnected path works as expected.
5226  * This test moves s1d3 to s4d1.
5227  */
5228 TEST_F_FORK(layout1_bind, path_disconnected)
5229 {
5230 	const struct rule layer1_allow_all[] = {
5231 		{
5232 			.path = TMP_DIR,
5233 			.access = ACCESS_ALL,
5234 		},
5235 		{},
5236 	};
5237 	const struct rule layer2_allow_just_f1[] = {
5238 		{
5239 			.path = file1_s1d3,
5240 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5241 		},
5242 		{},
5243 	};
5244 	const struct rule layer3_only_s1d2[] = {
5245 		{
5246 			.path = dir_s1d2,
5247 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5248 		},
5249 		{},
5250 	};
5251 
5252 	/* Landlock should not deny access just because it is disconnected. */
5253 	int ruleset_fd_l1 =
5254 		create_ruleset(_metadata, ACCESS_ALL, layer1_allow_all);
5255 
5256 	/* Creates the new ruleset now before we move the dir containing the file. */
5257 	int ruleset_fd_l2 =
5258 		create_ruleset(_metadata, ACCESS_RW, layer2_allow_just_f1);
5259 	int ruleset_fd_l3 =
5260 		create_ruleset(_metadata, ACCESS_RW, layer3_only_s1d2);
5261 	int bind_s1d3_fd;
5262 
5263 	enforce_ruleset(_metadata, ruleset_fd_l1);
5264 	EXPECT_EQ(0, close(ruleset_fd_l1));
5265 
5266 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5267 	ASSERT_LE(0, bind_s1d3_fd);
5268 
5269 	/* Tests access is possible before we move. */
5270 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5271 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5272 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
5273 
5274 	/* Makes it disconnected. */
5275 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
5276 	{
5277 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
5278 		       strerror(errno));
5279 	}
5280 
5281 	/* Tests that access is still possible. */
5282 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5283 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5284 
5285 	/*
5286 	 * Tests that ".." is not possible (not because of Landlock, but just
5287 	 * because it's disconnected).
5288 	 */
5289 	EXPECT_EQ(ENOENT,
5290 		  test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
5291 
5292 	/* This should still work with a narrower rule. */
5293 	enforce_ruleset(_metadata, ruleset_fd_l2);
5294 	EXPECT_EQ(0, close(ruleset_fd_l2));
5295 
5296 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY));
5297 	/*
5298 	 * Accessing a file through a disconnected file descriptor can still be
5299 	 * allowed by a rule tied to this file, even if it is no longer visible in
5300 	 * its mount point.
5301 	 */
5302 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5303 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5304 
5305 	enforce_ruleset(_metadata, ruleset_fd_l3);
5306 	EXPECT_EQ(0, close(ruleset_fd_l3));
5307 
5308 	EXPECT_EQ(EACCES, test_open(file1_s4d1, O_RDONLY));
5309 	/*
5310 	 * Accessing a file through a disconnected file descriptor can still be
5311 	 * allowed by a rule tied to the original mount point, even if it is no
5312 	 * longer visible in its mount point.
5313 	 */
5314 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5315 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5316 }
5317 
5318 /*
5319  * Test that renameat with disconnected paths works under Landlock.  This test
5320  * moves s1d3 to s4d2, so that we can have a rule allowing refers on the move
5321  * target's immediate parent.
5322  */
5323 TEST_F_FORK(layout1_bind, path_disconnected_rename)
5324 {
5325 	const struct rule layer1[] = {
5326 		{
5327 			.path = dir_s1d2,
5328 			.access = LANDLOCK_ACCESS_FS_REFER |
5329 				  LANDLOCK_ACCESS_FS_MAKE_DIR |
5330 				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
5331 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5332 				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
5333 				  LANDLOCK_ACCESS_FS_READ_FILE,
5334 		},
5335 		{
5336 			.path = dir_s4d1,
5337 			.access = LANDLOCK_ACCESS_FS_REFER |
5338 				  LANDLOCK_ACCESS_FS_MAKE_DIR |
5339 				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
5340 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5341 				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
5342 				  LANDLOCK_ACCESS_FS_READ_FILE,
5343 		},
5344 		{}
5345 	};
5346 
5347 	/* This layer only handles LANDLOCK_ACCESS_FS_READ_FILE. */
5348 	const struct rule layer2_only_s1d2[] = {
5349 		{
5350 			.path = dir_s1d2,
5351 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5352 		},
5353 		{},
5354 	};
5355 	int ruleset_fd_l1, ruleset_fd_l2;
5356 	pid_t child_pid;
5357 	int bind_s1d3_fd, status;
5358 
5359 	ASSERT_EQ(0, mkdir(dir_s4d1, 0755))
5360 	{
5361 		TH_LOG("Failed to create %s: %s", dir_s4d1, strerror(errno));
5362 	}
5363 	ruleset_fd_l1 = create_ruleset(_metadata, ACCESS_ALL, layer1);
5364 	ruleset_fd_l2 = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
5365 				       layer2_only_s1d2);
5366 
5367 	enforce_ruleset(_metadata, ruleset_fd_l1);
5368 	EXPECT_EQ(0, close(ruleset_fd_l1));
5369 
5370 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5371 	ASSERT_LE(0, bind_s1d3_fd);
5372 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5373 
5374 	/* Tests ENOENT priority over EACCES for disconnected directory. */
5375 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
5376 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
5377 	{
5378 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
5379 		       strerror(errno));
5380 	}
5381 	EXPECT_EQ(ENOENT, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
5382 
5383 	/*
5384 	 * The file is no longer under s1d2 but we should still be able to access it
5385 	 * with layer 2 because its mount point is evaluated as the first valid
5386 	 * directory because it was initially a parent.  Do a fork to test this so
5387 	 * we don't prevent ourselves from renaming it back later.
5388 	 */
5389 	child_pid = fork();
5390 	ASSERT_LE(0, child_pid);
5391 	if (child_pid == 0) {
5392 		enforce_ruleset(_metadata, ruleset_fd_l2);
5393 		EXPECT_EQ(0, close(ruleset_fd_l2));
5394 		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5395 		EXPECT_EQ(EACCES, test_open(file1_s4d2, O_RDONLY));
5396 
5397 		/*
5398 		 * Tests that access widening checks indeed prevents us from renaming it
5399 		 * back.
5400 		 */
5401 		EXPECT_EQ(-1, rename(dir_s4d2, dir_s1d3));
5402 		EXPECT_EQ(EXDEV, errno);
5403 
5404 		/*
5405 		 * Including through the now disconnected fd (but it should return
5406 		 * EXDEV).
5407 		 */
5408 		EXPECT_EQ(-1, renameat(bind_s1d3_fd, file1_name, AT_FDCWD,
5409 				       file1_s2d2));
5410 		EXPECT_EQ(EXDEV, errno);
5411 		_exit(_metadata->exit_code);
5412 		return;
5413 	}
5414 
5415 	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
5416 	EXPECT_EQ(1, WIFEXITED(status));
5417 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
5418 
5419 	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
5420 	{
5421 		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d1, dir_s1d3,
5422 		       strerror(errno));
5423 	}
5424 
5425 	/* Now checks that we can access it under l2. */
5426 	child_pid = fork();
5427 	ASSERT_LE(0, child_pid);
5428 	if (child_pid == 0) {
5429 		enforce_ruleset(_metadata, ruleset_fd_l2);
5430 		EXPECT_EQ(0, close(ruleset_fd_l2));
5431 		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5432 		EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5433 		_exit(_metadata->exit_code);
5434 		return;
5435 	}
5436 
5437 	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
5438 	EXPECT_EQ(1, WIFEXITED(status));
5439 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
5440 
5441 	/*
5442 	 * Also test that we can rename via a disconnected path.  We move the
5443 	 * dir back to the disconnected place first, then we rename file1 to
5444 	 * file2 through our dir fd.
5445 	 */
5446 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
5447 	{
5448 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
5449 		       strerror(errno));
5450 	}
5451 	ASSERT_EQ(0,
5452 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name))
5453 	{
5454 		TH_LOG("Failed to rename %s to %s within disconnected %s: %s",
5455 		       file1_name, file2_name, bind_dir_s1d3, strerror(errno));
5456 	}
5457 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5458 	ASSERT_EQ(0, renameat(bind_s1d3_fd, file2_name, AT_FDCWD, file1_s2d2))
5459 	{
5460 		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
5461 		       file2_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
5462 	}
5463 	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY));
5464 	EXPECT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5465 
5466 	/* Move it back using the disconnected path as the target. */
5467 	ASSERT_EQ(0, renameat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file1_name))
5468 	{
5469 		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
5470 		       file1_s1d2, file1_name, bind_dir_s1d3, strerror(errno));
5471 	}
5472 
5473 	/* Now make it connected again. */
5474 	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
5475 	{
5476 		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d2, dir_s1d3,
5477 		       strerror(errno));
5478 	}
5479 
5480 	/* Checks again that we can access it under l2. */
5481 	enforce_ruleset(_metadata, ruleset_fd_l2);
5482 	EXPECT_EQ(0, close(ruleset_fd_l2));
5483 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5484 	EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5485 }
5486 
5487 /*
5488  * Test that linkat(2) with disconnected paths works under Landlock. This
5489  * test moves s1d3 to s4d1.
5490  */
5491 TEST_F_FORK(layout1_bind, path_disconnected_link)
5492 {
5493 	/* Ruleset to be applied after renaming s1d3 to s4d1. */
5494 	const struct rule layer1[] = {
5495 		{
5496 			.path = dir_s4d1,
5497 			.access = LANDLOCK_ACCESS_FS_REFER |
5498 				  LANDLOCK_ACCESS_FS_READ_FILE |
5499 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5500 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
5501 		},
5502 		{
5503 			.path = dir_s2d2,
5504 			.access = LANDLOCK_ACCESS_FS_REFER |
5505 				  LANDLOCK_ACCESS_FS_READ_FILE |
5506 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5507 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
5508 		},
5509 		{}
5510 	};
5511 	int bind_s1d3_fd;
5512 
5513 	/* Removes unneeded files created by layout1, otherwise it will EEXIST. */
5514 	ASSERT_EQ(0, unlink(file1_s1d2));
5515 	ASSERT_EQ(0, unlink(file2_s1d3));
5516 
5517 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5518 	ASSERT_LE(0, bind_s1d3_fd);
5519 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5520 
5521 	/* Disconnects bind_s1d3_fd. */
5522 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
5523 	{
5524 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
5525 		       strerror(errno));
5526 	}
5527 
5528 	/* Need this later to test different parent link. */
5529 	ASSERT_EQ(0, mkdir(dir_s4d2, 0755))
5530 	{
5531 		TH_LOG("Failed to create %s: %s", dir_s4d2, strerror(errno));
5532 	}
5533 
5534 	enforce_fs(_metadata, ACCESS_ALL, layer1);
5535 
5536 	/* From disconnected to connected. */
5537 	ASSERT_EQ(0, linkat(bind_s1d3_fd, file1_name, AT_FDCWD, file1_s2d2, 0))
5538 	{
5539 		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
5540 		       file1_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
5541 	}
5542 
5543 	/* Tests that we can access via the new link... */
5544 	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY))
5545 	{
5546 		TH_LOG("Failed to open newly linked %s: %s", file1_s2d2,
5547 		       strerror(errno));
5548 	}
5549 
5550 	/* ...as well as the old one. */
5551 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
5552 	{
5553 		TH_LOG("Failed to open original %s: %s", file1_s4d1,
5554 		       strerror(errno));
5555 	}
5556 
5557 	/* From connected to disconnected. */
5558 	ASSERT_EQ(0, unlink(file1_s4d1));
5559 	ASSERT_EQ(0, linkat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file2_name, 0))
5560 	{
5561 		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
5562 		       file1_s2d2, file2_name, bind_dir_s1d3, strerror(errno));
5563 	}
5564 	EXPECT_EQ(0, test_open(file2_s4d1, O_RDONLY));
5565 	ASSERT_EQ(0, unlink(file1_s2d2));
5566 
5567 	/* From disconnected to disconnected (same parent). */
5568 	ASSERT_EQ(0,
5569 		  linkat(bind_s1d3_fd, file2_name, bind_s1d3_fd, file1_name, 0))
5570 	{
5571 		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
5572 		       file2_name, file1_name, bind_dir_s1d3, strerror(errno));
5573 	}
5574 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
5575 	{
5576 		TH_LOG("Failed to open newly linked %s: %s", file1_s4d1,
5577 		       strerror(errno));
5578 	}
5579 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY))
5580 	{
5581 		TH_LOG("Failed to open %s through newly created link under disconnected path: %s",
5582 		       file1_name, strerror(errno));
5583 	}
5584 	ASSERT_EQ(0, unlink(file2_s4d1));
5585 
5586 	/* From disconnected to disconnected (different parent). */
5587 	ASSERT_EQ(0,
5588 		  linkat(bind_s1d3_fd, file1_name, bind_s1d3_fd, "s4d2/f1", 0))
5589 	{
5590 		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
5591 		       file1_name, "s4d2/f1", bind_dir_s1d3, strerror(errno));
5592 	}
5593 	EXPECT_EQ(0, test_open(file1_s4d2, O_RDONLY))
5594 	{
5595 		TH_LOG("Failed to open %s after link: %s", file1_s4d2,
5596 		       strerror(errno));
5597 	}
5598 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "s4d2/f1", O_RDONLY))
5599 	{
5600 		TH_LOG("Failed to open %s through disconnected path after link: %s",
5601 		       "s4d2/f1", strerror(errno));
5602 	}
5603 }
5604 
5605 /*
5606  * layout4_disconnected_leafs with bind mount and renames:
5607  *
5608  * tmp
5609  * ├── s1d1
5610  * │   └── s1d2 [source of the bind mount]
5611  * │       ├── s1d31
5612  * │       │   └── s1d41 [now renamed beneath s3d1]
5613  * │       │       ├── f1
5614  * │       │       └── f2
5615  * │       └── s1d32
5616  * │           └── s1d42 [now renamed beneath s4d1]
5617  * │               ├── f3
5618  * │               └── f4
5619  * ├── s2d1
5620  * │   └── s2d2 [bind mount of s1d2]
5621  * │       ├── s1d31
5622  * │       │   └── s1d41 [opened FD, now renamed beneath s3d1]
5623  * │       │       ├── f1
5624  * │       │       └── f2
5625  * │       └── s1d32
5626  * │           └── s1d42 [opened FD, now renamed beneath s4d1]
5627  * │               ├── f3
5628  * │               └── f4
5629  * ├── s3d1
5630  * │   └── s1d41 [renamed here]
5631  * │       ├── f1
5632  * │       └── f2
5633  * └── s4d1
5634  *     └── s1d42 [renamed here]
5635  *         ├── f3
5636  *         └── f4
5637  */
5638 /* clang-format off */
5639 FIXTURE(layout4_disconnected_leafs) {
5640 	int s2d2_fd;
5641 };
5642 /* clang-format on */
5643 
5644 FIXTURE_SETUP(layout4_disconnected_leafs)
5645 {
5646 	prepare_layout(_metadata);
5647 
5648 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1");
5649 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2");
5650 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3");
5651 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f4");
5652 	create_directory(_metadata, TMP_DIR "/s2d1/s2d2");
5653 	create_directory(_metadata, TMP_DIR "/s3d1");
5654 	create_directory(_metadata, TMP_DIR "/s4d1");
5655 
5656 	self->s2d2_fd =
5657 		open(TMP_DIR "/s2d1/s2d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
5658 	ASSERT_LE(0, self->s2d2_fd);
5659 
5660 	set_cap(_metadata, CAP_SYS_ADMIN);
5661 	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2", NULL,
5662 			   MS_BIND, NULL));
5663 	clear_cap(_metadata, CAP_SYS_ADMIN);
5664 }
5665 
5666 FIXTURE_TEARDOWN_PARENT(layout4_disconnected_leafs)
5667 {
5668 	/* umount(TMP_DIR "/s2d1") is handled by namespace lifetime. */
5669 
5670 	/* Removes files after renames. */
5671 	remove_path(TMP_DIR "/s3d1/s1d41/f1");
5672 	remove_path(TMP_DIR "/s3d1/s1d41/f2");
5673 	remove_path(TMP_DIR "/s4d1/s1d42/f1");
5674 	remove_path(TMP_DIR "/s4d1/s1d42/f3");
5675 	remove_path(TMP_DIR "/s4d1/s1d42/f4");
5676 	remove_path(TMP_DIR "/s4d1/s1d42/f5");
5677 
5678 	cleanup_layout(_metadata);
5679 }
5680 
5681 FIXTURE_VARIANT(layout4_disconnected_leafs)
5682 {
5683 	/*
5684 	 * Parent of the bind mount source.  It should always be ignored when
5685 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5686 	 */
5687 	const __u64 allowed_s1d1;
5688 	/*
5689 	 * Source of bind mount (to s2d2).  It should always be enforced when
5690 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5691 	 */
5692 	const __u64 allowed_s1d2;
5693 	/*
5694 	 * Original parent of s1d41.  It should always be ignored when testing
5695 	 * against files under the s1d41 disconnected directory.
5696 	 */
5697 	const __u64 allowed_s1d31;
5698 	/*
5699 	 * Original parent of s1d42.  It should always be ignored when testing
5700 	 * against files under the s1d42 disconnected directory.
5701 	 */
5702 	const __u64 allowed_s1d32;
5703 	/*
5704 	 * Opened and disconnected source directory.  It should always be enforced
5705 	 * when testing against files under the s1d41 disconnected directory.
5706 	 */
5707 	const __u64 allowed_s1d41;
5708 	/*
5709 	 * Opened and disconnected source directory.  It should always be enforced
5710 	 * when testing against files under the s1d42 disconnected directory.
5711 	 */
5712 	const __u64 allowed_s1d42;
5713 	/*
5714 	 * File in the s1d41 disconnected directory.  It should always be enforced
5715 	 * when testing against itself under the s1d41 disconnected directory.
5716 	 */
5717 	const __u64 allowed_f1;
5718 	/*
5719 	 * File in the s1d41 disconnected directory.  It should always be enforced
5720 	 * when testing against itself under the s1d41 disconnected directory.
5721 	 */
5722 	const __u64 allowed_f2;
5723 	/*
5724 	 * File in the s1d42 disconnected directory.  It should always be enforced
5725 	 * when testing against itself under the s1d42 disconnected directory.
5726 	 */
5727 	const __u64 allowed_f3;
5728 	/*
5729 	 * Parent of the bind mount destination.  It should always be enforced when
5730 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5731 	 */
5732 	const __u64 allowed_s2d1;
5733 	/*
5734 	 * Directory covered by the bind mount.  It should always be ignored when
5735 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5736 	 */
5737 	const __u64 allowed_s2d2;
5738 	/*
5739 	 * New parent of the renamed s1d41.  It should always be ignored when
5740 	 * testing against files under the s1d41 disconnected directory.
5741 	 */
5742 	const __u64 allowed_s3d1;
5743 	/*
5744 	 * New parent of the renamed s1d42.  It should always be ignored when
5745 	 * testing against files under the s1d42 disconnected directory.
5746 	 */
5747 	const __u64 allowed_s4d1;
5748 
5749 	/* Expected result of the call to open([fd:s1d41]/f1, O_RDONLY). */
5750 	const int expected_read_result;
5751 	/* Expected result of the call to renameat([fd:s1d41]/f1, [fd:s1d42]/f1). */
5752 	const int expected_rename_result;
5753 	/*
5754 	 * Expected result of the call to renameat([fd:s1d41]/f2, [fd:s1d42]/f3,
5755 	 * RENAME_EXCHANGE).
5756 	 */
5757 	const int expected_exchange_result;
5758 	/* Expected result of the call to renameat([fd:s1d42]/f4, [fd:s1d42]/f5). */
5759 	const int expected_same_dir_rename_result;
5760 };
5761 
5762 /* clang-format off */
5763 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d1_mount_src_parent) {
5764 	/* clang-format on */
5765 	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
5766 			LANDLOCK_ACCESS_FS_READ_FILE |
5767 			LANDLOCK_ACCESS_FS_EXECUTE |
5768 			LANDLOCK_ACCESS_FS_MAKE_REG,
5769 	.expected_read_result = EACCES,
5770 	.expected_same_dir_rename_result = EACCES,
5771 	.expected_rename_result = EACCES,
5772 	.expected_exchange_result = EACCES,
5773 };
5774 
5775 /* clang-format off */
5776 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_refer) {
5777 	/* clang-format on */
5778 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5779 	.expected_read_result = 0,
5780 	.expected_same_dir_rename_result = EACCES,
5781 	.expected_rename_result = EACCES,
5782 	.expected_exchange_result = EACCES,
5783 };
5784 
5785 /* clang-format off */
5786 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_create) {
5787 	/* clang-format on */
5788 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
5789 			LANDLOCK_ACCESS_FS_MAKE_REG,
5790 	.expected_read_result = 0,
5791 	.expected_same_dir_rename_result = 0,
5792 	.expected_rename_result = EXDEV,
5793 	.expected_exchange_result = EXDEV,
5794 };
5795 
5796 /* clang-format off */
5797 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_rename) {
5798 	/* clang-format on */
5799 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5800 	.expected_read_result = EACCES,
5801 	.expected_same_dir_rename_result = 0,
5802 	.expected_rename_result = 0,
5803 	.expected_exchange_result = 0,
5804 };
5805 
5806 /* clang-format off */
5807 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d31_s1d32_old_parent) {
5808 	/* clang-format on */
5809 	.allowed_s1d31 = LANDLOCK_ACCESS_FS_REFER |
5810 			 LANDLOCK_ACCESS_FS_READ_FILE |
5811 			 LANDLOCK_ACCESS_FS_EXECUTE |
5812 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5813 	.allowed_s1d32 = LANDLOCK_ACCESS_FS_REFER |
5814 			 LANDLOCK_ACCESS_FS_READ_FILE |
5815 			 LANDLOCK_ACCESS_FS_EXECUTE |
5816 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5817 	.expected_read_result = EACCES,
5818 	.expected_same_dir_rename_result = EACCES,
5819 	.expected_rename_result = EACCES,
5820 	.expected_exchange_result = EACCES,
5821 };
5822 
5823 /* clang-format off */
5824 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_refer) {
5825 	/* clang-format on */
5826 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
5827 			 LANDLOCK_ACCESS_FS_READ_FILE,
5828 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
5829 			 LANDLOCK_ACCESS_FS_READ_FILE,
5830 	.expected_read_result = 0,
5831 	.expected_same_dir_rename_result = EACCES,
5832 	.expected_rename_result = EACCES,
5833 	.expected_exchange_result = EACCES,
5834 };
5835 
5836 /* clang-format off */
5837 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_create) {
5838 	/* clang-format on */
5839 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_READ_FILE |
5840 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5841 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_READ_FILE |
5842 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5843 	.expected_read_result = 0,
5844 	.expected_same_dir_rename_result = 0,
5845 	.expected_rename_result = EXDEV,
5846 	.expected_exchange_result = EXDEV,
5847 };
5848 
5849 /* clang-format off */
5850 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_even) {
5851 	/* clang-format on */
5852 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5853 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5854 	.expected_read_result = EACCES,
5855 	.expected_same_dir_rename_result = 0,
5856 	.expected_rename_result = 0,
5857 	.expected_exchange_result = 0,
5858 };
5859 
5860 /* The destination directory has more access right. */
5861 /* clang-format off */
5862 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_more) {
5863 	/* clang-format on */
5864 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5865 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
5866 			 LANDLOCK_ACCESS_FS_MAKE_REG |
5867 			 LANDLOCK_ACCESS_FS_EXECUTE,
5868 	.expected_read_result = EACCES,
5869 	.expected_same_dir_rename_result = 0,
5870 	/* Access denied. */
5871 	.expected_rename_result = EXDEV,
5872 	.expected_exchange_result = EXDEV,
5873 };
5874 
5875 /* The destination directory has less access right. */
5876 /* clang-format off */
5877 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_less) {
5878 	/* clang-format on */
5879 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
5880 			 LANDLOCK_ACCESS_FS_MAKE_REG |
5881 			 LANDLOCK_ACCESS_FS_EXECUTE,
5882 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5883 	.expected_read_result = EACCES,
5884 	.expected_same_dir_rename_result = 0,
5885 	/* Access allowed. */
5886 	.expected_rename_result = 0,
5887 	.expected_exchange_result = EXDEV,
5888 };
5889 
5890 /* clang-format off */
5891 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_create) {
5892 	/* clang-format on */
5893 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5894 			LANDLOCK_ACCESS_FS_MAKE_REG,
5895 	.expected_read_result = 0,
5896 	.expected_same_dir_rename_result = 0,
5897 	.expected_rename_result = EXDEV,
5898 	.expected_exchange_result = EXDEV,
5899 };
5900 
5901 /* clang-format off */
5902 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_refer) {
5903 	/* clang-format on */
5904 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5905 	.expected_read_result = 0,
5906 	.expected_same_dir_rename_result = EACCES,
5907 	.expected_rename_result = EACCES,
5908 	.expected_exchange_result = EACCES,
5909 };
5910 
5911 /* clang-format off */
5912 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_mini) {
5913 	/* clang-format on */
5914 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
5915 			LANDLOCK_ACCESS_FS_READ_FILE |
5916 			LANDLOCK_ACCESS_FS_MAKE_REG,
5917 	.expected_read_result = 0,
5918 	.expected_same_dir_rename_result = 0,
5919 	.expected_rename_result = 0,
5920 	.expected_exchange_result = 0,
5921 };
5922 
5923 /* clang-format off */
5924 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d2_covered_by_mount) {
5925 	/* clang-format on */
5926 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER |
5927 			LANDLOCK_ACCESS_FS_READ_FILE |
5928 			LANDLOCK_ACCESS_FS_EXECUTE |
5929 			LANDLOCK_ACCESS_FS_MAKE_REG,
5930 	.expected_read_result = EACCES,
5931 	.expected_same_dir_rename_result = EACCES,
5932 	.expected_rename_result = EACCES,
5933 	.expected_exchange_result = EACCES,
5934 };
5935 
5936 /* Tests collect_domain_accesses(). */
5937 /* clang-format off */
5938 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_refer) {
5939 	/* clang-format on */
5940 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5941 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5942 	.expected_read_result = 0,
5943 	.expected_same_dir_rename_result = EACCES,
5944 	.expected_rename_result = EACCES,
5945 	.expected_exchange_result = EACCES,
5946 };
5947 
5948 /* clang-format off */
5949 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_create) {
5950 	/* clang-format on */
5951 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5952 			LANDLOCK_ACCESS_FS_MAKE_REG,
5953 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5954 			LANDLOCK_ACCESS_FS_MAKE_REG,
5955 	.expected_read_result = 0,
5956 	.expected_same_dir_rename_result = 0,
5957 	.expected_rename_result = EXDEV,
5958 	.expected_exchange_result = EXDEV,
5959 };
5960 
5961 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs,
5962 		    s3d1_s4d1_disconnected_rename_even){
5963 	/* clang-format on */
5964 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5965 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5966 	.expected_read_result = EACCES,
5967 	.expected_same_dir_rename_result = 0,
5968 	.expected_rename_result = 0,
5969 	.expected_exchange_result = 0,
5970 };
5971 
5972 /* The destination directory has more access right. */
5973 /* clang-format off */
5974 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_more) {
5975 	/* clang-format on */
5976 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5977 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
5978 			LANDLOCK_ACCESS_FS_EXECUTE,
5979 	.expected_read_result = EACCES,
5980 	.expected_same_dir_rename_result = 0,
5981 	/* Access denied. */
5982 	.expected_rename_result = EXDEV,
5983 	.expected_exchange_result = EXDEV,
5984 };
5985 
5986 /* The destination directory has less access right. */
5987 /* clang-format off */
5988 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_less) {
5989 	/* clang-format on */
5990 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
5991 			LANDLOCK_ACCESS_FS_EXECUTE,
5992 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5993 	.expected_read_result = EACCES,
5994 	.expected_same_dir_rename_result = 0,
5995 	/* Access allowed. */
5996 	.expected_rename_result = 0,
5997 	.expected_exchange_result = EXDEV,
5998 };
5999 
6000 /* clang-format off */
6001 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, f1_f2_f3) {
6002 	/* clang-format on */
6003 	.allowed_f1 = LANDLOCK_ACCESS_FS_READ_FILE,
6004 	.allowed_f2 = LANDLOCK_ACCESS_FS_READ_FILE,
6005 	.allowed_f3 = LANDLOCK_ACCESS_FS_READ_FILE,
6006 	.expected_read_result = 0,
6007 	.expected_same_dir_rename_result = EACCES,
6008 	.expected_rename_result = EACCES,
6009 	.expected_exchange_result = EACCES,
6010 };
6011 
6012 TEST_F_FORK(layout4_disconnected_leafs, read_rename_exchange)
6013 {
6014 	const __u64 handled_access =
6015 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
6016 		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
6017 	const struct rule rules[] = {
6018 		{
6019 			.path = TMP_DIR "/s1d1",
6020 			.access = variant->allowed_s1d1,
6021 		},
6022 		{
6023 			.path = TMP_DIR "/s1d1/s1d2",
6024 			.access = variant->allowed_s1d2,
6025 		},
6026 		{
6027 			.path = TMP_DIR "/s1d1/s1d2/s1d31",
6028 			.access = variant->allowed_s1d31,
6029 		},
6030 		{
6031 			.path = TMP_DIR "/s1d1/s1d2/s1d32",
6032 			.access = variant->allowed_s1d32,
6033 		},
6034 		{
6035 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
6036 			.access = variant->allowed_s1d41,
6037 		},
6038 		{
6039 			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
6040 			.access = variant->allowed_s1d42,
6041 		},
6042 		{
6043 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1",
6044 			.access = variant->allowed_f1,
6045 		},
6046 		{
6047 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2",
6048 			.access = variant->allowed_f2,
6049 		},
6050 		{
6051 			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3",
6052 			.access = variant->allowed_f3,
6053 		},
6054 		{
6055 			.path = TMP_DIR "/s2d1",
6056 			.access = variant->allowed_s2d1,
6057 		},
6058 		/* s2d2_fd */
6059 		{
6060 			.path = TMP_DIR "/s3d1",
6061 			.access = variant->allowed_s3d1,
6062 		},
6063 		{
6064 			.path = TMP_DIR "/s4d1",
6065 			.access = variant->allowed_s4d1,
6066 		},
6067 		{},
6068 	};
6069 	int ruleset_fd, s1d41_bind_fd, s1d42_bind_fd;
6070 
6071 	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
6072 
6073 	/* Adds rule for the covered directory. */
6074 	if (variant->allowed_s2d2) {
6075 		ASSERT_EQ(0, landlock_add_rule(
6076 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6077 				     &(struct landlock_path_beneath_attr){
6078 					     .parent_fd = self->s2d2_fd,
6079 					     .allowed_access =
6080 						     variant->allowed_s2d2,
6081 				     },
6082 				     0));
6083 	}
6084 	EXPECT_EQ(0, close(self->s2d2_fd));
6085 
6086 	s1d41_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d31/s1d41",
6087 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6088 	ASSERT_LE(0, s1d41_bind_fd);
6089 	s1d42_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d32/s1d42",
6090 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6091 	ASSERT_LE(0, s1d42_bind_fd);
6092 
6093 	/* Disconnects and checks source and destination directories. */
6094 	EXPECT_EQ(0, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
6095 	EXPECT_EQ(0, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
6096 	/* Renames to make it accessible through s3d1/s1d41 */
6097 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
6098 				   AT_FDCWD, TMP_DIR "/s3d1/s1d41"));
6099 	/* Renames to make it accessible through s4d1/s1d42 */
6100 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
6101 				   AT_FDCWD, TMP_DIR "/s4d1/s1d42"));
6102 	EXPECT_EQ(ENOENT, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
6103 	EXPECT_EQ(ENOENT, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
6104 
6105 	enforce_ruleset(_metadata, ruleset_fd);
6106 	EXPECT_EQ(0, close(ruleset_fd));
6107 
6108 	EXPECT_EQ(variant->expected_read_result,
6109 		  test_open_rel(s1d41_bind_fd, "f1", O_RDONLY));
6110 
6111 	EXPECT_EQ(variant->expected_rename_result,
6112 		  test_renameat(s1d41_bind_fd, "f1", s1d42_bind_fd, "f1"));
6113 	EXPECT_EQ(variant->expected_exchange_result,
6114 		  test_exchangeat(s1d41_bind_fd, "f2", s1d42_bind_fd, "f3"));
6115 
6116 	EXPECT_EQ(variant->expected_same_dir_rename_result,
6117 		  test_renameat(s1d42_bind_fd, "f4", s1d42_bind_fd, "f5"));
6118 }
6119 
6120 /*
6121  * layout5_disconnected_branch before rename:
6122  *
6123  * tmp
6124  * ├── s1d1
6125  * │   └── s1d2 [source of the first bind mount]
6126  * │       └── s1d3
6127  * │           ├── s1d41
6128  * │           │   ├── f1
6129  * │           │   └── f2
6130  * │           └── s1d42
6131  * │               ├── f3
6132  * │               └── f4
6133  * ├── s2d1
6134  * │   └── s2d2 [source of the second bind mount]
6135  * │       └── s2d3
6136  * │           └── s2d4 [first s1d2 bind mount]
6137  * │               └── s1d3
6138  * │                   ├── s1d41
6139  * │                   │   ├── f1
6140  * │                   │   └── f2
6141  * │                   └── s1d42
6142  * │                       ├── f3
6143  * │                       └── f4
6144  * ├── s3d1
6145  * │   └── s3d2 [second s2d2 bind mount]
6146  * │       └── s2d3
6147  * │           └── s2d4 [first s1d2 bind mount]
6148  * │               └── s1d3
6149  * │                   ├── s1d41
6150  * │                   │   ├── f1
6151  * │                   │   └── f2
6152  * │                   └── s1d42
6153  * │                       ├── f3
6154  * │                       └── f4
6155  * └── s4d1
6156  *
6157  * After rename:
6158  *
6159  * tmp
6160  * ├── s1d1
6161  * │   └── s1d2 [source of the first bind mount]
6162  * │       └── s1d3
6163  * │           ├── s1d41
6164  * │           │   ├── f1
6165  * │           │   └── f2
6166  * │           └── s1d42
6167  * │               ├── f3
6168  * │               └── f4
6169  * ├── s2d1
6170  * │   └── s2d2 [source of the second bind mount]
6171  * ├── s3d1
6172  * │   └── s3d2 [second s2d2 bind mount]
6173  * └── s4d1
6174  *     └── s2d3 [renamed here]
6175  *         └── s2d4 [first s1d2 bind mount]
6176  *             └── s1d3
6177  *                 ├── s1d41
6178  *                 │   ├── f1
6179  *                 │   └── f2
6180  *                 └── s1d42
6181  *                     ├── f3
6182  *                     └── f4
6183  *
6184  * Decision path for access from the s3d1/s3d2/s2d3/s2d4/s1d3 file descriptor:
6185  *   1. first bind mount:   s1d3 -> s1d2
6186  *   2. second bind mount:    s2d3
6187  *   3. tmp mount:              s4d1 -> tmp [disconnected branch]
6188  *   4. second bind mount:        s2d2
6189  *   5. tmp mount:                  s3d1 -> tmp
6190  *   6. parent mounts:                [...] -> /
6191  *
6192  * The s4d1 directory is evaluated even if it is not in the s2d2 mount.
6193  */
6194 
6195 /* clang-format off */
6196 FIXTURE(layout5_disconnected_branch) {
6197 	int s2d4_fd, s3d2_fd;
6198 };
6199 /* clang-format on */
6200 
6201 FIXTURE_SETUP(layout5_disconnected_branch)
6202 {
6203 	prepare_layout(_metadata);
6204 
6205 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
6206 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
6207 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
6208 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
6209 	create_directory(_metadata, TMP_DIR "/s2d1/s2d2/s2d3/s2d4");
6210 	create_directory(_metadata, TMP_DIR "/s3d1/s3d2");
6211 	create_directory(_metadata, TMP_DIR "/s4d1");
6212 
6213 	self->s2d4_fd = open(TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
6214 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6215 	ASSERT_LE(0, self->s2d4_fd);
6216 
6217 	self->s3d2_fd =
6218 		open(TMP_DIR "/s3d1/s3d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
6219 	ASSERT_LE(0, self->s3d2_fd);
6220 
6221 	set_cap(_metadata, CAP_SYS_ADMIN);
6222 	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
6223 			   NULL, MS_BIND, NULL));
6224 	ASSERT_EQ(0, mount(TMP_DIR "/s2d1/s2d2", TMP_DIR "/s3d1/s3d2", NULL,
6225 			   MS_BIND | MS_REC, NULL));
6226 	clear_cap(_metadata, CAP_SYS_ADMIN);
6227 }
6228 
6229 FIXTURE_TEARDOWN_PARENT(layout5_disconnected_branch)
6230 {
6231 	/* Bind mounts are handled by namespace lifetime. */
6232 
6233 	/* Removes files after renames. */
6234 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
6235 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
6236 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f1");
6237 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
6238 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
6239 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f5");
6240 
6241 	cleanup_layout(_metadata);
6242 }
6243 
6244 FIXTURE_VARIANT(layout5_disconnected_branch)
6245 {
6246 	/*
6247 	 * Parent of all files.  It should always be enforced when testing against
6248 	 * files under the s1d41 or s1d42 disconnected directories.
6249 	 */
6250 	const __u64 allowed_base;
6251 	/*
6252 	 * Parent of the first bind mount source.  It should always be ignored when
6253 	 * testing against files under the s1d41 or s1d42 disconnected directories.
6254 	 */
6255 	const __u64 allowed_s1d1;
6256 	const __u64 allowed_s1d2;
6257 	const __u64 allowed_s1d3;
6258 	const __u64 allowed_s2d1;
6259 	const __u64 allowed_s2d2;
6260 	const __u64 allowed_s2d3;
6261 	const __u64 allowed_s2d4;
6262 	const __u64 allowed_s3d1;
6263 	const __u64 allowed_s3d2;
6264 	const __u64 allowed_s4d1;
6265 
6266 	/* Expected result of the call to open([fd:s1d3]/s1d41/f1, O_RDONLY). */
6267 	const int expected_read_result;
6268 	/*
6269 	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f1,
6270 	 * [fd:s1d3]/s1d42/f1).
6271 	 */
6272 	const int expected_rename_result;
6273 	/*
6274 	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f2,
6275 	 * [fd:s1d3]/s1d42/f3,  RENAME_EXCHANGE).
6276 	 */
6277 	const int expected_exchange_result;
6278 	/*
6279 	 * Expected result of the call to renameat([fd:s1d3]/s1d42/f4,
6280 	 * [fd:s1d3]/s1d42/f5).
6281 	 */
6282 	const int expected_same_dir_rename_result;
6283 };
6284 
6285 /* clang-format off */
6286 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d1_mount1_src_parent) {
6287 	/* clang-format on */
6288 	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
6289 			LANDLOCK_ACCESS_FS_READ_FILE |
6290 			LANDLOCK_ACCESS_FS_EXECUTE |
6291 			LANDLOCK_ACCESS_FS_MAKE_REG,
6292 	.expected_read_result = EACCES,
6293 	.expected_same_dir_rename_result = EACCES,
6294 	.expected_rename_result = EACCES,
6295 	.expected_exchange_result = EACCES,
6296 };
6297 
6298 /* clang-format off */
6299 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_refer) {
6300 	/* clang-format on */
6301 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6302 	.expected_read_result = 0,
6303 	.expected_same_dir_rename_result = EACCES,
6304 	.expected_rename_result = EACCES,
6305 	.expected_exchange_result = EACCES,
6306 };
6307 
6308 /* clang-format off */
6309 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_create) {
6310 	/* clang-format on */
6311 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
6312 			LANDLOCK_ACCESS_FS_MAKE_REG,
6313 	.expected_read_result = 0,
6314 	.expected_same_dir_rename_result = 0,
6315 	.expected_rename_result = EXDEV,
6316 	.expected_exchange_result = EXDEV,
6317 };
6318 
6319 /* clang-format off */
6320 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_rename) {
6321 	/* clang-format on */
6322 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6323 	.expected_read_result = EACCES,
6324 	.expected_same_dir_rename_result = 0,
6325 	.expected_rename_result = 0,
6326 	.expected_exchange_result = 0,
6327 };
6328 
6329 /* clang-format off */
6330 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_refer) {
6331 	/* clang-format on */
6332 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6333 	.expected_read_result = 0,
6334 	.expected_same_dir_rename_result = EACCES,
6335 	.expected_rename_result = EACCES,
6336 	.expected_exchange_result = EACCES,
6337 };
6338 
6339 /* clang-format off */
6340 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_create) {
6341 	/* clang-format on */
6342 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_READ_FILE |
6343 			LANDLOCK_ACCESS_FS_MAKE_REG,
6344 	.expected_read_result = 0,
6345 	.expected_same_dir_rename_result = 0,
6346 	.expected_rename_result = EXDEV,
6347 	.expected_exchange_result = EXDEV,
6348 };
6349 
6350 /* clang-format off */
6351 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_rename) {
6352 	/* clang-format on */
6353 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6354 	.expected_read_result = EACCES,
6355 	.expected_same_dir_rename_result = 0,
6356 	.expected_rename_result = 0,
6357 	.expected_exchange_result = 0,
6358 };
6359 
6360 /* clang-format off */
6361 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_full) {
6362 	/* clang-format on */
6363 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER |
6364 			LANDLOCK_ACCESS_FS_READ_FILE |
6365 			LANDLOCK_ACCESS_FS_EXECUTE |
6366 			LANDLOCK_ACCESS_FS_MAKE_REG,
6367 	.expected_read_result = 0,
6368 	.expected_same_dir_rename_result = 0,
6369 	.expected_rename_result = 0,
6370 	.expected_exchange_result = 0,
6371 };
6372 
6373 /* clang-format off */
6374 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d1_mount2_src_parent) {
6375 	/* clang-format on */
6376 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
6377 			LANDLOCK_ACCESS_FS_READ_FILE |
6378 			LANDLOCK_ACCESS_FS_EXECUTE |
6379 			LANDLOCK_ACCESS_FS_MAKE_REG,
6380 	.expected_read_result = EACCES,
6381 	.expected_same_dir_rename_result = EACCES,
6382 	.expected_rename_result = EACCES,
6383 	.expected_exchange_result = EACCES,
6384 };
6385 
6386 /* clang-format off */
6387 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_refer) {
6388 	/* clang-format on */
6389 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6390 	.expected_read_result = 0,
6391 	.expected_same_dir_rename_result = EACCES,
6392 	.expected_rename_result = EACCES,
6393 	.expected_exchange_result = EACCES,
6394 };
6395 
6396 /* clang-format off */
6397 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_create) {
6398 	/* clang-format on */
6399 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_READ_FILE |
6400 			LANDLOCK_ACCESS_FS_MAKE_REG,
6401 	.expected_read_result = 0,
6402 	.expected_same_dir_rename_result = 0,
6403 	.expected_rename_result = EXDEV,
6404 	.expected_exchange_result = EXDEV,
6405 };
6406 
6407 /* clang-format off */
6408 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_rename) {
6409 	/* clang-format on */
6410 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6411 	.expected_read_result = EACCES,
6412 	.expected_same_dir_rename_result = 0,
6413 	.expected_rename_result = 0,
6414 	.expected_exchange_result = 0,
6415 };
6416 
6417 /* clang-format off */
6418 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_refer) {
6419 	/* clang-format on */
6420 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6421 	.expected_read_result = 0,
6422 	.expected_same_dir_rename_result = EACCES,
6423 	.expected_rename_result = EACCES,
6424 	.expected_exchange_result = EACCES,
6425 };
6426 
6427 /* clang-format off */
6428 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_create) {
6429 	/* clang-format on */
6430 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_READ_FILE |
6431 			LANDLOCK_ACCESS_FS_MAKE_REG,
6432 	.expected_read_result = 0,
6433 	.expected_same_dir_rename_result = 0,
6434 	.expected_rename_result = EXDEV,
6435 	.expected_exchange_result = EXDEV,
6436 };
6437 
6438 /* clang-format off */
6439 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_rename) {
6440 	/* clang-format on */
6441 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6442 	.expected_read_result = EACCES,
6443 	.expected_same_dir_rename_result = 0,
6444 	.expected_rename_result = 0,
6445 	.expected_exchange_result = 0,
6446 };
6447 
6448 /* clang-format off */
6449 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d4_mount1_dst) {
6450 	/* clang-format on */
6451 	.allowed_s2d4 = LANDLOCK_ACCESS_FS_REFER |
6452 			LANDLOCK_ACCESS_FS_READ_FILE |
6453 			LANDLOCK_ACCESS_FS_EXECUTE |
6454 			LANDLOCK_ACCESS_FS_MAKE_REG,
6455 	.expected_read_result = EACCES,
6456 	.expected_same_dir_rename_result = EACCES,
6457 	.expected_rename_result = EACCES,
6458 	.expected_exchange_result = EACCES,
6459 };
6460 
6461 /* clang-format off */
6462 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_refer) {
6463 	/* clang-format on */
6464 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6465 	.expected_read_result = 0,
6466 	.expected_same_dir_rename_result = EACCES,
6467 	.expected_rename_result = EACCES,
6468 	.expected_exchange_result = EACCES,
6469 };
6470 
6471 /* clang-format off */
6472 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_create) {
6473 	/* clang-format on */
6474 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
6475 			LANDLOCK_ACCESS_FS_MAKE_REG,
6476 	.expected_read_result = 0,
6477 	.expected_same_dir_rename_result = 0,
6478 	.expected_rename_result = EXDEV,
6479 	.expected_exchange_result = EXDEV,
6480 };
6481 
6482 /* clang-format off */
6483 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_rename) {
6484 	/* clang-format on */
6485 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6486 	.expected_read_result = EACCES,
6487 	.expected_same_dir_rename_result = 0,
6488 	.expected_rename_result = 0,
6489 	.expected_exchange_result = 0,
6490 };
6491 
6492 /* clang-format off */
6493 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d2_mount1_dst) {
6494 	/* clang-format on */
6495 	.allowed_s3d2 = LANDLOCK_ACCESS_FS_REFER |
6496 			LANDLOCK_ACCESS_FS_READ_FILE |
6497 			LANDLOCK_ACCESS_FS_EXECUTE |
6498 			LANDLOCK_ACCESS_FS_MAKE_REG,
6499 	.expected_read_result = EACCES,
6500 	.expected_same_dir_rename_result = EACCES,
6501 	.expected_rename_result = EACCES,
6502 	.expected_exchange_result = EACCES,
6503 };
6504 
6505 /* clang-format off */
6506 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_refer) {
6507 	/* clang-format on */
6508 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6509 	.expected_read_result = 0,
6510 	.expected_same_dir_rename_result = EACCES,
6511 	.expected_rename_result = EACCES,
6512 	.expected_exchange_result = EACCES,
6513 };
6514 
6515 /* clang-format off */
6516 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_create) {
6517 	/* clang-format on */
6518 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
6519 			LANDLOCK_ACCESS_FS_MAKE_REG,
6520 	.expected_read_result = 0,
6521 	.expected_same_dir_rename_result = 0,
6522 	.expected_rename_result = EXDEV,
6523 	.expected_exchange_result = EXDEV,
6524 };
6525 
6526 /* clang-format off */
6527 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_rename) {
6528 	/* clang-format on */
6529 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6530 	.expected_read_result = EACCES,
6531 	.expected_same_dir_rename_result = 0,
6532 	.expected_rename_result = 0,
6533 	.expected_exchange_result = 0,
6534 };
6535 
6536 TEST_F_FORK(layout5_disconnected_branch, read_rename_exchange)
6537 {
6538 	const __u64 handled_access =
6539 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
6540 		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
6541 	const struct rule rules[] = {
6542 		{
6543 			.path = TMP_DIR "/s1d1",
6544 			.access = variant->allowed_s1d1,
6545 		},
6546 		{
6547 			.path = TMP_DIR "/s1d1/s1d2",
6548 			.access = variant->allowed_s1d2,
6549 		},
6550 		{
6551 			.path = TMP_DIR "/s1d1/s1d2/s1d3",
6552 			.access = variant->allowed_s1d3,
6553 		},
6554 		{
6555 			.path = TMP_DIR "/s2d1",
6556 			.access = variant->allowed_s2d1,
6557 		},
6558 		{
6559 			.path = TMP_DIR "/s2d1/s2d2",
6560 			.access = variant->allowed_s2d2,
6561 		},
6562 		{
6563 			.path = TMP_DIR "/s2d1/s2d2/s2d3",
6564 			.access = variant->allowed_s2d3,
6565 		},
6566 		/* s2d4_fd */
6567 		{
6568 			.path = TMP_DIR "/s3d1",
6569 			.access = variant->allowed_s3d1,
6570 		},
6571 		/* s3d2_fd */
6572 		{
6573 			.path = TMP_DIR "/s4d1",
6574 			.access = variant->allowed_s4d1,
6575 		},
6576 		{},
6577 	};
6578 	int ruleset_fd, s1d3_bind_fd;
6579 
6580 	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
6581 	ASSERT_LE(0, ruleset_fd);
6582 
6583 	/* Adds rules for the covered directories. */
6584 	if (variant->allowed_s2d4) {
6585 		ASSERT_EQ(0, landlock_add_rule(
6586 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6587 				     &(struct landlock_path_beneath_attr){
6588 					     .parent_fd = self->s2d4_fd,
6589 					     .allowed_access =
6590 						     variant->allowed_s2d4,
6591 				     },
6592 				     0));
6593 	}
6594 	EXPECT_EQ(0, close(self->s2d4_fd));
6595 
6596 	if (variant->allowed_s3d2) {
6597 		ASSERT_EQ(0, landlock_add_rule(
6598 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6599 				     &(struct landlock_path_beneath_attr){
6600 					     .parent_fd = self->s3d2_fd,
6601 					     .allowed_access =
6602 						     variant->allowed_s3d2,
6603 				     },
6604 				     0));
6605 	}
6606 	EXPECT_EQ(0, close(self->s3d2_fd));
6607 
6608 	s1d3_bind_fd = open(TMP_DIR "/s3d1/s3d2/s2d3/s2d4/s1d3",
6609 			    O_DIRECTORY | O_PATH | O_CLOEXEC);
6610 	ASSERT_LE(0, s1d3_bind_fd);
6611 
6612 	/* Disconnects and checks source and destination directories. */
6613 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
6614 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
6615 	/* Renames to make it accessible through s3d1/s1d41 */
6616 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s2d1/s2d2/s2d3",
6617 				   AT_FDCWD, TMP_DIR "/s4d1/s2d3"));
6618 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
6619 	EXPECT_EQ(ENOENT, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
6620 
6621 	enforce_ruleset(_metadata, ruleset_fd);
6622 	EXPECT_EQ(0, close(ruleset_fd));
6623 
6624 	EXPECT_EQ(variant->expected_read_result,
6625 		  test_open_rel(s1d3_bind_fd, "s1d41/f1", O_RDONLY));
6626 
6627 	EXPECT_EQ(variant->expected_rename_result,
6628 		  test_renameat(s1d3_bind_fd, "s1d41/f1", s1d3_bind_fd,
6629 				"s1d42/f1"));
6630 	EXPECT_EQ(variant->expected_exchange_result,
6631 		  test_exchangeat(s1d3_bind_fd, "s1d41/f2", s1d3_bind_fd,
6632 				  "s1d42/f3"));
6633 
6634 	EXPECT_EQ(variant->expected_same_dir_rename_result,
6635 		  test_renameat(s1d3_bind_fd, "s1d42/f4", s1d3_bind_fd,
6636 				"s1d42/f5"));
6637 }
6638 
6639 #define LOWER_BASE TMP_DIR "/lower"
6640 #define LOWER_DATA LOWER_BASE "/data"
6641 static const char lower_fl1[] = LOWER_DATA "/fl1";
6642 static const char lower_dl1[] = LOWER_DATA "/dl1";
6643 static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2";
6644 static const char lower_fo1[] = LOWER_DATA "/fo1";
6645 static const char lower_do1[] = LOWER_DATA "/do1";
6646 static const char lower_do1_fo2[] = LOWER_DATA "/do1/fo2";
6647 static const char lower_do1_fl3[] = LOWER_DATA "/do1/fl3";
6648 /* lower_pl1 is a FIFO and is deliberately not in the lists below. */
6649 static const char lower_pl1[] = LOWER_DATA "/pl1";
6650 
6651 static const char (*lower_base_files[])[] = {
6652 	&lower_fl1,
6653 	&lower_fo1,
6654 	NULL,
6655 };
6656 static const char (*lower_base_directories[])[] = {
6657 	&lower_dl1,
6658 	&lower_do1,
6659 	NULL,
6660 };
6661 static const char (*lower_sub_files[])[] = {
6662 	&lower_dl1_fl2,
6663 	&lower_do1_fo2,
6664 	&lower_do1_fl3,
6665 	NULL,
6666 };
6667 
6668 #define UPPER_BASE TMP_DIR "/upper"
6669 #define UPPER_DATA UPPER_BASE "/data"
6670 #define UPPER_WORK UPPER_BASE "/work"
6671 static const char upper_fu1[] = UPPER_DATA "/fu1";
6672 static const char upper_du1[] = UPPER_DATA "/du1";
6673 static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2";
6674 static const char upper_fo1[] = UPPER_DATA "/fo1";
6675 static const char upper_do1[] = UPPER_DATA "/do1";
6676 static const char upper_do1_fo2[] = UPPER_DATA "/do1/fo2";
6677 static const char upper_do1_fu3[] = UPPER_DATA "/do1/fu3";
6678 
6679 static const char (*upper_base_files[])[] = {
6680 	&upper_fu1,
6681 	&upper_fo1,
6682 	NULL,
6683 };
6684 static const char (*upper_base_directories[])[] = {
6685 	&upper_du1,
6686 	&upper_do1,
6687 	NULL,
6688 };
6689 static const char (*upper_sub_files[])[] = {
6690 	&upper_du1_fu2,
6691 	&upper_do1_fo2,
6692 	&upper_do1_fu3,
6693 	NULL,
6694 };
6695 
6696 #define MERGE_BASE TMP_DIR "/merge"
6697 #define MERGE_DATA MERGE_BASE "/data"
6698 static const char merge_fl1[] = MERGE_DATA "/fl1";
6699 /* merge_pl1 is a FIFO and is deliberately not in the lists below. */
6700 static const char merge_pl1[] = MERGE_DATA "/pl1";
6701 static const char merge_dl1[] = MERGE_DATA "/dl1";
6702 static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2";
6703 static const char merge_fu1[] = MERGE_DATA "/fu1";
6704 static const char merge_du1[] = MERGE_DATA "/du1";
6705 static const char merge_du1_fu2[] = MERGE_DATA "/du1/fu2";
6706 static const char merge_fo1[] = MERGE_DATA "/fo1";
6707 static const char merge_do1[] = MERGE_DATA "/do1";
6708 static const char merge_do1_fo2[] = MERGE_DATA "/do1/fo2";
6709 static const char merge_do1_fl3[] = MERGE_DATA "/do1/fl3";
6710 static const char merge_do1_fu3[] = MERGE_DATA "/do1/fu3";
6711 
6712 static const char (*merge_base_files[])[] = {
6713 	&merge_fl1,
6714 	&merge_fu1,
6715 	&merge_fo1,
6716 	NULL,
6717 };
6718 static const char (*merge_base_directories[])[] = {
6719 	&merge_dl1,
6720 	&merge_du1,
6721 	&merge_do1,
6722 	NULL,
6723 };
6724 static const char (*merge_sub_files[])[] = {
6725 	&merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2,
6726 	&merge_do1_fl3, &merge_do1_fu3, NULL,
6727 };
6728 
6729 /*
6730  * layout2_overlay hierarchy:
6731  *
6732  * tmp
6733  * ├── lower
6734  * │   └── data
6735  * │       ├── dl1
6736  * │       │   └── fl2
6737  * │       ├── do1
6738  * │       │   ├── fl3
6739  * │       │   └── fo2
6740  * │       ├── fl1
6741  * │       ├── fo1
6742  * │       └── pl1 [FIFO]
6743  * ├── merge
6744  * │   └── data
6745  * │       ├── dl1
6746  * │       │   └── fl2
6747  * │       ├── do1
6748  * │       │   ├── fl3
6749  * │       │   ├── fo2
6750  * │       │   └── fu3
6751  * │       ├── du1
6752  * │       │   └── fu2
6753  * │       ├── fl1
6754  * │       ├── fo1
6755  * │       ├── fu1
6756  * │       └── pl1 [FIFO]
6757  * └── upper
6758  *     ├── data
6759  *     │   ├── do1
6760  *     │   │   ├── fo2
6761  *     │   │   └── fu3
6762  *     │   ├── du1
6763  *     │   │   └── fu2
6764  *     │   ├── fo1
6765  *     │   └── fu1
6766  *     └── work
6767  *         └── work
6768  */
6769 
6770 FIXTURE(layout2_overlay)
6771 {
6772 	bool skip_test;
6773 };
6774 
6775 FIXTURE_SETUP(layout2_overlay)
6776 {
6777 	if (!supports_filesystem("overlay")) {
6778 		self->skip_test = true;
6779 		SKIP(return, "overlayfs is not supported (setup)");
6780 	}
6781 
6782 	prepare_layout(_metadata);
6783 
6784 	create_directory(_metadata, LOWER_BASE);
6785 	set_cap(_metadata, CAP_SYS_ADMIN);
6786 	/* Creates tmpfs mount points to get deterministic overlayfs. */
6787 	ASSERT_EQ(0, mount_opt(&mnt_tmp, LOWER_BASE));
6788 	clear_cap(_metadata, CAP_SYS_ADMIN);
6789 	create_file(_metadata, lower_fl1);
6790 	create_file(_metadata, lower_dl1_fl2);
6791 	create_file(_metadata, lower_fo1);
6792 	create_file(_metadata, lower_do1_fo2);
6793 	create_file(_metadata, lower_do1_fl3);
6794 	ASSERT_EQ(0, mknod(lower_pl1, S_IFIFO | 0600, 0));
6795 
6796 	create_directory(_metadata, UPPER_BASE);
6797 	set_cap(_metadata, CAP_SYS_ADMIN);
6798 	ASSERT_EQ(0, mount_opt(&mnt_tmp, UPPER_BASE));
6799 	clear_cap(_metadata, CAP_SYS_ADMIN);
6800 	create_file(_metadata, upper_fu1);
6801 	create_file(_metadata, upper_du1_fu2);
6802 	create_file(_metadata, upper_fo1);
6803 	create_file(_metadata, upper_do1_fo2);
6804 	create_file(_metadata, upper_do1_fu3);
6805 	ASSERT_EQ(0, mkdir(UPPER_WORK, 0700));
6806 
6807 	create_directory(_metadata, MERGE_DATA);
6808 	set_cap(_metadata, CAP_SYS_ADMIN);
6809 	set_cap(_metadata, CAP_DAC_OVERRIDE);
6810 	ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0,
6811 			   "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA
6812 			   ",workdir=" UPPER_WORK));
6813 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
6814 	clear_cap(_metadata, CAP_SYS_ADMIN);
6815 }
6816 
6817 FIXTURE_TEARDOWN_PARENT(layout2_overlay)
6818 {
6819 	if (self->skip_test)
6820 		SKIP(return, "overlayfs is not supported (teardown)");
6821 
6822 	EXPECT_EQ(0, remove_path(lower_do1_fl3));
6823 	EXPECT_EQ(0, remove_path(lower_dl1_fl2));
6824 	EXPECT_EQ(0, remove_path(lower_fl1));
6825 	EXPECT_EQ(0, remove_path(lower_do1_fo2));
6826 	EXPECT_EQ(0, remove_path(lower_fo1));
6827 	EXPECT_EQ(0, remove_path(lower_pl1));
6828 
6829 	/* umount(LOWER_BASE)) is handled by namespace lifetime. */
6830 	EXPECT_EQ(0, remove_path(LOWER_BASE));
6831 
6832 	EXPECT_EQ(0, remove_path(upper_do1_fu3));
6833 	EXPECT_EQ(0, remove_path(upper_du1_fu2));
6834 	EXPECT_EQ(0, remove_path(upper_fu1));
6835 	EXPECT_EQ(0, remove_path(upper_do1_fo2));
6836 	EXPECT_EQ(0, remove_path(upper_fo1));
6837 	EXPECT_EQ(0, remove_path(UPPER_WORK "/work"));
6838 
6839 	/* umount(UPPER_BASE)) is handled by namespace lifetime. */
6840 	EXPECT_EQ(0, remove_path(UPPER_BASE));
6841 
6842 	/* umount(MERGE_DATA)) is handled by namespace lifetime. */
6843 	EXPECT_EQ(0, remove_path(MERGE_DATA));
6844 
6845 	cleanup_layout(_metadata);
6846 }
6847 
6848 TEST_F_FORK(layout2_overlay, no_restriction)
6849 {
6850 	if (self->skip_test)
6851 		SKIP(return, "overlayfs is not supported (test)");
6852 
6853 	ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
6854 	ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
6855 	ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
6856 	ASSERT_EQ(0, test_open(lower_fo1, O_RDONLY));
6857 	ASSERT_EQ(0, test_open(lower_do1, O_RDONLY));
6858 	ASSERT_EQ(0, test_open(lower_do1_fo2, O_RDONLY));
6859 	ASSERT_EQ(0, test_open(lower_do1_fl3, O_RDONLY));
6860 
6861 	ASSERT_EQ(0, test_open(upper_fu1, O_RDONLY));
6862 	ASSERT_EQ(0, test_open(upper_du1, O_RDONLY));
6863 	ASSERT_EQ(0, test_open(upper_du1_fu2, O_RDONLY));
6864 	ASSERT_EQ(0, test_open(upper_fo1, O_RDONLY));
6865 	ASSERT_EQ(0, test_open(upper_do1, O_RDONLY));
6866 	ASSERT_EQ(0, test_open(upper_do1_fo2, O_RDONLY));
6867 	ASSERT_EQ(0, test_open(upper_do1_fu3, O_RDONLY));
6868 
6869 	ASSERT_EQ(0, test_open(merge_fl1, O_RDONLY));
6870 	ASSERT_EQ(0, test_open(merge_dl1, O_RDONLY));
6871 	ASSERT_EQ(0, test_open(merge_dl1_fl2, O_RDONLY));
6872 	ASSERT_EQ(0, test_open(merge_fu1, O_RDONLY));
6873 	ASSERT_EQ(0, test_open(merge_du1, O_RDONLY));
6874 	ASSERT_EQ(0, test_open(merge_du1_fu2, O_RDONLY));
6875 	ASSERT_EQ(0, test_open(merge_fo1, O_RDONLY));
6876 	ASSERT_EQ(0, test_open(merge_do1, O_RDONLY));
6877 	ASSERT_EQ(0, test_open(merge_do1_fo2, O_RDONLY));
6878 	ASSERT_EQ(0, test_open(merge_do1_fl3, O_RDONLY));
6879 	ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY));
6880 }
6881 
6882 #define for_each_path(path_list, path_entry, i)               \
6883 	for (i = 0, path_entry = *path_list[i]; path_list[i]; \
6884 	     path_entry = *path_list[++i])
6885 
6886 TEST_F_FORK(layout2_overlay, same_content_different_file)
6887 {
6888 	/* Sets access right on parent directories of both layers. */
6889 	const struct rule layer1_base[] = {
6890 		{
6891 			.path = LOWER_BASE,
6892 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6893 		},
6894 		{
6895 			.path = UPPER_BASE,
6896 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6897 		},
6898 		{
6899 			.path = MERGE_BASE,
6900 			.access = ACCESS_RW,
6901 		},
6902 		{},
6903 	};
6904 	const struct rule layer2_data[] = {
6905 		{
6906 			.path = LOWER_DATA,
6907 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6908 		},
6909 		{
6910 			.path = UPPER_DATA,
6911 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6912 		},
6913 		{
6914 			.path = MERGE_DATA,
6915 			.access = ACCESS_RW,
6916 		},
6917 		{},
6918 	};
6919 	/* Sets access right on directories inside both layers. */
6920 	const struct rule layer3_subdirs[] = {
6921 		{
6922 			.path = lower_dl1,
6923 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6924 		},
6925 		{
6926 			.path = lower_do1,
6927 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6928 		},
6929 		{
6930 			.path = upper_du1,
6931 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6932 		},
6933 		{
6934 			.path = upper_do1,
6935 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6936 		},
6937 		{
6938 			.path = merge_dl1,
6939 			.access = ACCESS_RW,
6940 		},
6941 		{
6942 			.path = merge_du1,
6943 			.access = ACCESS_RW,
6944 		},
6945 		{
6946 			.path = merge_do1,
6947 			.access = ACCESS_RW,
6948 		},
6949 		{},
6950 	};
6951 	/* Tighten access rights to the files. */
6952 	const struct rule layer4_files[] = {
6953 		{
6954 			.path = lower_dl1_fl2,
6955 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6956 		},
6957 		{
6958 			.path = lower_do1_fo2,
6959 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6960 		},
6961 		{
6962 			.path = lower_do1_fl3,
6963 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6964 		},
6965 		{
6966 			.path = upper_du1_fu2,
6967 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6968 		},
6969 		{
6970 			.path = upper_do1_fo2,
6971 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6972 		},
6973 		{
6974 			.path = upper_do1_fu3,
6975 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6976 		},
6977 		{
6978 			.path = merge_dl1_fl2,
6979 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6980 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6981 		},
6982 		{
6983 			.path = merge_du1_fu2,
6984 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6985 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6986 		},
6987 		{
6988 			.path = merge_do1_fo2,
6989 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6990 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6991 		},
6992 		{
6993 			.path = merge_do1_fl3,
6994 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6995 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6996 		},
6997 		{
6998 			.path = merge_do1_fu3,
6999 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
7000 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
7001 		},
7002 		{},
7003 	};
7004 	const struct rule layer5_merge_only[] = {
7005 		{
7006 			.path = MERGE_DATA,
7007 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
7008 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
7009 		},
7010 		{},
7011 	};
7012 	size_t i;
7013 	const char *path_entry;
7014 
7015 	if (self->skip_test)
7016 		SKIP(return, "overlayfs is not supported (test)");
7017 
7018 	/* Sets rules on base directories (i.e. outside overlay scope). */
7019 	enforce_fs(_metadata, ACCESS_RW, layer1_base);
7020 
7021 	/* Checks lower layer. */
7022 	for_each_path(lower_base_files, path_entry, i) {
7023 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7024 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7025 	}
7026 	for_each_path(lower_base_directories, path_entry, i) {
7027 		ASSERT_EQ(EACCES,
7028 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7029 	}
7030 	for_each_path(lower_sub_files, path_entry, i) {
7031 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7032 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7033 	}
7034 	/* Checks upper layer. */
7035 	for_each_path(upper_base_files, path_entry, i) {
7036 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7037 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7038 	}
7039 	for_each_path(upper_base_directories, path_entry, i) {
7040 		ASSERT_EQ(EACCES,
7041 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7042 	}
7043 	for_each_path(upper_sub_files, path_entry, i) {
7044 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7045 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7046 	}
7047 	/*
7048 	 * Checks that access rights are independent from the lower and upper
7049 	 * layers: write access to upper files viewed through the merge point
7050 	 * is still allowed, and write access to lower file viewed (and copied)
7051 	 * through the merge point is still allowed.
7052 	 */
7053 	for_each_path(merge_base_files, path_entry, i) {
7054 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7055 	}
7056 	for_each_path(merge_base_directories, path_entry, i) {
7057 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7058 	}
7059 	for_each_path(merge_sub_files, path_entry, i) {
7060 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7061 	}
7062 
7063 	/* Sets rules on data directories (i.e. inside overlay scope). */
7064 	enforce_fs(_metadata, ACCESS_RW, layer2_data);
7065 
7066 	/* Checks merge. */
7067 	for_each_path(merge_base_files, path_entry, i) {
7068 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7069 	}
7070 	for_each_path(merge_base_directories, path_entry, i) {
7071 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7072 	}
7073 	for_each_path(merge_sub_files, path_entry, i) {
7074 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7075 	}
7076 
7077 	/* Same checks with tighter rules. */
7078 	enforce_fs(_metadata, ACCESS_RW, layer3_subdirs);
7079 
7080 	/* Checks changes for lower layer. */
7081 	for_each_path(lower_base_files, path_entry, i) {
7082 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7083 	}
7084 	/* Checks changes for upper layer. */
7085 	for_each_path(upper_base_files, path_entry, i) {
7086 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7087 	}
7088 	/* Checks all merge accesses. */
7089 	for_each_path(merge_base_files, path_entry, i) {
7090 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7091 	}
7092 	for_each_path(merge_base_directories, path_entry, i) {
7093 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7094 	}
7095 	for_each_path(merge_sub_files, path_entry, i) {
7096 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7097 	}
7098 
7099 	/* Sets rules directly on overlayed files. */
7100 	enforce_fs(_metadata, ACCESS_RW, layer4_files);
7101 
7102 	/* Checks unchanged accesses on lower layer. */
7103 	for_each_path(lower_sub_files, path_entry, i) {
7104 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7105 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7106 	}
7107 	/* Checks unchanged accesses on upper layer. */
7108 	for_each_path(upper_sub_files, path_entry, i) {
7109 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7110 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7111 	}
7112 	/* Checks all merge accesses. */
7113 	for_each_path(merge_base_files, path_entry, i) {
7114 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7115 	}
7116 	for_each_path(merge_base_directories, path_entry, i) {
7117 		ASSERT_EQ(EACCES,
7118 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7119 	}
7120 	for_each_path(merge_sub_files, path_entry, i) {
7121 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7122 	}
7123 
7124 	/* Only allows access to the merge hierarchy. */
7125 	enforce_fs(_metadata, ACCESS_RW, layer5_merge_only);
7126 
7127 	/* Checks new accesses on lower layer. */
7128 	for_each_path(lower_sub_files, path_entry, i) {
7129 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7130 	}
7131 	/* Checks new accesses on upper layer. */
7132 	for_each_path(upper_sub_files, path_entry, i) {
7133 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7134 	}
7135 	/* Checks all merge accesses. */
7136 	for_each_path(merge_base_files, path_entry, i) {
7137 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7138 	}
7139 	for_each_path(merge_base_directories, path_entry, i) {
7140 		ASSERT_EQ(EACCES,
7141 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7142 	}
7143 	for_each_path(merge_sub_files, path_entry, i) {
7144 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7145 	}
7146 }
7147 
7148 TEST_F_FORK(layout2_overlay, rename_in_overlay_without_make_reg)
7149 {
7150 	const char *const merge_pl1_renamed = MERGE_DATA "/pl1_renamed";
7151 
7152 	if (self->skip_test)
7153 		SKIP(return, "overlayfs is not supported (test)");
7154 
7155 	/*
7156 	 * merge_pl1 is a FIFO which only exists in the lower layer.  Before
7157 	 * the rename, the upper layer has no entry under this name.
7158 	 */
7159 	ASSERT_TRUE(is_fifo(merge_pl1));
7160 	ASSERT_TRUE(is_missing(UPPER_DATA "/pl1"));
7161 
7162 	/* MAKE_REG is restricted, but MAKE_FIFO is not. */
7163 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, NULL);
7164 
7165 	/*
7166 	 * Rename the FIFO through OverlayFS.  merge_pl1 originates from the
7167 	 * lower layer, so this triggers a copy-up and creates the whiteout in
7168 	 * the upper layer to hide the lower layer FIFO file.  Even though
7169 	 * MAKE_REG is restricted, the rename on the OverlayFS works.
7170 	 */
7171 	EXPECT_EQ(0, rename(merge_pl1, merge_pl1_renamed));
7172 
7173 	/* Check that the rename worked. */
7174 	EXPECT_TRUE(is_fifo(merge_pl1_renamed));
7175 	EXPECT_TRUE(is_missing(merge_pl1));
7176 
7177 	/*
7178 	 * Check that the whiteout object was created on the underlying "upper"
7179 	 * filesystem during the rename.  This is OK because the whiteout object
7180 	 * was created by OverlayFS, not by the calling task.
7181 	 */
7182 	EXPECT_TRUE(is_whiteout(UPPER_DATA "/pl1"));
7183 }
7184 
7185 FIXTURE(layout3_fs)
7186 {
7187 	bool has_created_dir;
7188 	bool has_created_file;
7189 	bool skip_test;
7190 };
7191 
7192 FIXTURE_VARIANT(layout3_fs)
7193 {
7194 	const struct mnt_opt mnt;
7195 	const char *const file_path;
7196 	unsigned int cwd_fs_magic;
7197 };
7198 
7199 /* clang-format off */
7200 FIXTURE_VARIANT_ADD(layout3_fs, tmpfs) {
7201 	/* clang-format on */
7202 	.mnt = {
7203 		.type = "tmpfs",
7204 		.data = MNT_TMP_DATA,
7205 	},
7206 	.file_path = file1_s1d1,
7207 };
7208 
7209 FIXTURE_VARIANT_ADD(layout3_fs, ramfs) {
7210 	.mnt = {
7211 		.type = "ramfs",
7212 		.data = "mode=700",
7213 	},
7214 	.file_path = TMP_DIR "/dir/file",
7215 };
7216 
7217 FIXTURE_VARIANT_ADD(layout3_fs, cgroup2) {
7218 	.mnt = {
7219 		.type = "cgroup2",
7220 	},
7221 	.file_path = TMP_DIR "/test/cgroup.procs",
7222 };
7223 
7224 FIXTURE_VARIANT_ADD(layout3_fs, proc) {
7225 	.mnt = {
7226 		.type = "proc",
7227 	},
7228 	.file_path = TMP_DIR "/self/status",
7229 };
7230 
7231 FIXTURE_VARIANT_ADD(layout3_fs, sysfs) {
7232 	.mnt = {
7233 		.type = "sysfs",
7234 	},
7235 	.file_path = TMP_DIR "/kernel/notes",
7236 };
7237 
7238 FIXTURE_VARIANT_ADD(layout3_fs, hostfs) {
7239 	.mnt = {
7240 		.source = TMP_DIR,
7241 		.flags = MS_BIND,
7242 	},
7243 	.file_path = TMP_DIR "/dir/file",
7244 	.cwd_fs_magic = HOSTFS_SUPER_MAGIC,
7245 };
7246 
7247 static char *dirname_alloc(const char *path)
7248 {
7249 	char *dup;
7250 
7251 	if (!path)
7252 		return NULL;
7253 
7254 	dup = strdup(path);
7255 	if (!dup)
7256 		return NULL;
7257 
7258 	return dirname(dup);
7259 }
7260 
7261 FIXTURE_SETUP(layout3_fs)
7262 {
7263 	struct stat statbuf;
7264 	char *dir_path = dirname_alloc(variant->file_path);
7265 
7266 	if (!supports_filesystem(variant->mnt.type) ||
7267 	    !cwd_matches_fs(variant->cwd_fs_magic)) {
7268 		self->skip_test = true;
7269 		SKIP(return, "this filesystem is not supported (setup)");
7270 	}
7271 
7272 	prepare_layout_opt(_metadata, &variant->mnt);
7273 
7274 	/* Creates directory when required. */
7275 	if (stat(dir_path, &statbuf)) {
7276 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7277 		EXPECT_EQ(0, mkdir(dir_path, 0700))
7278 		{
7279 			TH_LOG("Failed to create directory \"%s\": %s",
7280 			       dir_path, strerror(errno));
7281 		}
7282 		self->has_created_dir = true;
7283 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7284 	}
7285 
7286 	/* Creates file when required. */
7287 	if (stat(variant->file_path, &statbuf)) {
7288 		int fd;
7289 
7290 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7291 		fd = creat(variant->file_path, 0600);
7292 		EXPECT_LE(0, fd)
7293 		{
7294 			TH_LOG("Failed to create file \"%s\": %s",
7295 			       variant->file_path, strerror(errno));
7296 		}
7297 		EXPECT_EQ(0, close(fd));
7298 		self->has_created_file = true;
7299 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7300 	}
7301 
7302 	free(dir_path);
7303 }
7304 
7305 FIXTURE_TEARDOWN_PARENT(layout3_fs)
7306 {
7307 	if (self->skip_test)
7308 		SKIP(return, "this filesystem is not supported (teardown)");
7309 
7310 	if (self->has_created_file) {
7311 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7312 		/*
7313 		 * Don't check for error because the file might already
7314 		 * have been removed (cf. release_inode test).
7315 		 */
7316 		unlink(variant->file_path);
7317 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7318 	}
7319 
7320 	if (self->has_created_dir) {
7321 		char *dir_path = dirname_alloc(variant->file_path);
7322 
7323 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7324 		/*
7325 		 * Don't check for error because the directory might already
7326 		 * have been removed (cf. release_inode test).
7327 		 */
7328 		rmdir(dir_path);
7329 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7330 		free(dir_path);
7331 	}
7332 
7333 	cleanup_layout(_metadata);
7334 }
7335 
7336 static void layer3_fs_tag_inode(struct __test_metadata *const _metadata,
7337 				FIXTURE_DATA(layout3_fs) * self,
7338 				const FIXTURE_VARIANT(layout3_fs) * variant,
7339 				const char *const rule_path)
7340 {
7341 	const struct rule layer1_allow_read_file[] = {
7342 		{
7343 			.path = rule_path,
7344 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
7345 		},
7346 		{},
7347 	};
7348 	const char *const dev_null_path = "/dev/null";
7349 
7350 	if (self->skip_test)
7351 		SKIP(return, "this filesystem is not supported (test)");
7352 
7353 	/* Checks without Landlock. */
7354 	EXPECT_EQ(0, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7355 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7356 
7357 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
7358 		   layer1_allow_read_file);
7359 
7360 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7361 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7362 
7363 	/* Forbids directory reading. */
7364 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, NULL);
7365 
7366 	/* Checks with Landlock and forbidden access. */
7367 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7368 	EXPECT_EQ(EACCES, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7369 }
7370 
7371 /* Matrix of tests to check file hierarchy evaluation. */
7372 
7373 TEST_F_FORK(layout3_fs, tag_inode_dir_parent)
7374 {
7375 	/* The current directory must not be the root for this test. */
7376 	layer3_fs_tag_inode(_metadata, self, variant, ".");
7377 }
7378 
7379 TEST_F_FORK(layout3_fs, tag_inode_dir_mnt)
7380 {
7381 	layer3_fs_tag_inode(_metadata, self, variant, TMP_DIR);
7382 }
7383 
7384 TEST_F_FORK(layout3_fs, tag_inode_dir_child)
7385 {
7386 	char *dir_path = dirname_alloc(variant->file_path);
7387 
7388 	layer3_fs_tag_inode(_metadata, self, variant, dir_path);
7389 	free(dir_path);
7390 }
7391 
7392 TEST_F_FORK(layout3_fs, tag_inode_file)
7393 {
7394 	layer3_fs_tag_inode(_metadata, self, variant, variant->file_path);
7395 }
7396 
7397 /* Light version of layout1.release_inodes */
7398 TEST_F_FORK(layout3_fs, release_inodes)
7399 {
7400 	const struct rule layer1[] = {
7401 		{
7402 			.path = TMP_DIR,
7403 			.access = LANDLOCK_ACCESS_FS_READ_DIR,
7404 		},
7405 		{},
7406 	};
7407 	int ruleset_fd;
7408 
7409 	if (self->skip_test)
7410 		SKIP(return, "this filesystem is not supported (test)");
7411 
7412 	/* Clean up for the teardown to not fail. */
7413 	if (self->has_created_file)
7414 		EXPECT_EQ(0, remove_path(variant->file_path));
7415 
7416 	if (self->has_created_dir) {
7417 		char *dir_path = dirname_alloc(variant->file_path);
7418 
7419 		/* Don't check for error because of cgroup specificities. */
7420 		remove_path(dir_path);
7421 		free(dir_path);
7422 	}
7423 
7424 	ruleset_fd =
7425 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
7426 
7427 	/* Unmount the filesystem while it is being used by a ruleset. */
7428 	set_cap(_metadata, CAP_SYS_ADMIN);
7429 	ASSERT_EQ(0, umount(TMP_DIR));
7430 	clear_cap(_metadata, CAP_SYS_ADMIN);
7431 
7432 	/* Replaces with a new mount point to simplify FIXTURE_TEARDOWN. */
7433 	set_cap(_metadata, CAP_SYS_ADMIN);
7434 	ASSERT_EQ(0, mount_opt(&mnt_tmp, TMP_DIR));
7435 	clear_cap(_metadata, CAP_SYS_ADMIN);
7436 
7437 	enforce_ruleset(_metadata, ruleset_fd);
7438 	ASSERT_EQ(0, close(ruleset_fd));
7439 
7440 	/* Checks that access to the new mount point is denied. */
7441 	ASSERT_EQ(EACCES, test_open(TMP_DIR, O_RDONLY));
7442 }
7443 
7444 static int matches_log_fs_extra(struct __test_metadata *const _metadata,
7445 				int audit_fd, const char *const blockers,
7446 				const char *const path, const char *const extra)
7447 {
7448 	static const char log_template[] = REGEX_LANDLOCK_PREFIX
7449 		" blockers=fs\\.%s path=\"%s\" dev=\"[^\"]\\+\" ino=[0-9]\\+$";
7450 	char *absolute_path = NULL;
7451 	size_t log_match_remaining = sizeof(log_template) + strlen(blockers) +
7452 				     PATH_MAX * 2 +
7453 				     (extra ? strlen(extra) : 0) + 1;
7454 	char log_match[log_match_remaining];
7455 	char *log_match_cursor = log_match;
7456 	size_t chunk_len;
7457 
7458 	chunk_len = snprintf(log_match_cursor, log_match_remaining,
7459 			     REGEX_LANDLOCK_PREFIX " blockers=%s path=\"",
7460 			     blockers);
7461 	if (chunk_len < 0 || chunk_len >= log_match_remaining)
7462 		return -E2BIG;
7463 
7464 	/*
7465 	 * It is assumed that absolute_path does not contain control
7466 	 * characters nor spaces, see audit_string_contains_control().
7467 	 */
7468 	absolute_path = realpath(path, NULL);
7469 	if (!absolute_path)
7470 		return -errno;
7471 
7472 	log_match_remaining -= chunk_len;
7473 	log_match_cursor += chunk_len;
7474 	log_match_cursor = regex_escape(absolute_path, log_match_cursor,
7475 					log_match_remaining);
7476 	free(absolute_path);
7477 	if (log_match_cursor < 0)
7478 		return (long long)log_match_cursor;
7479 
7480 	log_match_remaining -= log_match_cursor - log_match;
7481 	chunk_len = snprintf(log_match_cursor, log_match_remaining,
7482 			     "\" dev=\"[^\"]\\+\" ino=[0-9]\\+%s$",
7483 			     extra ?: "");
7484 	if (chunk_len < 0 || chunk_len >= log_match_remaining)
7485 		return -E2BIG;
7486 
7487 	return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
7488 				  NULL);
7489 }
7490 
7491 static int matches_log_fs(struct __test_metadata *const _metadata, int audit_fd,
7492 			  const char *const blockers, const char *const path)
7493 {
7494 	return matches_log_fs_extra(_metadata, audit_fd, blockers, path, NULL);
7495 }
7496 
7497 FIXTURE(audit_layout1)
7498 {
7499 	struct audit_filter audit_filter;
7500 	int audit_fd;
7501 };
7502 
7503 FIXTURE_SETUP(audit_layout1)
7504 {
7505 	prepare_layout(_metadata);
7506 
7507 	create_layout1(_metadata);
7508 
7509 	set_cap(_metadata, CAP_AUDIT_CONTROL);
7510 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
7511 	EXPECT_LE(0, self->audit_fd);
7512 	disable_caps(_metadata);
7513 }
7514 
7515 FIXTURE_TEARDOWN_PARENT(audit_layout1)
7516 {
7517 	remove_layout1(_metadata);
7518 
7519 	cleanup_layout(_metadata);
7520 
7521 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
7522 }
7523 
7524 TEST_F(audit_layout1, execute_make)
7525 {
7526 	struct audit_records records;
7527 
7528 	copy_file(_metadata, bin_true, file1_s1d1);
7529 	test_execute(_metadata, 0, file1_s1d1);
7530 	test_check_exec(_metadata, 0, file1_s1d1);
7531 
7532 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, NULL);
7533 
7534 	test_execute(_metadata, EACCES, file1_s1d1);
7535 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.execute",
7536 				    file1_s1d1));
7537 	test_check_exec(_metadata, EACCES, file1_s1d1);
7538 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.execute",
7539 				    file1_s1d1));
7540 
7541 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7542 	EXPECT_EQ(0, records.access);
7543 	EXPECT_EQ(0, records.domain);
7544 }
7545 
7546 /*
7547  * Using a set of handled/denied access rights make it possible to check that
7548  * only the blocked ones are logged.
7549  */
7550 
7551 TEST_F(audit_layout1, execute_read)
7552 {
7553 	struct audit_records records;
7554 
7555 	copy_file(_metadata, bin_true, file1_s1d1);
7556 	test_execute(_metadata, 0, file1_s1d1);
7557 	test_check_exec(_metadata, 0, file1_s1d1);
7558 
7559 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7560 
7561 	/*
7562 	 * The only difference with the previous audit_layout1.execute_read test is
7563 	 * the extra ",fs\\.read_file" blocked by the executable file.
7564 	 */
7565 	test_execute(_metadata, EACCES, file1_s1d1);
7566 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7567 				    "fs\\.execute,fs\\.read_file", file1_s1d1));
7568 	test_check_exec(_metadata, EACCES, file1_s1d1);
7569 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7570 				    "fs\\.execute,fs\\.read_file", file1_s1d1));
7571 
7572 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7573 	EXPECT_EQ(0, records.access);
7574 	EXPECT_EQ(0, records.domain);
7575 }
7576 
7577 TEST_F(audit_layout1, write_file)
7578 {
7579 	struct audit_records records;
7580 
7581 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7582 
7583 	EXPECT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
7584 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7585 				    "fs\\.write_file", file1_s1d1));
7586 
7587 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7588 	EXPECT_EQ(0, records.access);
7589 	EXPECT_EQ(1, records.domain);
7590 }
7591 
7592 TEST_F(audit_layout1, read_file)
7593 {
7594 	struct audit_records records;
7595 
7596 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7597 
7598 	EXPECT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
7599 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.read_file",
7600 				    file1_s1d1));
7601 
7602 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7603 	EXPECT_EQ(0, records.access);
7604 	EXPECT_EQ(1, records.domain);
7605 }
7606 
7607 TEST_F(audit_layout1, read_dir)
7608 {
7609 	struct audit_records records;
7610 
7611 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7612 
7613 	EXPECT_EQ(EACCES, test_open(dir_s1d1, O_DIRECTORY));
7614 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.read_dir",
7615 				    dir_s1d1));
7616 
7617 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7618 	EXPECT_EQ(0, records.access);
7619 	EXPECT_EQ(1, records.domain);
7620 }
7621 
7622 TEST_F(audit_layout1, remove_dir)
7623 {
7624 	struct audit_records records;
7625 
7626 	EXPECT_EQ(0, unlink(file1_s1d3));
7627 	EXPECT_EQ(0, unlink(file2_s1d3));
7628 
7629 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7630 
7631 	EXPECT_EQ(-1, rmdir(dir_s1d3));
7632 	EXPECT_EQ(EACCES, errno);
7633 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7634 				    "fs\\.remove_dir", dir_s1d2));
7635 
7636 	EXPECT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
7637 	EXPECT_EQ(EACCES, errno);
7638 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7639 				    "fs\\.remove_dir", dir_s1d2));
7640 
7641 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7642 	EXPECT_EQ(0, records.access);
7643 	EXPECT_EQ(0, records.domain);
7644 }
7645 
7646 TEST_F(audit_layout1, remove_file)
7647 {
7648 	struct audit_records records;
7649 
7650 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7651 
7652 	EXPECT_EQ(-1, unlink(file1_s1d3));
7653 	EXPECT_EQ(EACCES, errno);
7654 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7655 				    "fs\\.remove_file", dir_s1d3));
7656 
7657 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7658 	EXPECT_EQ(0, records.access);
7659 	EXPECT_EQ(1, records.domain);
7660 }
7661 
7662 TEST_F(audit_layout1, make_char)
7663 {
7664 	struct audit_records records;
7665 
7666 	EXPECT_EQ(0, unlink(file1_s1d3));
7667 
7668 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7669 
7670 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFCHR | 0644, makedev(7, 0)));
7671 	EXPECT_EQ(EACCES, errno);
7672 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_char",
7673 				    dir_s1d3));
7674 
7675 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7676 	EXPECT_EQ(0, records.access);
7677 	EXPECT_EQ(1, records.domain);
7678 }
7679 
7680 TEST_F(audit_layout1, make_whiteout)
7681 {
7682 	struct audit_records records;
7683 
7684 	EXPECT_EQ(0, unlink(file1_s1d3));
7685 
7686 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7687 
7688 	/* Whiteout creation is denied and logged as fs.make_reg. */
7689 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFCHR | 0644, makedev(0, 0)));
7690 	EXPECT_EQ(EACCES, errno);
7691 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_reg",
7692 				    dir_s1d3));
7693 
7694 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7695 	EXPECT_EQ(0, records.access);
7696 	EXPECT_EQ(1, records.domain);
7697 }
7698 
7699 TEST_F(audit_layout1, make_dir)
7700 {
7701 	struct audit_records records;
7702 
7703 	EXPECT_EQ(0, unlink(file1_s1d3));
7704 
7705 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7706 
7707 	EXPECT_EQ(-1, mkdir(file1_s1d3, 0755));
7708 	EXPECT_EQ(EACCES, errno);
7709 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_dir",
7710 				    dir_s1d3));
7711 
7712 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7713 	EXPECT_EQ(0, records.access);
7714 	EXPECT_EQ(1, records.domain);
7715 }
7716 
7717 TEST_F(audit_layout1, make_reg)
7718 {
7719 	struct audit_records records;
7720 
7721 	EXPECT_EQ(0, unlink(file1_s1d3));
7722 
7723 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7724 
7725 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFREG | 0644, 0));
7726 	EXPECT_EQ(EACCES, errno);
7727 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_reg",
7728 				    dir_s1d3));
7729 
7730 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7731 	EXPECT_EQ(0, records.access);
7732 	EXPECT_EQ(1, records.domain);
7733 }
7734 
7735 TEST_F(audit_layout1, make_sock)
7736 {
7737 	struct audit_records records;
7738 
7739 	EXPECT_EQ(0, unlink(file1_s1d3));
7740 
7741 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7742 
7743 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFSOCK | 0644, 0));
7744 	EXPECT_EQ(EACCES, errno);
7745 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_sock",
7746 				    dir_s1d3));
7747 
7748 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7749 	EXPECT_EQ(0, records.access);
7750 	EXPECT_EQ(1, records.domain);
7751 }
7752 
7753 TEST_F(audit_layout1, make_fifo)
7754 {
7755 	struct audit_records records;
7756 
7757 	EXPECT_EQ(0, unlink(file1_s1d3));
7758 
7759 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7760 
7761 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFIFO | 0644, 0));
7762 	EXPECT_EQ(EACCES, errno);
7763 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_fifo",
7764 				    dir_s1d3));
7765 
7766 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7767 	EXPECT_EQ(0, records.access);
7768 	EXPECT_EQ(1, records.domain);
7769 }
7770 
7771 TEST_F(audit_layout1, make_block)
7772 {
7773 	struct audit_records records;
7774 
7775 	EXPECT_EQ(0, unlink(file1_s1d3));
7776 
7777 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7778 
7779 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFBLK | 0644, 0));
7780 	EXPECT_EQ(EACCES, errno);
7781 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7782 				    "fs\\.make_block", dir_s1d3));
7783 
7784 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7785 	EXPECT_EQ(0, records.access);
7786 	EXPECT_EQ(1, records.domain);
7787 }
7788 
7789 TEST_F(audit_layout1, make_sym)
7790 {
7791 	struct audit_records records;
7792 
7793 	EXPECT_EQ(0, unlink(file1_s1d3));
7794 
7795 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7796 
7797 	EXPECT_EQ(-1, symlink("target", file1_s1d3));
7798 	EXPECT_EQ(EACCES, errno);
7799 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_sym",
7800 				    dir_s1d3));
7801 
7802 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7803 	EXPECT_EQ(0, records.access);
7804 	EXPECT_EQ(1, records.domain);
7805 }
7806 
7807 TEST_F(audit_layout1, refer_handled)
7808 {
7809 	struct audit_records records;
7810 
7811 	EXPECT_EQ(0, unlink(file1_s1d3));
7812 
7813 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REFER, NULL);
7814 
7815 	EXPECT_EQ(-1, link(file1_s1d1, file1_s1d3));
7816 	EXPECT_EQ(EXDEV, errno);
7817 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7818 				    dir_s1d1));
7819 	EXPECT_EQ(0,
7820 		  matches_log_domain_allocated(self->audit_fd, getpid(), NULL));
7821 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7822 				    dir_s1d3));
7823 
7824 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7825 	EXPECT_EQ(0, records.access);
7826 	EXPECT_EQ(0, records.domain);
7827 }
7828 
7829 TEST_F(audit_layout1, refer_make)
7830 {
7831 	struct audit_records records;
7832 
7833 	EXPECT_EQ(0, unlink(file1_s1d3));
7834 
7835 	enforce_fs(_metadata,
7836 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
7837 		   NULL);
7838 
7839 	EXPECT_EQ(-1, link(file1_s1d1, file1_s1d3));
7840 	EXPECT_EQ(EACCES, errno);
7841 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7842 				    dir_s1d1));
7843 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7844 				    "fs\\.make_reg,fs\\.refer", dir_s1d3));
7845 
7846 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7847 	EXPECT_EQ(0, records.access);
7848 	EXPECT_EQ(0, records.domain);
7849 }
7850 
7851 TEST_F(audit_layout1, refer_rename)
7852 {
7853 	struct audit_records records;
7854 
7855 	EXPECT_EQ(0, unlink(file1_s1d3));
7856 
7857 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7858 
7859 	EXPECT_EQ(EACCES, test_rename(file1_s1d2, file1_s2d3));
7860 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7861 				    "fs\\.remove_file,fs\\.refer", dir_s1d2));
7862 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7863 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7864 				    dir_s2d3));
7865 
7866 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7867 	EXPECT_EQ(0, records.access);
7868 	EXPECT_EQ(0, records.domain);
7869 }
7870 
7871 TEST_F(audit_layout1, refer_exchange)
7872 {
7873 	struct audit_records records;
7874 
7875 	EXPECT_EQ(0, unlink(file1_s1d3));
7876 
7877 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7878 
7879 	/*
7880 	 * The only difference with the previous audit_layout1.refer_rename test is
7881 	 * the extra ",fs\\.make_reg" blocked by the source directory.
7882 	 */
7883 	EXPECT_EQ(EACCES, test_exchange(file1_s1d2, file1_s2d3));
7884 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7885 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7886 				    dir_s1d2));
7887 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7888 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7889 				    dir_s2d3));
7890 
7891 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7892 	EXPECT_EQ(0, records.access);
7893 	EXPECT_EQ(0, records.domain);
7894 }
7895 
7896 /*
7897  * This test checks that the audit record is correctly generated when the
7898  * operation is only partially denied.  This is the case for rename(2) when the
7899  * source file is allowed to be referenced but the destination directory is not.
7900  *
7901  * This is also a regression test for commit d617f0d72d80 ("landlock: Optimize
7902  * file path walks and prepare for audit support") and commit 058518c20920
7903  * ("landlock: Align partial refer access checks with final ones").
7904  */
7905 TEST_F(audit_layout1, refer_rename_half)
7906 {
7907 	struct audit_records records;
7908 	const struct rule layer1[] = {
7909 		{
7910 			.path = dir_s2d2,
7911 			.access = LANDLOCK_ACCESS_FS_REFER,
7912 		},
7913 		{},
7914 	};
7915 
7916 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REFER, layer1);
7917 
7918 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d3));
7919 	ASSERT_EQ(EXDEV, errno);
7920 
7921 	/* Only half of the request is denied. */
7922 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7923 				    dir_s1d1));
7924 
7925 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7926 	EXPECT_EQ(0, records.access);
7927 	EXPECT_EQ(1, records.domain);
7928 }
7929 
7930 TEST_F(audit_layout1, truncate)
7931 {
7932 	struct audit_records records;
7933 
7934 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7935 
7936 	EXPECT_EQ(-1, truncate(file1_s1d3, 0));
7937 	EXPECT_EQ(EACCES, errno);
7938 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.truncate",
7939 				    file1_s1d3));
7940 
7941 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7942 	EXPECT_EQ(0, records.access);
7943 	EXPECT_EQ(1, records.domain);
7944 }
7945 
7946 TEST_F(audit_layout1, ioctl_dev)
7947 {
7948 	struct audit_records records;
7949 	int fd;
7950 
7951 	enforce_fs(_metadata, ACCESS_ALL & ~LANDLOCK_ACCESS_FS_READ_FILE, NULL);
7952 
7953 	fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
7954 	ASSERT_LE(0, fd);
7955 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIONREAD));
7956 	EXPECT_EQ(0, matches_log_fs_extra(_metadata, self->audit_fd,
7957 					  "fs\\.ioctl_dev", "/dev/null",
7958 					  " ioctlcmd=0x541b"));
7959 
7960 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7961 	EXPECT_EQ(0, records.access);
7962 	EXPECT_EQ(1, records.domain);
7963 }
7964 
7965 TEST_F(audit_layout1, resolve_unix)
7966 {
7967 	struct audit_records records;
7968 	const char *const path = "sock";
7969 	int srv_fd, cli_fd, status;
7970 	pid_t child_pid;
7971 
7972 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, path);
7973 
7974 	child_pid = fork();
7975 	ASSERT_LE(0, child_pid);
7976 	if (!child_pid) {
7977 		enforce_fs(_metadata, ACCESS_ALL, NULL);
7978 
7979 		cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
7980 		ASSERT_LE(0, cli_fd);
7981 		EXPECT_EQ(EACCES,
7982 			  test_connect_named_unix(_metadata, cli_fd, path));
7983 
7984 		EXPECT_EQ(0, close(cli_fd));
7985 		_exit(_metadata->exit_code);
7986 	}
7987 
7988 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
7989 	EXPECT_EQ(1, WIFEXITED(status));
7990 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
7991 
7992 	EXPECT_EQ(0, matches_log_fs_extra(_metadata, self->audit_fd,
7993 					  "fs\\.resolve_unix", path, NULL));
7994 
7995 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7996 	EXPECT_EQ(0, records.access);
7997 	EXPECT_EQ(1, records.domain);
7998 
7999 	EXPECT_EQ(0, close(srv_fd));
8000 }
8001 
8002 TEST_F(audit_layout1, mount)
8003 {
8004 	struct audit_records records;
8005 
8006 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, NULL);
8007 
8008 	set_cap(_metadata, CAP_SYS_ADMIN);
8009 	EXPECT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
8010 	EXPECT_EQ(EPERM, errno);
8011 	clear_cap(_metadata, CAP_SYS_ADMIN);
8012 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
8013 				    "fs\\.change_topology", dir_s3d2));
8014 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
8015 	EXPECT_EQ(0, records.access);
8016 	EXPECT_EQ(1, records.domain);
8017 }
8018 
8019 static bool debug_quiet_tests;
8020 
8021 FIXTURE(audit_quiet_layout1)
8022 {
8023 	struct audit_filter audit_filter;
8024 	int audit_fd;
8025 };
8026 
8027 FIXTURE_SETUP(audit_quiet_layout1)
8028 {
8029 	prepare_layout(_metadata);
8030 	create_layout1(_metadata);
8031 
8032 	set_cap(_metadata, CAP_AUDIT_CONTROL);
8033 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
8034 	EXPECT_LE(0, self->audit_fd);
8035 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
8036 
8037 	if (getenv("DEBUG_QUIET_TESTS"))
8038 		debug_quiet_tests = true;
8039 }
8040 
8041 FIXTURE_TEARDOWN_PARENT(audit_quiet_layout1)
8042 {
8043 	remove_layout1(_metadata);
8044 	cleanup_layout(_metadata);
8045 
8046 	set_cap(_metadata, CAP_AUDIT_CONTROL);
8047 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
8048 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
8049 }
8050 
8051 struct a_rule {
8052 	const char *path;
8053 	__u64 access;
8054 	bool quiet;
8055 };
8056 
8057 struct a_layer {
8058 	__u64 handled_access_fs;
8059 	__u64 quiet_access_fs;
8060 	struct a_rule rules[6];
8061 	__u64 restrict_flags;
8062 };
8063 
8064 struct a_target {
8065 	/* File/dir to try open. */
8066 	const char *target;
8067 	/* Open mode (one of O_RDONLY, O_WRONLY, or O_RDWR). */
8068 	int open_mode;
8069 	/* Should open succeed? */
8070 	bool expect_open_success;
8071 	/* If open fails, whether to expect an audit log for read. */
8072 	bool audit_read_blocked;
8073 	/* If open fails, whether to expect an audit log for write. */
8074 	bool audit_write_blocked;
8075 	/* If ftruncate() is expected to be allowed. */
8076 	bool expect_truncate_success;
8077 	/* If ftruncate fails, whether to expect an audit log. */
8078 	bool audit_truncate;
8079 	/*
8080 	 * If ioctl() is expected to be allowed (ioctl not attempted if neither
8081 	 * this nor expect_ioctl_denied is set).
8082 	 */
8083 	bool expect_ioctl_allowed;
8084 	/* If ioctl() is expected to be denied. */
8085 	bool expect_ioctl_denied;
8086 	/* If ioctl fails, whether to expect an audit log. */
8087 	bool audit_ioctl;
8088 };
8089 
8090 #define AUDIT_QUIET_MAX_TARGETS 10
8091 
8092 FIXTURE_VARIANT(audit_quiet_layout1)
8093 {
8094 	struct a_layer layers[3];
8095 	struct a_target targets[AUDIT_QUIET_MAX_TARGETS];
8096 };
8097 
8098 #define FS_R LANDLOCK_ACCESS_FS_READ_FILE
8099 #define FS_W LANDLOCK_ACCESS_FS_WRITE_FILE
8100 #define FS_TRUNC LANDLOCK_ACCESS_FS_TRUNCATE
8101 #define FS_IOCTL LANDLOCK_ACCESS_FS_IOCTL_DEV
8102 
8103 static int sprint_access_bits(char *buf, size_t buflen, __u64 access)
8104 {
8105 	size_t offset = 0;
8106 
8107 	if (buflen < strlen("rwti make_reg remove_file refer") + 1)
8108 		abort();
8109 
8110 	buf[0] = '\0';
8111 	if (access & FS_R)
8112 		offset += snprintf(buf + offset, buflen - offset, "r");
8113 	if (access & FS_W)
8114 		offset += snprintf(buf + offset, buflen - offset, "w");
8115 	if (access & FS_TRUNC)
8116 		offset += snprintf(buf + offset, buflen - offset, "t");
8117 	if (access & FS_IOCTL)
8118 		offset += snprintf(buf + offset, buflen - offset, "i");
8119 	if (access & LANDLOCK_ACCESS_FS_MAKE_REG)
8120 		offset += snprintf(buf + offset, buflen - offset, ",make_reg");
8121 	if (access & LANDLOCK_ACCESS_FS_REMOVE_FILE)
8122 		offset +=
8123 			snprintf(buf + offset, buflen - offset, ",remove_file");
8124 	if (access & LANDLOCK_ACCESS_FS_REFER)
8125 		offset += snprintf(buf + offset, buflen - offset, ",refer");
8126 
8127 	if (buf[0] == ',') {
8128 		offset--;
8129 		memmove(buf, buf + 1, offset);
8130 		buf[offset] = '\0';
8131 	}
8132 
8133 	return offset;
8134 }
8135 
8136 static int apply_a_layer(struct __test_metadata *const _metadata,
8137 			 const struct a_layer *l)
8138 {
8139 	struct landlock_ruleset_attr rs_attr = {
8140 		.handled_access_fs = l->handled_access_fs,
8141 		.quiet_access_fs = l->quiet_access_fs,
8142 	};
8143 	int rs_fd;
8144 	int i;
8145 	const struct a_rule *r;
8146 	char handled_access_s[33], quiet_access_s[33], rule_access_s[33];
8147 
8148 	if (!l->handled_access_fs)
8149 		return 0;
8150 
8151 	rs_fd = landlock_create_ruleset(&rs_attr, sizeof(rs_attr), 0);
8152 	ASSERT_LE(0, rs_fd);
8153 
8154 	for (i = 0; i < ARRAY_SIZE(l->rules); i++) {
8155 		r = &l->rules[i];
8156 		if (!r->path)
8157 			continue;
8158 
8159 		add_path_beneath(_metadata, rs_fd, r->access, r->path,
8160 				 r->quiet ? LANDLOCK_ADD_RULE_QUIET : 0);
8161 	}
8162 
8163 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
8164 	ASSERT_EQ(0, landlock_restrict_self(rs_fd, l->restrict_flags))
8165 	{
8166 		TH_LOG("Failed to enforce ruleset: %s", strerror(errno));
8167 	}
8168 	ASSERT_EQ(0, close(rs_fd));
8169 
8170 	if (debug_quiet_tests) {
8171 		sprint_access_bits(handled_access_s, sizeof(handled_access_s),
8172 				   l->handled_access_fs);
8173 		sprint_access_bits(quiet_access_s, sizeof(quiet_access_s),
8174 				   l->quiet_access_fs);
8175 		TH_LOG("applied layer: handled=%s quiet=%s restrict_flags=0x%llx",
8176 		       handled_access_s, quiet_access_s,
8177 		       (unsigned long long)l->restrict_flags);
8178 		for (i = 0; i < ARRAY_SIZE(l->rules); i++) {
8179 			r = &l->rules[i];
8180 			if (!r->path)
8181 				continue;
8182 
8183 			sprint_access_bits(rule_access_s, sizeof(rule_access_s),
8184 					   r->access);
8185 			TH_LOG("  rule[%d]: path=%s access=%s quiet=%d", i,
8186 			       r->path, rule_access_s, r->quiet);
8187 		}
8188 	}
8189 	return 0;
8190 }
8191 
8192 void audit_quiet_layout1_test_body(struct __test_metadata *const _metadata,
8193 				   FIXTURE_DATA(audit_quiet_layout1) * self,
8194 				   const struct a_target *targets)
8195 {
8196 	struct audit_records records = {};
8197 	int i;
8198 	const struct a_target *target;
8199 	int fd = -1;
8200 	int open_mode;
8201 	int ret;
8202 	bool expect_audit;
8203 	const char *blocker;
8204 
8205 	for (i = 0; i < AUDIT_QUIET_MAX_TARGETS; i++) {
8206 		target = &targets[i];
8207 		if (!target->target)
8208 			continue;
8209 
8210 		open_mode = target->open_mode & (O_RDONLY | O_WRONLY | O_RDWR);
8211 
8212 		EXPECT_TRUE(open_mode == O_RDONLY || open_mode == O_WRONLY ||
8213 			    open_mode == O_RDWR);
8214 
8215 		if (target->expect_open_success) {
8216 			EXPECT_FALSE(target->audit_read_blocked);
8217 			EXPECT_FALSE(target->audit_write_blocked);
8218 		}
8219 		if (target->expect_truncate_success)
8220 			EXPECT_TRUE(target->expect_open_success &&
8221 				    !target->audit_truncate);
8222 
8223 		if (debug_quiet_tests)
8224 			TH_LOG("Try open \"%s\" with %s%s", target->target,
8225 			       open_mode != O_WRONLY ? "r" : "",
8226 			       open_mode != O_RDONLY ? "w" : "");
8227 
8228 		fd = openat(AT_FDCWD, target->target, open_mode | O_CLOEXEC);
8229 		if (target->expect_open_success) {
8230 			ASSERT_LE(0, fd)
8231 			{
8232 				TH_LOG("Failed to open \"%s\": %s",
8233 				       target->target, strerror(errno));
8234 			};
8235 		} else {
8236 			ASSERT_EQ(-1, fd);
8237 			ASSERT_EQ(EACCES, errno);
8238 		}
8239 
8240 		expect_audit = true;
8241 
8242 		if (target->audit_read_blocked && target->audit_write_blocked)
8243 			blocker = "fs\\.write_file,fs\\.read_file";
8244 		else if (target->audit_read_blocked)
8245 			blocker = "fs\\.read_file";
8246 		else if (target->audit_write_blocked)
8247 			blocker = "fs\\.write_file";
8248 		else
8249 			expect_audit = false;
8250 
8251 		if (expect_audit)
8252 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
8253 						    blocker, target->target));
8254 
8255 		/* Check that we see no (other) logs. */
8256 		EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
8257 		ASSERT_EQ(0, records.access);
8258 
8259 		if (target->expect_open_success && fd >= 0) {
8260 			if (debug_quiet_tests)
8261 				TH_LOG("Try ftruncate \"%s\"", target->target);
8262 
8263 			ret = ftruncate(fd, 0);
8264 			if (target->expect_truncate_success) {
8265 				ASSERT_EQ(0, ret);
8266 			} else {
8267 				ASSERT_EQ(-1, ret);
8268 				if (open_mode != O_RDONLY)
8269 					ASSERT_EQ(EACCES, errno);
8270 			}
8271 
8272 			if (target->audit_truncate)
8273 				ASSERT_EQ(0, matches_log_fs(_metadata,
8274 							    self->audit_fd,
8275 							    "fs\\.truncate",
8276 							    target->target));
8277 
8278 			if (target->expect_ioctl_allowed ||
8279 			    target->expect_ioctl_denied) {
8280 				if (debug_quiet_tests)
8281 					TH_LOG("Try ioctl FIONREAD on \"%s\"",
8282 					       target->target);
8283 
8284 				ret = ioctl_error(_metadata, fd, FIONREAD);
8285 				if (target->expect_ioctl_allowed) {
8286 					ASSERT_NE(EACCES, ret);
8287 				} else {
8288 					ASSERT_EQ(EACCES, ret);
8289 				}
8290 			}
8291 
8292 			if (target->audit_ioctl)
8293 				ASSERT_EQ(0, matches_log_fs_extra(
8294 						     _metadata, self->audit_fd,
8295 						     "fs\\.ioctl_dev",
8296 						     target->target,
8297 						     " ioctlcmd=0x541b\\+"));
8298 
8299 			/* Check that we see no other logs. */
8300 			EXPECT_EQ(0, audit_count_records(self->audit_fd,
8301 							 &records));
8302 			ASSERT_EQ(0, records.access);
8303 			ASSERT_EQ(0, close(fd));
8304 		}
8305 	}
8306 }
8307 
8308 TEST_F(audit_quiet_layout1, base)
8309 {
8310 	int i;
8311 
8312 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
8313 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
8314 
8315 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
8316 }
8317 
8318 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_simple) {
8319 	.layers = {
8320 		{
8321 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8322 			.quiet_access_fs = FS_R,
8323 			.rules = {
8324 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8325 			},
8326 		},
8327 	},
8328 	.targets = {
8329 		{
8330 			.target = file1_s1d1,
8331 			.open_mode = O_RDONLY,
8332 		},
8333 		/* Not covered by quiet */
8334 		{
8335 			.target = file1_s2d1,
8336 			.open_mode = O_RDONLY,
8337 			.audit_read_blocked = true,
8338 		},
8339 		/* Access not quieted */
8340 		{
8341 			.target = file1_s1d1,
8342 			.open_mode = O_WRONLY,
8343 			.audit_write_blocked = true,
8344 		},
8345 		/*
8346 		 * Quiet flag only takes effect if all blocked access bits are
8347 		 * quieted, otherwise audit log emitted as normal (with all
8348 		 * blockers)
8349 		 */
8350 		{
8351 			.target = file1_s1d1,
8352 			.open_mode = O_RDWR,
8353 			.audit_read_blocked = true,
8354 			.audit_write_blocked = true,
8355 		},
8356 	},
8357 };
8358 
8359 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_allow_read) {
8360 	.layers = {
8361 		{
8362 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8363 			.quiet_access_fs = FS_W,
8364 			.rules = {
8365 				{ .path = dir_s1d1, .access = FS_R, .quiet = true },
8366 				/* Quiet flags inherit down and are not overridden */
8367 				{ .path = file1_s1d1, .access = FS_R, .quiet = false },
8368 				{ .path = file1_s2d3, .access = 0, .quiet = true },
8369 			},
8370 		},
8371 	},
8372 	.targets = {
8373 		/* Read ok */
8374 		{
8375 			.target = file1_s1d1,
8376 			.open_mode = O_RDONLY,
8377 			.expect_open_success = true,
8378 		},
8379 		/* Write quieted */
8380 		{
8381 			.target = file1_s1d1,
8382 			.open_mode = O_WRONLY,
8383 		},
8384 		/* Read allowed, write quieted so no audit */
8385 		{
8386 			.target = file1_s1d1,
8387 			.open_mode = O_RDWR,
8388 		},
8389 		/* Not covered by quiet */
8390 		{
8391 			.target = file1_s2d2,
8392 			.open_mode = O_WRONLY,
8393 			.audit_write_blocked = true,
8394 		},
8395 		{
8396 			.target = file1_s2d2,
8397 			.open_mode = O_RDWR,
8398 			.audit_read_blocked = true,
8399 			.audit_write_blocked = true,
8400 		},
8401 		/* Single file quiet */
8402 		{
8403 			.target = file1_s2d3,
8404 			.open_mode = O_WRONLY,
8405 		},
8406 		/* Wrong file */
8407 		{
8408 			.target = file2_s2d3,
8409 			.open_mode = O_WRONLY,
8410 			.audit_write_blocked = true,
8411 		},
8412 		/* Access not quieted */
8413 		{
8414 			.target = file1_s2d3,
8415 			.open_mode = O_RDONLY,
8416 			.audit_read_blocked = true,
8417 		},
8418 		/* Some access not quieted */
8419 		{
8420 			.target = file1_s2d3,
8421 			.open_mode = O_RDWR,
8422 			.audit_read_blocked = true,
8423 			.audit_write_blocked = true,
8424 		},
8425 	},
8426 };
8427 
8428 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_allow_write) {
8429 	.layers = {
8430 		{
8431 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8432 			.quiet_access_fs = FS_R,
8433 			.rules = {
8434 				{ .path = dir_s1d1, .access = FS_W, .quiet = true },
8435 			},
8436 		},
8437 	},
8438 	.targets = {
8439 		/* Read quieted */
8440 		{
8441 			.target = file1_s1d1,
8442 			.open_mode = O_RDONLY,
8443 		},
8444 		/* Truncate not quieted */
8445 		{
8446 			.target = file1_s1d1,
8447 			.open_mode = O_WRONLY,
8448 			.expect_open_success = true,
8449 			.audit_truncate = true,
8450 		},
8451 		/* Not covered by quiet */
8452 		{
8453 			.target = file1_s2d1,
8454 			.open_mode = O_RDONLY,
8455 			.audit_read_blocked = true,
8456 		},
8457 		/* Write allowed, read quieted so no audit */
8458 		{
8459 			.target = file1_s1d1,
8460 			.open_mode = O_RDWR,
8461 		},
8462 	},
8463 };
8464 
8465 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_write_quiet_trunc) {
8466 	.layers = {
8467 		{
8468 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8469 			.quiet_access_fs = FS_TRUNC,
8470 			.rules = {
8471 				{ .path = dir_s1d1, .access = FS_W, .quiet = true },
8472 				{ .path = dir_s2d1, .access = FS_W, .quiet = false },
8473 			},
8474 		},
8475 	},
8476 	.targets = {
8477 		/* Read not allowed and not quieted */
8478 		{
8479 			.target = file1_s1d1,
8480 			.open_mode = O_RDONLY,
8481 			.audit_read_blocked = true,
8482 		},
8483 		/* Truncate quieted */
8484 		{
8485 			.target = file1_s1d1,
8486 			.open_mode = O_WRONLY,
8487 			.expect_open_success = true,
8488 		},
8489 		/* Not covered by quiet (truncate) */
8490 		{
8491 			.target = file1_s2d1,
8492 			.open_mode = O_WRONLY,
8493 			.expect_open_success = true,
8494 			.audit_truncate = true,
8495 		},
8496 		/* Not covered by quiet (read/write) */
8497 		{
8498 			.target = file1_s3d1,
8499 			.open_mode = O_RDWR,
8500 			.audit_read_blocked = true,
8501 			.audit_write_blocked = true,
8502 		},
8503 	},
8504 };
8505 
8506 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_rw_quiet_trunc) {
8507 	.layers = {
8508 		{
8509 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8510 			.quiet_access_fs = FS_TRUNC,
8511 			.rules = {
8512 				{ .path = dir_s1d1, .access = FS_R | FS_W, .quiet = true },
8513 				{ .path = dir_s2d1, .access = FS_R | FS_W, .quiet = false },
8514 			},
8515 		},
8516 	},
8517 	.targets = {
8518 		{
8519 			.target = file1_s1d1,
8520 			.open_mode = O_RDWR,
8521 			.expect_open_success = true,
8522 		},
8523 		{
8524 			.target = file1_s2d1,
8525 			.open_mode = O_RDWR,
8526 			.expect_open_success = true,
8527 			.audit_truncate = true,
8528 		},
8529 	},
8530 };
8531 
8532 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_all) {
8533 	.layers = {
8534 		{
8535 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8536 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8537 			.rules = {
8538 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8539 				{ .path = file1_s2d1, .access = FS_R | FS_W, .quiet = true },
8540 				{ .path = file1_s2d3, .access = 0, .quiet = true },
8541 				{ .path = dir_s3d1, .access = FS_W, .quiet = false },
8542 				{ .path = "/dev/zero", .access = FS_R, .quiet = false },
8543 				{ .path = "/dev/null", .access = FS_R, .quiet = true },
8544 			},
8545 		},
8546 	},
8547 	.targets = {
8548 		/* No logs */
8549 		{
8550 			.target = file1_s1d1,
8551 			.open_mode = O_RDONLY,
8552 		},
8553 		{
8554 			.target = file1_s1d1,
8555 			.open_mode = O_WRONLY,
8556 		},
8557 		{
8558 			.target = file1_s1d1,
8559 			.open_mode = O_RDWR,
8560 		},
8561 		/* Truncate quieted - no log */
8562 		{
8563 			.target = file1_s2d1,
8564 			.open_mode = O_RDWR,
8565 			.expect_open_success = true,
8566 		},
8567 		/* Truncate not covered by quiet */
8568 		{
8569 			.target = file1_s3d1,
8570 			.open_mode = O_WRONLY,
8571 			.expect_open_success = true,
8572 			.audit_truncate = true,
8573 		},
8574 		/* Not covered by quiet */
8575 		{
8576 			.target = file1_s3d1,
8577 			.open_mode = O_RDONLY,
8578 			.audit_read_blocked = true,
8579 		},
8580 		/* Single file quiet */
8581 		{
8582 			.target = file1_s2d3,
8583 			.open_mode = O_RDWR,
8584 		},
8585 		/* Wrong file */
8586 		{
8587 			.target = file2_s2d3,
8588 			.open_mode = O_RDWR,
8589 			.audit_read_blocked = true,
8590 			.audit_write_blocked = true,
8591 		},
8592 		/* Ioctl quieted */
8593 		{
8594 			.target = "/dev/null",
8595 			.open_mode = O_RDONLY,
8596 			.expect_open_success = true,
8597 			.expect_ioctl_denied = true,
8598 		},
8599 		/* Ioctl not quieted */
8600 		{
8601 			.target = "/dev/zero",
8602 			.open_mode = O_RDONLY,
8603 			.expect_open_success = true,
8604 			.expect_ioctl_denied = true,
8605 			.audit_ioctl = true,
8606 		},
8607 	},
8608 };
8609 
8610 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_across_mountpoint) {
8611 	.layers = {
8612 		{
8613 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8614 			.quiet_access_fs = FS_R,
8615 			.rules = {
8616 				{ .path = dir_s3d1, .access = 0, .quiet = true },
8617 			},
8618 		},
8619 	},
8620 	.targets = {
8621 		{
8622 			.target = file1_s3d3,
8623 			.open_mode = O_RDONLY,
8624 		},
8625 		/* Not covered by quiet */
8626 		{
8627 			.target = file1_s1d1,
8628 			.open_mode = O_RDONLY,
8629 			.audit_read_blocked = true,
8630 		},
8631 		{
8632 			.target = file1_s1d1,
8633 			.open_mode = O_RDWR,
8634 			.audit_read_blocked = true,
8635 			.audit_write_blocked = true,
8636 		},
8637 		/* Access not quieted */
8638 		{
8639 			.target = file1_s3d3,
8640 			.open_mode = O_WRONLY,
8641 			.audit_write_blocked = true,
8642 		},
8643 	},
8644 };
8645 
8646 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_all_quiet) {
8647 	.layers = {
8648 		{
8649 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8650 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8651 			.rules = {
8652 				{
8653 					.path = dir_s1d1,
8654 					.access = FS_R | FS_W | FS_TRUNC,
8655 					.quiet = true
8656 				},
8657 				{
8658 					.path = "/dev/null",
8659 					.access = FS_R | FS_W | FS_IOCTL,
8660 					.quiet = true
8661 				},
8662 			},
8663 		},
8664 	},
8665 	.targets = {
8666 		{
8667 			.target = file1_s1d1,
8668 			.open_mode = O_RDWR,
8669 			.expect_open_success = true,
8670 			.expect_truncate_success = true,
8671 		},
8672 		{
8673 			.target = "/dev/null",
8674 			.open_mode = O_RDONLY,
8675 			.expect_open_success = true,
8676 			.expect_ioctl_allowed = true,
8677 		},
8678 	},
8679 };
8680 
8681 /*
8682  * With LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, it doesn't matter what the
8683  * quiet flags below the layer say.
8684  */
8685 FIXTURE_VARIANT_ADD(audit_quiet_layout1, subdomains_off) {
8686 	.layers = {
8687 		{
8688 			.handled_access_fs = FS_R,
8689 			.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
8690 			.rules = {
8691 				{ .path = "/", .access = FS_R, .quiet = false },
8692 			}
8693 		},
8694 		{
8695 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8696 			.quiet_access_fs = FS_R,
8697 			.rules = {
8698 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8699 				{ .path = file1_s2d2, .access = FS_R | FS_W, .quiet = true },
8700 				{ .path = file1_s2d3, .access = FS_R | FS_W, .quiet = false },
8701 				{ .path = "/dev/null", .access = FS_R | FS_W, .quiet = true },
8702 				{ .path = "/dev/zero", .access = FS_R | FS_W, .quiet = false },
8703 			},
8704 		},
8705 	},
8706 	.targets = {
8707 		{
8708 			.target = file1_s1d1,
8709 			.open_mode = O_RDWR,
8710 		},
8711 		{
8712 			.target = file1_s2d1,
8713 			.open_mode = O_RDWR,
8714 		},
8715 		{
8716 			.target = file1_s2d2,
8717 			.open_mode = O_RDWR,
8718 			.expect_open_success = true,
8719 			/* No audit_truncate */
8720 		},
8721 		{
8722 			.target = file1_s2d3,
8723 			.open_mode = O_RDWR,
8724 			.expect_open_success = true,
8725 			/* No audit_truncate */
8726 		},
8727 		{
8728 			.target = "/dev/null",
8729 			.open_mode = O_RDONLY,
8730 			.expect_open_success = true,
8731 			.expect_ioctl_denied = true,
8732 			/* No audit_ioctl */
8733 		},
8734 		{
8735 			.target = "/dev/zero",
8736 			.open_mode = O_RDONLY,
8737 			.expect_open_success = true,
8738 			.expect_ioctl_denied = true,
8739 			/* No audit_ioctl */
8740 		},
8741 	},
8742 };
8743 
8744 /*
8745  * With LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF, it doesn't matter what the
8746  * quiet flags on the layer say.
8747  */
8748 FIXTURE_VARIANT_ADD(audit_quiet_layout1, same_exec_off) {
8749 	.layers = {
8750 		{
8751 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8752 			.quiet_access_fs = FS_R,
8753 			.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
8754 			.rules = {
8755 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8756 				{ .path = file1_s2d2, .access = FS_R | FS_W, .quiet = true },
8757 				{ .path = file1_s2d3, .access = FS_R | FS_W, .quiet = false },
8758 				{ .path = "/dev/null", .access = FS_R | FS_W, .quiet = true },
8759 				{ .path = "/dev/zero", .access = FS_R | FS_W, .quiet = false },
8760 			},
8761 		},
8762 	},
8763 	.targets = {
8764 		{
8765 			.target = file1_s1d1,
8766 			.open_mode = O_RDWR,
8767 		},
8768 		{
8769 			.target = file1_s2d1,
8770 			.open_mode = O_RDWR,
8771 		},
8772 		{
8773 			.target = file1_s2d2,
8774 			.open_mode = O_RDWR,
8775 			.expect_open_success = true,
8776 			/* No audit_truncate */
8777 		},
8778 		{
8779 			.target = file1_s2d3,
8780 			.open_mode = O_RDWR,
8781 			.expect_open_success = true,
8782 			/* No audit_truncate */
8783 		},
8784 		{
8785 			.target = "/dev/null",
8786 			.open_mode = O_RDONLY,
8787 			.expect_open_success = true,
8788 			.expect_ioctl_denied = true,
8789 			/* No audit_ioctl */
8790 		},
8791 		{
8792 			.target = "/dev/zero",
8793 			.open_mode = O_RDONLY,
8794 			.expect_open_success = true,
8795 			.expect_ioctl_denied = true,
8796 			/* No audit_ioctl */
8797 		},
8798 	},
8799 };
8800 
8801 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_1) {
8802 	/* Here, rules that deny access are always quiet. */
8803 	.layers = {
8804 		{
8805 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8806 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8807 			.rules = {
8808 				{
8809 					.path = dir_s1d1,
8810 					.access = FS_W,
8811 					.quiet = true,
8812 				},
8813 				{
8814 					.path = dir_s2d1,
8815 					.access = FS_R | FS_W | FS_TRUNC,
8816 					.quiet = false,
8817 				},
8818 				{
8819 					.path = "/dev/null",
8820 					.access = FS_R,
8821 					.quiet = true,
8822 				},
8823 				{
8824 					.path = "/dev/zero",
8825 					.access = FS_R | FS_W | FS_IOCTL,
8826 					.quiet = false,
8827 				},
8828 			},
8829 		},
8830 		{
8831 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8832 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8833 			.rules = {
8834 				{
8835 					.path = dir_s1d1,
8836 					.access = FS_R | FS_W | FS_TRUNC,
8837 					.quiet = false,
8838 				},
8839 				{
8840 					.path = dir_s2d1,
8841 					.access = FS_W,
8842 					.quiet = true,
8843 				},
8844 				{
8845 					.path = "/dev/null",
8846 					.access = FS_R | FS_W | FS_IOCTL,
8847 					.quiet = false,
8848 				},
8849 				{
8850 					.path = "/dev/zero",
8851 					.access = FS_R,
8852 					.quiet = true,
8853 				},
8854 			},
8855 		},
8856 	},
8857 	.targets = {
8858 		{
8859 			.target = file1_s1d1,
8860 			.open_mode = O_RDONLY,
8861 		},
8862 		{
8863 			.target = file1_s1d1,
8864 			.open_mode = O_WRONLY,
8865 			.expect_open_success = true,
8866 		},
8867 		{
8868 			.target = file1_s2d1,
8869 			.open_mode = O_RDONLY,
8870 		},
8871 		{
8872 			.target = file1_s2d1,
8873 			.open_mode = O_WRONLY,
8874 			.expect_open_success = true,
8875 		},
8876 		{
8877 			.target = "/dev/null",
8878 			.open_mode = O_RDONLY,
8879 			.expect_open_success = true,
8880 			.expect_ioctl_denied = true,
8881 		},
8882 		{
8883 			.target = "/dev/zero",
8884 			.open_mode = O_RDONLY,
8885 			.expect_open_success = true,
8886 			.expect_ioctl_denied = true,
8887 		},
8888 	},
8889 };
8890 
8891 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_2) {
8892 	/* Here, rules that deny access are never quiet. */
8893 	.layers = {
8894 		{
8895 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8896 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8897 			.rules = {
8898 				{
8899 					.path = dir_s1d1,
8900 					.access = FS_W,
8901 					.quiet = false
8902 				},
8903 				{
8904 					.path = dir_s2d1,
8905 					.access = FS_R | FS_W | FS_TRUNC,
8906 					.quiet = true
8907 				},
8908 				{
8909 					.path = "/dev/null",
8910 					.access = FS_R,
8911 					.quiet = false
8912 				},
8913 				{
8914 					.path = "/dev/zero",
8915 					.access = FS_R | FS_W | FS_IOCTL,
8916 					.quiet = true
8917 				},
8918 			},
8919 		},
8920 		{
8921 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8922 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8923 			.rules = {
8924 				{
8925 					.path = dir_s1d1,
8926 					.access = FS_R | FS_W | FS_TRUNC,
8927 					.quiet = true
8928 				},
8929 				{
8930 					.path = dir_s2d1,
8931 					.access = FS_W,
8932 					.quiet = false
8933 				},
8934 				{
8935 					.path = "/dev/null",
8936 					.access = FS_R | FS_W | FS_IOCTL,
8937 					.quiet = true
8938 				},
8939 				{
8940 					.path = "/dev/zero",
8941 					.access = FS_R,
8942 					.quiet = false
8943 				},
8944 			},
8945 		},
8946 	},
8947 	.targets = {
8948 		{
8949 			.target = file1_s1d1,
8950 			.open_mode = O_RDONLY,
8951 			.audit_read_blocked = true,
8952 		},
8953 		{
8954 			.target = file1_s1d1,
8955 			.open_mode = O_WRONLY,
8956 			.expect_open_success = true,
8957 			.audit_truncate	= true,
8958 		},
8959 		{
8960 			.target = file1_s2d1,
8961 			.open_mode = O_RDONLY,
8962 			.audit_read_blocked = true,
8963 		},
8964 		{
8965 			.target = file1_s2d1,
8966 			.open_mode = O_WRONLY,
8967 			.expect_open_success = true,
8968 			.audit_truncate	= true,
8969 		},
8970 		{
8971 			.target = "/dev/null",
8972 			.open_mode = O_RDONLY,
8973 			.expect_open_success = true,
8974 			.expect_ioctl_denied = true,
8975 			.audit_ioctl = true,
8976 		},
8977 		{
8978 			.target = "/dev/zero",
8979 			.open_mode = O_RDONLY,
8980 			.expect_open_success = true,
8981 			.expect_ioctl_denied = true,
8982 			.audit_ioctl = true,
8983 		},
8984 	},
8985 };
8986 
8987 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_3) {
8988 	/* This time only the second layer quiets things. */
8989 	.layers = {
8990 		{
8991 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8992 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8993 			.rules = {
8994 				{
8995 					.path = dir_s1d1,
8996 					.access = FS_W,
8997 					.quiet = false,
8998 				},
8999 				{
9000 					.path = dir_s2d1,
9001 					.access = FS_R | FS_W | FS_TRUNC,
9002 					.quiet = false,
9003 				},
9004 				{
9005 					.path = "/dev/null",
9006 					.access = FS_R,
9007 					.quiet = false,
9008 				},
9009 				{
9010 					.path = "/dev/zero",
9011 					.access = FS_R | FS_W | FS_IOCTL,
9012 					.quiet = false,
9013 				},
9014 			},
9015 		},
9016 		{
9017 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9018 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9019 			.rules = {
9020 				{
9021 					.path = dir_s1d1,
9022 					.access = FS_R | FS_W | FS_TRUNC,
9023 					.quiet = false,
9024 				},
9025 				{
9026 					.path = dir_s2d1,
9027 					.access = FS_W,
9028 					.quiet = true,
9029 				},
9030 				{
9031 					.path = "/dev/null",
9032 					.access = FS_R | FS_W | FS_IOCTL,
9033 					.quiet = false,
9034 				},
9035 				{
9036 					.path = "/dev/zero",
9037 					.access = FS_R,
9038 					.quiet = true,
9039 				},
9040 			},
9041 		},
9042 	},
9043 	.targets = {
9044 		{
9045 			.target = file1_s1d1,
9046 			.open_mode = O_RDONLY,
9047 			.audit_read_blocked = true,
9048 		},
9049 		{
9050 			.target = file1_s1d1,
9051 			.open_mode = O_WRONLY,
9052 			.expect_open_success = true,
9053 			.audit_truncate = true,
9054 		},
9055 		{
9056 			.target = file1_s2d1,
9057 			.open_mode = O_RDONLY,
9058 		},
9059 		{
9060 			.target = file1_s2d1,
9061 			.open_mode = O_WRONLY,
9062 			.expect_open_success = true,
9063 		},
9064 		{
9065 			.target = "/dev/null",
9066 			.open_mode = O_RDONLY,
9067 			.expect_open_success = true,
9068 			.expect_ioctl_denied = true,
9069 			.audit_ioctl = true,
9070 		},
9071 		{
9072 			.target = "/dev/zero",
9073 			.open_mode = O_RDONLY,
9074 			.expect_open_success = true,
9075 			.expect_ioctl_denied = true,
9076 		},
9077 	},
9078 };
9079 
9080 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_quiet_access) {
9081 	/* Here, rules that deny access are always quiet. */
9082 	.layers = {
9083 		{
9084 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9085 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9086 			.rules = {
9087 				{
9088 					.path = dir_s1d1,
9089 					.access = FS_W,
9090 					.quiet = true,
9091 				},
9092 				{
9093 					.path = dir_s2d1,
9094 					.access = FS_R | FS_W | FS_TRUNC,
9095 					.quiet = false,
9096 				},
9097 				{
9098 					.path = "/dev/null",
9099 					.access = FS_R,
9100 					.quiet = true,
9101 				},
9102 				{
9103 					.path = "/dev/zero",
9104 					.access = FS_R | FS_W | FS_IOCTL,
9105 					.quiet = false,
9106 				},
9107 			},
9108 		},
9109 		{
9110 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9111 			.quiet_access_fs = FS_IOCTL,
9112 			.rules = {
9113 				{
9114 					.path = dir_s1d1,
9115 					.access = FS_R | FS_W | FS_TRUNC,
9116 					.quiet = false,
9117 				},
9118 				{
9119 					.path = dir_s2d1,
9120 					.access = FS_W,
9121 					.quiet = true,
9122 				},
9123 				{
9124 					.path = "/dev/null",
9125 					.access = FS_R | FS_W | FS_IOCTL,
9126 					.quiet = false,
9127 				},
9128 				{
9129 					.path = "/dev/zero",
9130 					.access = FS_R,
9131 					.quiet = true,
9132 				},
9133 			},
9134 		},
9135 	},
9136 	.targets = {
9137 		{
9138 			.target = file1_s1d1,
9139 			.open_mode = O_RDONLY,
9140 		},
9141 		{
9142 			.target = file1_s1d1,
9143 			.open_mode = O_WRONLY,
9144 			.expect_open_success = true,
9145 		},
9146 		{
9147 			.target = file1_s2d1,
9148 			.open_mode = O_RDONLY,
9149 			.audit_read_blocked = true,
9150 		},
9151 		{
9152 			.target = file1_s2d1,
9153 			.open_mode = O_WRONLY,
9154 			.expect_open_success = true,
9155 			.audit_truncate	= true,
9156 		},
9157 		{
9158 			.target = "/dev/null",
9159 			.open_mode = O_RDONLY,
9160 			.expect_open_success = true,
9161 			.expect_ioctl_denied = true,
9162 		},
9163 		{
9164 			.target = "/dev/zero",
9165 			.open_mode = O_RDONLY,
9166 			.expect_open_success = true,
9167 			.expect_ioctl_denied = true,
9168 		},
9169 	},
9170 };
9171 
9172 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_1) {
9173 	/* Quiet from layer 1 */
9174 	.layers = {
9175 		{
9176 			.handled_access_fs = FS_R,
9177 			.quiet_access_fs = FS_R,
9178 			.rules = {
9179 				{
9180 					.path = file1_s1d1,
9181 					.access = FS_R,
9182 					.quiet = true,
9183 				},
9184 				{
9185 					.path = file2_s1d1,
9186 					.access = 0,
9187 					.quiet = true,
9188 				},
9189 				{
9190 					.path = file1_s1d2,
9191 					.access = 0,
9192 					.quiet = true,
9193 				},
9194 				{
9195 					.path = file2_s1d2,
9196 					.access = FS_R,
9197 					.quiet = true,
9198 				},
9199 			},
9200 		},
9201 		{
9202 			.handled_access_fs = FS_W,
9203 			.quiet_access_fs = FS_W,
9204 			.rules = {
9205 				{
9206 					.path = file1_s1d1,
9207 					.access = FS_W,
9208 					.quiet = false,
9209 				},
9210 				/* Nothing for file2_s1d1 */
9211 				{
9212 					.path = file1_s1d2,
9213 					.access = FS_W,
9214 					.quiet = false,
9215 				},
9216 				/* Nothing for file2_s1d2 */
9217 			},
9218 		},
9219 	},
9220 	.targets = {
9221 		{
9222 			.target = file1_s1d1,
9223 			.open_mode = O_RDWR,
9224 			.expect_open_success = true,
9225 			.expect_truncate_success = true,
9226 		},
9227 		/* Missing both, youngest layer denies write, not quiet */
9228 		{
9229 			.target = file2_s1d1,
9230 			.open_mode = O_RDWR,
9231 			.audit_write_blocked = true,
9232 		},
9233 		/* Missing read, denied and quieted by layer 1 */
9234 		{
9235 			.target = file1_s1d2,
9236 			.open_mode = O_RDWR,
9237 		},
9238 		/* Missing write, denied and not quieted by layer 2 */
9239 		{
9240 			.target = file2_s1d2,
9241 			.open_mode = O_RDWR,
9242 			.audit_write_blocked = true,
9243 		},
9244 	},
9245 };
9246 
9247 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_2) {
9248 	/* Quiet from layer 2 */
9249 	.layers = {
9250 		{
9251 			.handled_access_fs = FS_R,
9252 			.quiet_access_fs = FS_R,
9253 			.rules = {
9254 				{
9255 					.path = file1_s1d1,
9256 					.access = FS_R,
9257 					.quiet = false,
9258 				},
9259 				/* Nothing for file2_s1d1 and file1_s1d2 */
9260 				{
9261 					.path = file2_s1d2,
9262 					.access = FS_R,
9263 					.quiet = false,
9264 				},
9265 			},
9266 		},
9267 		{
9268 			.handled_access_fs = FS_W,
9269 			.quiet_access_fs = FS_W,
9270 			.rules = {
9271 				{
9272 					.path = file1_s1d1,
9273 					.access = FS_W,
9274 					.quiet = true,
9275 				},
9276 				{
9277 					.path = file2_s1d1,
9278 					.access = 0,
9279 					.quiet = true,
9280 				},
9281 				{
9282 					.path = file1_s1d2,
9283 					.access = FS_W,
9284 					.quiet = true,
9285 				},
9286 				{
9287 					.path = file2_s1d2,
9288 					.access = 0,
9289 					.quiet = true,
9290 				},
9291 			},
9292 		},
9293 	},
9294 	.targets = {
9295 		{
9296 			.target = file1_s1d1,
9297 			.open_mode = O_RDWR,
9298 			.expect_open_success = true,
9299 			.expect_truncate_success = true,
9300 		},
9301 		/* Missing both, youngest layer denies write, quiet */
9302 		{
9303 			.target = file2_s1d1,
9304 			.open_mode = O_RDWR,
9305 		},
9306 		/* Missing read, denied and not quieted by layer 1 */
9307 		{
9308 			.target = file1_s1d2,
9309 			.open_mode = O_RDWR,
9310 			.audit_read_blocked = true,
9311 		},
9312 		/* Missing write, denied and quieted by layer 2 */
9313 		{
9314 			.target = file2_s1d2,
9315 			.open_mode = O_RDWR,
9316 		},
9317 	},
9318 };
9319 
9320 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_3) {
9321 	/* Quiet from both layers */
9322 	.layers = {
9323 		{
9324 			.handled_access_fs = FS_R,
9325 			.quiet_access_fs = FS_R,
9326 			.rules = {
9327 				{
9328 					.path = file1_s1d1,
9329 					.access = FS_R,
9330 					.quiet = true,
9331 				},
9332 				{
9333 					.path = file2_s1d1,
9334 					.access = 0,
9335 					.quiet = true,
9336 				},
9337 				{
9338 					.path = file1_s1d2,
9339 					.access = 0,
9340 					.quiet = true,
9341 				},
9342 				{
9343 					.path = file2_s1d2,
9344 					.access = FS_R,
9345 					.quiet = true,
9346 				},
9347 			},
9348 		},
9349 		{
9350 			.handled_access_fs = FS_W,
9351 			.quiet_access_fs = FS_W,
9352 			.rules = {
9353 				{
9354 					.path = file1_s1d1,
9355 					.access = FS_W,
9356 					.quiet = true,
9357 				},
9358 				{
9359 					.path = file2_s1d1,
9360 					.access = 0,
9361 					.quiet = true,
9362 				},
9363 				{
9364 					.path = file1_s1d2,
9365 					.access = FS_W,
9366 					.quiet = true,
9367 				},
9368 				{
9369 					.path = file2_s1d2,
9370 					.access = 0,
9371 					.quiet = true,
9372 				},
9373 			},
9374 		},
9375 	},
9376 	.targets = {
9377 		{
9378 			.target = file1_s1d1,
9379 			.open_mode = O_RDWR,
9380 			.expect_open_success = true,
9381 			.expect_truncate_success = true,
9382 		},
9383 		{
9384 			.target = file2_s1d1,
9385 			.open_mode = O_RDWR,
9386 		},
9387 		{
9388 			.target = file1_s1d2,
9389 			.open_mode = O_RDWR,
9390 		},
9391 		{
9392 			.target = file2_s1d2,
9393 			.open_mode = O_RDWR,
9394 		},
9395 	},
9396 };
9397 
9398 FIXTURE_VARIANT_ADD(audit_quiet_layout1, without_quiet_then_with_quiet) {
9399 	.layers = {
9400 		{
9401 			.handled_access_fs = FS_R | FS_W,
9402 			.quiet_access_fs = FS_R,
9403 			.rules = {
9404 				{ .path = dir_s1d1, .access = FS_W, .quiet = false },
9405 				{ .path = dir_s1d1, .access = 0, .quiet = true },
9406 			},
9407 		},
9408 	},
9409 	.targets = {
9410 		/* Read denied and quieted */
9411 		{
9412 			.target = file1_s1d1,
9413 			.open_mode = O_RDONLY,
9414 		},
9415 		/* Write ok */
9416 		{
9417 			.target = file1_s1d1,
9418 			.open_mode = O_WRONLY,
9419 			.expect_open_success = true,
9420 			.expect_truncate_success = true,
9421 		},
9422 		/* Write ok, read denied and quieted */
9423 		{
9424 			.target = file1_s1d1,
9425 			.open_mode = O_RDWR,
9426 		},
9427 		/* Not covered by quiet */
9428 		{
9429 			.target = file1_s2d1,
9430 			.open_mode = O_RDONLY,
9431 			.audit_read_blocked = true,
9432 		},
9433 	},
9434 };
9435 
9436 /*
9437  * The following TEST_F extend the above test cases to test more layers, with
9438  * the inserted layers having varying configurations.
9439  */
9440 
9441 /* Extra allow all layers, quiet or not, does not change any behaviour. */
9442 TEST_F(audit_quiet_layout1, allow_all_layer)
9443 {
9444 	struct a_layer allow_all_layer = {
9445 		.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9446 		.quiet_access_fs = 0,
9447 		.rules = {
9448 			{
9449 				.path = "/",
9450 				.access = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9451 				.quiet = false,
9452 			},
9453 		},
9454 	};
9455 	int i;
9456 
9457 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9458 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9459 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9460 
9461 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9462 
9463 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9464 
9465 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9466 
9467 	/*
9468 	 * SELF_LOG flags or quiet bits from inner allowing layers should not
9469 	 * affect behaviour.
9470 	 */
9471 	allow_all_layer.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL;
9472 	allow_all_layer.rules[0].quiet = true;
9473 	/*
9474 	 * Note: this only works because we're not checking counts of domain
9475 	 * alloc/dealloc logs
9476 	 */
9477 	allow_all_layer.restrict_flags =
9478 		LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
9479 		LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF;
9480 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9481 
9482 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9483 }
9484 
9485 /*
9486  * Add useless outer layers until we reach the layer limit.  Should not change
9487  * anything.
9488  */
9489 TEST_F(audit_quiet_layout1, many_outer_layers)
9490 {
9491 	struct a_layer useless_layer = {
9492 		.handled_access_fs = FS_R | FS_W | FS_TRUNC,
9493 		.quiet_access_fs = FS_R | FS_W | FS_TRUNC,
9494 		.rules = {
9495 			{ .path = "/", .access = FS_R | FS_W | FS_TRUNC, .quiet = true },
9496 		},
9497 	};
9498 	int i;
9499 
9500 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++) {
9501 		if (variant->layers[i].handled_access_fs == 0)
9502 			break;
9503 	}
9504 
9505 	for (; i < LANDLOCK_MAX_NUM_LAYERS; i++)
9506 		ASSERT_EQ(0, apply_a_layer(_metadata, &useless_layer));
9507 
9508 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9509 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9510 
9511 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9512 }
9513 
9514 /* An inner layer that denies and quiets everything should result in no logs. */
9515 TEST_F(audit_quiet_layout1, deny_all_quiet_layer)
9516 {
9517 	struct a_layer deny_all_layer = {
9518 		.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9519 		.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9520 		.rules = {
9521 			{ .path = "/", .access = 0, .quiet = true },
9522 		},
9523 	};
9524 	int i;
9525 	FIXTURE_VARIANT(audit_quiet_layout1) variant_2 = {};
9526 
9527 	/* Any open should fail with no logs. */
9528 	for (i = 0; i < ARRAY_SIZE(variant->targets); i++) {
9529 		const struct a_target *target = &variant->targets[i];
9530 
9531 		variant_2.targets[i] = (struct a_target){
9532 			.target = target->target,
9533 			.open_mode = target->open_mode,
9534 			/* We denied everything, open should always fail. */
9535 			.expect_open_success = false,
9536 		};
9537 	}
9538 
9539 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9540 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9541 	ASSERT_EQ(0, apply_a_layer(_metadata, &deny_all_layer));
9542 
9543 	audit_quiet_layout1_test_body(_metadata, self, variant_2.targets);
9544 }
9545 
9546 /*
9547  * An inner layer that denies everything without quiet should produce logs for
9548  * all access.
9549  */
9550 TEST_F(audit_quiet_layout1, deny_all_layer)
9551 {
9552 	struct a_layer deny_all_layer = {
9553 		.handled_access_fs = FS_R | FS_W,
9554 		.quiet_access_fs = FS_R | FS_W,
9555 	};
9556 	int i;
9557 	FIXTURE_VARIANT(audit_quiet_layout1) variant_2 = {};
9558 	bool test_has_subdomains_off = false;
9559 
9560 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++) {
9561 		if (variant->layers[i].restrict_flags &
9562 		    LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF) {
9563 			test_has_subdomains_off = true;
9564 			break;
9565 		}
9566 	}
9567 
9568 	for (i = 0; i < ARRAY_SIZE(variant->targets); i++) {
9569 		const struct a_target *target = &variant->targets[i];
9570 
9571 		variant_2.targets[i] = (struct a_target){
9572 			.target = target->target,
9573 			.open_mode = target->open_mode,
9574 
9575 			/* We denied everything, open should always fail. */
9576 			.expect_open_success = false,
9577 			/* Audit should always happen as long as open request contains read. */
9578 			.audit_read_blocked = !test_has_subdomains_off &&
9579 					      target->open_mode != O_WRONLY,
9580 			/* Audit should always happen as long as open request contains write. */
9581 			.audit_write_blocked = !test_has_subdomains_off &&
9582 					       target->open_mode != O_RDONLY,
9583 		};
9584 	}
9585 
9586 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9587 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9588 	ASSERT_EQ(0, apply_a_layer(_metadata, &deny_all_layer));
9589 
9590 	audit_quiet_layout1_test_body(_metadata, self, variant_2.targets);
9591 }
9592 
9593 /* Uses layout1_bind hierarchy */
9594 FIXTURE(audit_quiet_rename)
9595 {
9596 	struct audit_filter audit_filter;
9597 	int audit_fd;
9598 };
9599 
9600 FIXTURE_SETUP(audit_quiet_rename)
9601 {
9602 	prepare_layout(_metadata);
9603 	create_layout1(_metadata);
9604 
9605 	set_cap(_metadata, CAP_SYS_ADMIN);
9606 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
9607 	clear_cap(_metadata, CAP_SYS_ADMIN);
9608 
9609 	set_cap(_metadata, CAP_AUDIT_CONTROL);
9610 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
9611 	EXPECT_LE(0, self->audit_fd);
9612 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
9613 
9614 	if (getenv("DEBUG_QUIET_TESTS"))
9615 		debug_quiet_tests = true;
9616 }
9617 
9618 FIXTURE_TEARDOWN_PARENT(audit_quiet_rename)
9619 {
9620 	remove_layout1(_metadata);
9621 	cleanup_layout(_metadata);
9622 
9623 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
9624 
9625 	remove_path(file1_s4d1);
9626 	remove_path(file2_s4d1);
9627 
9628 	set_cap(_metadata, CAP_AUDIT_CONTROL);
9629 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
9630 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
9631 }
9632 
9633 static void simple_quiet_rename(struct __test_metadata *const _metadata,
9634 				FIXTURE_DATA(audit_quiet_rename) *const self,
9635 				__u64 handled_access, __u64 quiet_access,
9636 				bool source_allow, bool dest_allow,
9637 				bool source_quiet, bool dest_quiet,
9638 				const char *source_blockers,
9639 				const char *dest_blockers)
9640 {
9641 	/* We will move file1_s1d1 to file1_s2d1 */
9642 	struct a_layer layer = {
9643 		.handled_access_fs = handled_access,
9644 		.quiet_access_fs = quiet_access,
9645 		.rules = {
9646 			{
9647 				.path = dir_s1d1,
9648 				.access = source_allow ? handled_access : 0,
9649 				.quiet = source_quiet,
9650 			},
9651 			{
9652 				.path = dir_s2d1,
9653 				.access = dest_allow ? handled_access : 0,
9654 				.quiet = dest_quiet,
9655 			},
9656 		},
9657 	};
9658 	struct audit_records records = {};
9659 	int ret, err;
9660 
9661 	/* Skip landlock_add_rule for useless rules. */
9662 	if (!source_allow && !source_quiet)
9663 		layer.rules[0].path = NULL;
9664 	if (!dest_allow && !dest_quiet)
9665 		layer.rules[1].path = NULL;
9666 
9667 	EXPECT_EQ(0, unlink(file1_s2d1));
9668 	EXPECT_EQ(0, apply_a_layer(_metadata, &layer));
9669 
9670 	if (debug_quiet_tests)
9671 		TH_LOG("Try renameat \"%s\" to \"%s\"", file1_s1d1, file1_s2d1);
9672 	ret = renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1);
9673 	err = errno;
9674 	if (ret != 0 && debug_quiet_tests) {
9675 		TH_LOG("renameat error: %s", err == EXDEV  ? "EXDEV" :
9676 					     err == EACCES ? "EACCES" :
9677 							     strerror(err));
9678 	}
9679 	if (source_allow && dest_allow) {
9680 		ASSERT_EQ(0, ret);
9681 	} else {
9682 		ASSERT_EQ(-1, ret);
9683 		if (handled_access & (LANDLOCK_ACCESS_FS_MAKE_REG |
9684 				      LANDLOCK_ACCESS_FS_REMOVE_FILE)) {
9685 			ASSERT_EQ(EACCES, err);
9686 		} else {
9687 			ASSERT_EQ(EXDEV, err);
9688 		}
9689 
9690 		if (source_blockers)
9691 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9692 						    source_blockers, dir_s1d1));
9693 		if (dest_blockers)
9694 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9695 						    dest_blockers, dir_s2d1));
9696 	}
9697 	/*
9698 	 * No other logs. records.domain not checked per reasoning in
9699 	 * audit_quiet_layout1_test_body.
9700 	 */
9701 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9702 	ASSERT_EQ(0, records.access);
9703 }
9704 
9705 TEST_F(audit_quiet_rename, rename_ok)
9706 {
9707 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9708 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9709 		       LANDLOCK_ACCESS_FS_REFER;
9710 
9711 	simple_quiet_rename(_metadata, self, access, access, true, true, false,
9712 			    false, NULL, NULL);
9713 }
9714 
9715 TEST_F(audit_quiet_rename, no_quiet)
9716 {
9717 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9718 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9719 		       LANDLOCK_ACCESS_FS_REFER;
9720 
9721 	simple_quiet_rename(_metadata, self, access, access, false, false,
9722 			    false, false, "fs\\.remove_file,fs\\.refer",
9723 			    "fs\\.make_reg,fs\\.refer");
9724 }
9725 
9726 TEST_F(audit_quiet_rename, quiet)
9727 {
9728 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9729 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9730 		       LANDLOCK_ACCESS_FS_REFER;
9731 
9732 	simple_quiet_rename(_metadata, self, access, access, false, false, true,
9733 			    true, NULL, NULL);
9734 }
9735 
9736 TEST_F(audit_quiet_rename, source_no_quiet_dest_quiet)
9737 {
9738 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9739 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9740 		       LANDLOCK_ACCESS_FS_REFER;
9741 
9742 	simple_quiet_rename(_metadata, self, access, access, false, false,
9743 			    false, true, "fs\\.remove_file,fs\\.refer", NULL);
9744 }
9745 
9746 TEST_F(audit_quiet_rename, source_quiet_dest_no_quiet)
9747 {
9748 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9749 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9750 		       LANDLOCK_ACCESS_FS_REFER;
9751 
9752 	simple_quiet_rename(_metadata, self, access, access, false, false, true,
9753 			    false, NULL, "fs\\.make_reg,fs\\.refer");
9754 }
9755 
9756 TEST_F(audit_quiet_rename, only_quiet_refer)
9757 {
9758 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9759 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9760 		       LANDLOCK_ACCESS_FS_REFER;
9761 
9762 	simple_quiet_rename(_metadata, self, access, LANDLOCK_ACCESS_FS_REFER,
9763 			    false, false, true, true,
9764 			    "fs\\.remove_file,fs\\.refer",
9765 			    "fs\\.make_reg,fs\\.refer");
9766 }
9767 
9768 TEST_F(audit_quiet_rename, source_allow_dest_quiet)
9769 {
9770 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9771 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9772 		       LANDLOCK_ACCESS_FS_REFER;
9773 
9774 	simple_quiet_rename(_metadata, self, access, access, true, false, false,
9775 			    true, NULL, NULL);
9776 }
9777 
9778 TEST_F(audit_quiet_rename, source_quiet_dest_allow)
9779 {
9780 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9781 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9782 		       LANDLOCK_ACCESS_FS_REFER;
9783 
9784 	simple_quiet_rename(_metadata, self, access, access, false, true, true,
9785 			    false, NULL, NULL);
9786 }
9787 
9788 TEST_F(audit_quiet_rename, handle_all_deny_quiet_refer)
9789 {
9790 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9791 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9792 		       LANDLOCK_ACCESS_FS_REFER;
9793 	struct a_layer layer = {
9794 		.handled_access_fs = access,
9795 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
9796 		.rules = {
9797 			{
9798 				.path = dir_s1d1,
9799 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9800 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9801 				.quiet = true,
9802 			},
9803 			{
9804 				.path = dir_s2d1,
9805 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9806 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9807 				.quiet = true,
9808 			},
9809 		},
9810 	};
9811 	struct audit_records records = {};
9812 
9813 	EXPECT_EQ(0, unlink(file1_s2d1));
9814 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9815 
9816 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9817 	ASSERT_EQ(EXDEV, errno);
9818 
9819 	/* No logs */
9820 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9821 	ASSERT_EQ(0, records.access);
9822 }
9823 
9824 TEST_F(audit_quiet_rename, handle_all_deny_not_quiet_refer)
9825 {
9826 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9827 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9828 		       LANDLOCK_ACCESS_FS_REFER;
9829 	struct a_layer layer = {
9830 		.handled_access_fs = access,
9831 		.quiet_access_fs = 0,
9832 		.rules = {
9833 			{
9834 				.path = dir_s1d1,
9835 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9836 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9837 				.quiet = false,
9838 			},
9839 			{
9840 				.path = dir_s2d1,
9841 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9842 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9843 				.quiet = false,
9844 			},
9845 		},
9846 	};
9847 	struct audit_records records = {};
9848 
9849 	EXPECT_EQ(0, unlink(file1_s2d1));
9850 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9851 
9852 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9853 	ASSERT_EQ(EXDEV, errno);
9854 
9855 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9856 				    dir_s1d1));
9857 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9858 				    dir_s2d1));
9859 
9860 	/* No other logs */
9861 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9862 	ASSERT_EQ(0, records.access);
9863 }
9864 
9865 TEST_F(audit_quiet_rename, handle_all_deny_refer_quiet_source_not_quiet_dest)
9866 {
9867 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9868 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9869 		       LANDLOCK_ACCESS_FS_REFER;
9870 	struct a_layer layer = {
9871 		.handled_access_fs = access,
9872 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
9873 		.rules = {
9874 			{
9875 				.path = dir_s1d1,
9876 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9877 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9878 				.quiet = true,
9879 			},
9880 			{
9881 				.path = dir_s2d1,
9882 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9883 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9884 				.quiet = false,
9885 			},
9886 		},
9887 	};
9888 	struct audit_records records = {};
9889 
9890 	EXPECT_EQ(0, unlink(file1_s2d1));
9891 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9892 
9893 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9894 	ASSERT_EQ(EXDEV, errno);
9895 
9896 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9897 				    dir_s2d1));
9898 
9899 	/* No other logs */
9900 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9901 	ASSERT_EQ(0, records.access);
9902 }
9903 
9904 TEST_F(audit_quiet_rename, quiet_same_dir)
9905 {
9906 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9907 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9908 		       LANDLOCK_ACCESS_FS_REFER;
9909 	struct a_layer layer = {
9910 		.handled_access_fs = access,
9911 		.quiet_access_fs = access,
9912 		.rules = {
9913 			{
9914 				.path = dir_s1d1,
9915 				.access = 0,
9916 				.quiet = true,
9917 			},
9918 		},
9919 	};
9920 	struct audit_records records = {};
9921 
9922 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9923 
9924 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1));
9925 	ASSERT_EQ(EACCES, errno);
9926 
9927 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9928 	ASSERT_EQ(0, records.access);
9929 }
9930 
9931 TEST_F(audit_quiet_rename, quiet_flag_on_file_ignored)
9932 {
9933 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9934 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9935 		       LANDLOCK_ACCESS_FS_REFER;
9936 	struct a_layer layer = {
9937 		.handled_access_fs = access,
9938 		.quiet_access_fs = access,
9939 		.rules = {
9940 			{
9941 				.path = file1_s1d1,
9942 				.access = 0,
9943 				.quiet = true,
9944 			},
9945 			{
9946 				.path = file1_s2d1,
9947 				.access = 0,
9948 				.quiet = true,
9949 			},
9950 		},
9951 	};
9952 	struct audit_records records = {};
9953 
9954 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9955 
9956 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9957 	ASSERT_EQ(EACCES, errno);
9958 
9959 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9960 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
9961 	/* We didn't unlink destination file */
9962 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9963 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
9964 				    dir_s2d1));
9965 
9966 	/* No other logs */
9967 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9968 	ASSERT_EQ(0, records.access);
9969 }
9970 
9971 TEST_F(audit_quiet_rename, quiet_flag_on_file_ignored_same_dir)
9972 {
9973 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9974 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9975 		       LANDLOCK_ACCESS_FS_REFER;
9976 	struct a_layer layer = {
9977 		.handled_access_fs = access,
9978 		.quiet_access_fs = access,
9979 		.rules = {
9980 			{
9981 				.path = file1_s1d1,
9982 				.access = 0,
9983 				.quiet = true,
9984 			},
9985 			{
9986 				.path = file2_s1d1,
9987 				.access = 0,
9988 				.quiet = true,
9989 			},
9990 		},
9991 	};
9992 	struct audit_records records = {};
9993 
9994 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9995 
9996 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1));
9997 	ASSERT_EQ(EACCES, errno);
9998 
9999 	ASSERT_EQ(0,
10000 		  matches_log_fs(_metadata, self->audit_fd,
10001 				 "fs\\.remove_file,fs\\.make_reg", dir_s1d1));
10002 
10003 	/* No other logs */
10004 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10005 	ASSERT_EQ(0, records.access);
10006 }
10007 
10008 TEST_F(audit_quiet_rename, two_layers_different_quiet1)
10009 {
10010 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10011 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10012 		       LANDLOCK_ACCESS_FS_REFER;
10013 	struct a_layer layer1 = {
10014 		.handled_access_fs = access,
10015 		.quiet_access_fs = access,
10016 		.rules = {
10017 			{
10018 				.path = dir_s1d1,
10019 				.access = access,
10020 				.quiet = false,
10021 			},
10022 			{
10023 				.path = dir_s2d1,
10024 				.access = 0,
10025 				.quiet = true,
10026 			},
10027 		},
10028 	};
10029 	struct a_layer layer2 = {
10030 		.handled_access_fs = access,
10031 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
10032 		.rules = {
10033 			{
10034 				.path = dir_s1d1,
10035 				.access = 0,
10036 				.quiet = true,
10037 			},
10038 			{
10039 				.path = dir_s2d1,
10040 				.access = access,
10041 				.quiet = false,
10042 			},
10043 		},
10044 	};
10045 	struct audit_records records = {};
10046 
10047 	EXPECT_EQ(0, unlink(file1_s2d1));
10048 
10049 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10050 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10051 
10052 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10053 	ASSERT_EQ(EACCES, errno);
10054 
10055 	/*
10056 	 * The youngest denial will be layer 2.  Refer is quieted but we are
10057 	 * also missing remove_file on source.
10058 	 */
10059 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10060 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
10061 	/* No other logs */
10062 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10063 	ASSERT_EQ(0, records.access);
10064 }
10065 
10066 TEST_F(audit_quiet_rename, two_layers_different_quiet2)
10067 {
10068 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10069 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10070 		       LANDLOCK_ACCESS_FS_REFER;
10071 	struct a_layer layer1 = {
10072 		.handled_access_fs = access,
10073 		.quiet_access_fs = access,
10074 		.rules = {
10075 			{
10076 				.path = dir_s1d1,
10077 				.access = access,
10078 				.quiet = false,
10079 			},
10080 			{
10081 				.path = dir_s2d1,
10082 				.access = 0,
10083 				.quiet = true,
10084 			},
10085 		},
10086 	};
10087 	struct a_layer layer2 = {
10088 		.handled_access_fs = LANDLOCK_ACCESS_FS_REFER,
10089 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
10090 		.rules = {
10091 			{
10092 				.path = dir_s1d1,
10093 				.access = 0,
10094 				.quiet = true,
10095 			},
10096 			{
10097 				.path = dir_s2d1,
10098 				.access = LANDLOCK_ACCESS_FS_REFER,
10099 				.quiet = false,
10100 			},
10101 		},
10102 	};
10103 	struct audit_records records = {};
10104 
10105 	EXPECT_EQ(0, unlink(file1_s2d1));
10106 
10107 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10108 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10109 
10110 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10111 	ASSERT_EQ(EACCES, errno);
10112 
10113 	/*
10114 	 * The youngest denial will be layer 2, but refer is quieted (and that
10115 	 * layer does not handle any other accesses).
10116 	 */
10117 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10118 	ASSERT_EQ(0, records.access);
10119 }
10120 
10121 TEST_F(audit_quiet_rename, two_layers_different_quiet3)
10122 {
10123 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10124 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10125 		       LANDLOCK_ACCESS_FS_REFER;
10126 	struct a_layer layer1 = {
10127 		.handled_access_fs = access,
10128 		.quiet_access_fs = access,
10129 		.rules = {
10130 			{
10131 				.path = dir_s1d1,
10132 				.access = access,
10133 				.quiet = false,
10134 			},
10135 			{
10136 				.path = dir_s2d1,
10137 				.access = 0,
10138 				.quiet = true,
10139 			},
10140 		},
10141 	};
10142 	struct a_layer layer2 = {
10143 		.handled_access_fs = access,
10144 		.quiet_access_fs = access,
10145 		.rules = {
10146 			{
10147 				.path = dir_s1d1,
10148 				.access = 0,
10149 				.quiet = true,
10150 			},
10151 			{
10152 				.path = dir_s2d1,
10153 				.access = access,
10154 				.quiet = false,
10155 			},
10156 		},
10157 	};
10158 	struct audit_records records = {};
10159 
10160 	EXPECT_EQ(0, unlink(file1_s2d1));
10161 
10162 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10163 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10164 
10165 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10166 	ASSERT_EQ(EACCES, errno);
10167 
10168 	/*
10169 	 * The youngest denial will be layer 2, in which everything is quieted.
10170 	 */
10171 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10172 	ASSERT_EQ(0, records.access);
10173 }
10174 
10175 TEST_F(audit_quiet_rename,
10176        first_layer_quiet_deny_all_second_layer_not_quiet_deny_all)
10177 {
10178 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10179 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10180 		       LANDLOCK_ACCESS_FS_REFER;
10181 	struct a_layer layer1 = {
10182 		.handled_access_fs = access,
10183 		.quiet_access_fs = access,
10184 		.rules = {
10185 			{
10186 				.path = dir_s1d1,
10187 				.access = 0,
10188 				.quiet = true,
10189 			},
10190 			{
10191 				.path = dir_s2d1,
10192 				.access = 0,
10193 				.quiet = true,
10194 			},
10195 		},
10196 	};
10197 	struct a_layer layer2 = {
10198 		.handled_access_fs = access,
10199 		.quiet_access_fs = access,
10200 		.rules = {},
10201 	};
10202 	struct audit_records records = {};
10203 
10204 	EXPECT_EQ(0, unlink(file1_s2d1));
10205 
10206 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10207 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10208 
10209 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10210 	ASSERT_EQ(EACCES, errno);
10211 
10212 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10213 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
10214 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10215 				    "fs\\.make_reg,fs\\.refer", dir_s2d1));
10216 	/* No other logs. */
10217 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10218 	ASSERT_EQ(0, records.access);
10219 }
10220 
10221 TEST_F(audit_quiet_rename,
10222        first_layer_quiet_deny_all_second_layer_dest_not_quiet)
10223 {
10224 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10225 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10226 		       LANDLOCK_ACCESS_FS_REFER;
10227 	struct a_layer layer1 = {
10228 		.handled_access_fs = access,
10229 		.quiet_access_fs = access,
10230 		.rules = {
10231 			{
10232 				.path = dir_s1d1,
10233 				.access = 0,
10234 				.quiet = true,
10235 			},
10236 			{
10237 				.path = dir_s2d1,
10238 				.access = 0,
10239 				.quiet = true,
10240 			},
10241 		},
10242 	};
10243 	struct a_layer layer2 = {
10244 		.handled_access_fs = access,
10245 		.quiet_access_fs = access,
10246 		.rules = {
10247 			{
10248 				.path = dir_s1d1,
10249 				.access = 0,
10250 				.quiet = true,
10251 			},
10252 		},
10253 	};
10254 	struct audit_records records = {};
10255 
10256 	EXPECT_EQ(0, unlink(file1_s2d1));
10257 
10258 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10259 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10260 
10261 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10262 	ASSERT_EQ(EACCES, errno);
10263 
10264 	/* Source is quieted but destination is not. */
10265 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10266 				    "fs\\.make_reg,fs\\.refer", dir_s2d1));
10267 	/* No other logs. */
10268 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10269 	ASSERT_EQ(0, records.access);
10270 }
10271 
10272 TEST_F(audit_quiet_rename, rename_xchg)
10273 {
10274 	struct a_layer layer = {
10275 		.handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_REG |
10276 				     LANDLOCK_ACCESS_FS_REMOVE_FILE |
10277 				     LANDLOCK_ACCESS_FS_REFER,
10278 		.quiet_access_fs = LANDLOCK_ACCESS_FS_MAKE_REG,
10279 		.rules = { {
10280 				   .path = dir_s1d1,
10281 				   .access = LANDLOCK_ACCESS_FS_REMOVE_FILE |
10282 					     LANDLOCK_ACCESS_FS_REFER,
10283 				   .quiet = true,
10284 			   },
10285 			   {
10286 				   .path = dir_s2d1,
10287 				   .access = LANDLOCK_ACCESS_FS_MAKE_REG |
10288 					     LANDLOCK_ACCESS_FS_REMOVE_FILE |
10289 					     LANDLOCK_ACCESS_FS_REFER,
10290 				   .quiet = false,
10291 			   } },
10292 	};
10293 	struct audit_records records = {};
10294 
10295 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10296 
10297 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1,
10298 				RENAME_EXCHANGE));
10299 	ASSERT_EQ(EACCES, errno);
10300 
10301 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10302 	ASSERT_EQ(0, records.access);
10303 }
10304 
10305 TEST_F(audit_quiet_rename, quiet_on_parent_mount)
10306 {
10307 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10308 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10309 		       LANDLOCK_ACCESS_FS_REFER;
10310 	struct a_layer layer = {
10311 		.handled_access_fs = access,
10312 		.quiet_access_fs = access,
10313 		.rules = {
10314 			{
10315 				.path = dir_s2d1,
10316 				.access = 0,
10317 				.quiet = true,
10318 			},
10319 		},
10320 	};
10321 	struct audit_records records = {};
10322 
10323 	EXPECT_EQ(0, unlink(file2_s1d3));
10324 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10325 
10326 	ASSERT_EQ(-1, renameat(AT_FDCWD, bind_file1_s1d3, AT_FDCWD,
10327 			       bind_file2_s1d3));
10328 	ASSERT_EQ(EACCES, errno);
10329 
10330 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10331 	ASSERT_EQ(0, records.access);
10332 }
10333 
10334 TEST_F(audit_quiet_rename, quiet_behind_mountpoint_ignored)
10335 {
10336 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10337 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10338 		       LANDLOCK_ACCESS_FS_REFER;
10339 	struct a_layer layer = {
10340 		.handled_access_fs = access,
10341 		.quiet_access_fs = access,
10342 		.rules = {
10343 			{
10344 				.path = dir_s1d1,
10345 				.access = 0,
10346 				.quiet = true,
10347 			},
10348 		},
10349 	};
10350 	struct audit_records records = {};
10351 
10352 	EXPECT_EQ(0, unlink(file2_s1d3));
10353 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10354 
10355 	ASSERT_EQ(-1, renameat(AT_FDCWD, bind_file1_s1d3, AT_FDCWD,
10356 			       bind_file2_s1d3));
10357 	ASSERT_EQ(EACCES, errno);
10358 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10359 				    "fs\\.remove_file,fs\\.make_reg",
10360 				    bind_dir_s1d3));
10361 
10362 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10363 	ASSERT_EQ(0, records.access);
10364 }
10365 
10366 TEST_F(audit_quiet_rename, quiet_on_parent_mount_disconnected)
10367 {
10368 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10369 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10370 		       LANDLOCK_ACCESS_FS_REFER;
10371 	struct a_layer layer = {
10372 		.handled_access_fs = access,
10373 		.quiet_access_fs = access,
10374 		.rules = {
10375 			{
10376 				.path = dir_s2d1,
10377 				.access = 0,
10378 				.quiet = true,
10379 			},
10380 		},
10381 	};
10382 	struct audit_records records = {};
10383 	int bind_s1d3_fd;
10384 
10385 	EXPECT_EQ(0, unlink(file2_s1d3));
10386 
10387 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_DIRECTORY);
10388 	ASSERT_GE(bind_s1d3_fd, 0);
10389 
10390 	/* Make s1d3 disconnected. */
10391 	create_directory(_metadata, dir_s4d1);
10392 	ASSERT_EQ(0, renameat(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s4d2));
10393 
10394 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10395 
10396 	ASSERT_EQ(-1,
10397 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name));
10398 	ASSERT_EQ(EACCES, errno);
10399 
10400 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10401 	ASSERT_EQ(0, records.access);
10402 }
10403 
10404 TEST_F(audit_quiet_rename, quiet_behind_mountpoint_disconnected)
10405 {
10406 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10407 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10408 		       LANDLOCK_ACCESS_FS_REFER;
10409 	struct a_layer layer = {
10410 		.handled_access_fs = access,
10411 		.quiet_access_fs = access,
10412 		.rules = {
10413 			{
10414 				.path = dir_s4d1,
10415 				.access = 0,
10416 				.quiet = true,
10417 			},
10418 		},
10419 	};
10420 	struct audit_records records = {};
10421 	int bind_s1d3_fd;
10422 
10423 	EXPECT_EQ(0, unlink(file2_s1d3));
10424 
10425 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_DIRECTORY);
10426 	ASSERT_GE(bind_s1d3_fd, 0);
10427 
10428 	/* Make s1d3 disconnected. */
10429 	create_directory(_metadata, dir_s4d1);
10430 	ASSERT_EQ(0, renameat(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s4d2));
10431 
10432 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10433 
10434 	ASSERT_EQ(-1,
10435 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name));
10436 	ASSERT_EQ(EACCES, errno);
10437 
10438 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10439 	ASSERT_EQ(0, records.access);
10440 }
10441 
10442 /* clang-format off */
10443 FIXTURE(trace_layout1) {
10444 	/* clang-format on */
10445 	int tracefs_ok;
10446 };
10447 
10448 FIXTURE_SETUP(trace_layout1)
10449 {
10450 	struct stat st;
10451 
10452 	/*
10453 	 * Check tracefs availability before creating the layout, following the
10454 	 * layout3_fs pattern: skip before any layout creation to avoid leaving
10455 	 * stale TMP_DIR on skip.
10456 	 */
10457 	if (stat(TRACEFS_LANDLOCK_DIR, &st)) {
10458 		self->tracefs_ok = 0;
10459 		SKIP(return, "tracefs not available");
10460 	}
10461 	self->tracefs_ok = 1;
10462 
10463 	/* Isolate tracefs state (PID filter, event enables). */
10464 	set_cap(_metadata, CAP_SYS_ADMIN);
10465 	ASSERT_EQ(0, unshare(CLONE_NEWNS));
10466 	ASSERT_EQ(0, mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL));
10467 	clear_cap(_metadata, CAP_SYS_ADMIN);
10468 
10469 	prepare_layout(_metadata);
10470 	create_layout1(_metadata);
10471 
10472 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10473 	ASSERT_EQ(0, tracefs_fixture_setup());
10474 	ASSERT_EQ(0, tracefs_enable_event(TRACEFS_CHECK_RULE_FS_ENABLE, true));
10475 	ASSERT_EQ(0, tracefs_clear());
10476 	ASSERT_EQ(0, tracefs_set_pid_filter(getpid()));
10477 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10478 }
10479 
10480 FIXTURE_TEARDOWN_PARENT(trace_layout1)
10481 {
10482 	if (!self->tracefs_ok)
10483 		return;
10484 
10485 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10486 	tracefs_enable_event(TRACEFS_CHECK_RULE_FS_ENABLE, false);
10487 	tracefs_clear_pid_filter();
10488 	tracefs_fixture_teardown();
10489 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10490 
10491 	remove_layout1(_metadata);
10492 	cleanup_layout(_metadata);
10493 }
10494 
10495 /*
10496  * Verifies that check_rule_fs events include correct field values: domain, dev,
10497  * ino, access_request, and grants.  All values are verified against stat() of
10498  * the rule path on a deterministic tmpfs layout.
10499  */
10500 TEST_F(trace_layout1, check_rule_fs_fields)
10501 {
10502 	struct stat dir_stat;
10503 	char expected_dev[32];
10504 	char expected_ino[32];
10505 	char *buf;
10506 	char field[64];
10507 
10508 	if (!self->tracefs_ok)
10509 		SKIP(return, "tracefs not available");
10510 
10511 	ASSERT_EQ(0, stat(dir_s1d1, &dir_stat));
10512 	snprintf(expected_dev, sizeof(expected_dev), "%u:%u",
10513 		 major(dir_stat.st_dev), minor(dir_stat.st_dev));
10514 	snprintf(expected_ino, sizeof(expected_ino), "%lu", dir_stat.st_ino);
10515 
10516 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10517 	ASSERT_EQ(0, tracefs_clear());
10518 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10519 
10520 	sandbox_child_fs_access(_metadata, dir_s1d1,
10521 				LANDLOCK_ACCESS_FS_READ_DIR,
10522 				LANDLOCK_ACCESS_FS_READ_DIR, dir_s1d1);
10523 
10524 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10525 	buf = tracefs_read_trace();
10526 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10527 	ASSERT_NE(NULL, buf);
10528 
10529 	EXPECT_EQ(1,
10530 		  tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK)))
10531 	{
10532 		TH_LOG("Expected 1 check_rule_fs event\n%s", buf);
10533 	}
10534 
10535 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10536 					   "dev", field, sizeof(field)));
10537 	EXPECT_STREQ(expected_dev, field)
10538 	{
10539 		TH_LOG("Expected dev=%s, got %s", expected_dev, field);
10540 	}
10541 
10542 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10543 					   "ino", field, sizeof(field)));
10544 	EXPECT_STREQ(expected_ino, field)
10545 	{
10546 		TH_LOG("Expected ino=%s, got %s", expected_ino, field);
10547 	}
10548 
10549 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10550 					   "access_request", field,
10551 					   sizeof(field)));
10552 	EXPECT_STREQ("read_dir", field)
10553 	{
10554 		TH_LOG("Expected access_request=read_dir, got %s", field);
10555 	}
10556 
10557 	/*
10558 	 * The domain handles only READ_DIR, so the rule carries the
10559 	 * unhandled-rights padding; intersecting with the request leaves just
10560 	 * the requested read_dir (no padding, no hex).
10561 	 */
10562 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10563 					   "grants", field, sizeof(field)));
10564 	EXPECT_STREQ("{read_dir}", field)
10565 	{
10566 		TH_LOG("Expected grants={read_dir}, got %s", field);
10567 	}
10568 
10569 	free(buf);
10570 }
10571 
10572 /*
10573  * Verifies check_rule_fs behavior with multiple rules.  With rules at s1d1 and
10574  * s1d2 (a child of s1d1), accessing s1d2 produces only 1 event because the
10575  * pathwalk short-circuits after the first rule fully unmasks the single layer.
10576  */
10577 TEST_F(trace_layout1, check_rule_fs_multiple_rules)
10578 {
10579 	pid_t pid;
10580 	int status;
10581 	char *buf;
10582 	int count;
10583 
10584 	if (!self->tracefs_ok)
10585 		SKIP(return, "tracefs not available");
10586 
10587 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10588 	ASSERT_EQ(0, tracefs_clear());
10589 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10590 
10591 	pid = fork();
10592 	ASSERT_LE(0, pid);
10593 
10594 	if (pid == 0) {
10595 		struct landlock_ruleset_attr attr = {
10596 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
10597 		};
10598 		struct landlock_path_beneath_attr path_beneath = {
10599 			.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
10600 		};
10601 		int ruleset_fd, fd;
10602 
10603 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10604 		if (ruleset_fd < 0)
10605 			_exit(1);
10606 
10607 		path_beneath.parent_fd =
10608 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10609 		if (path_beneath.parent_fd < 0)
10610 			_exit(1);
10611 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10612 				      &path_beneath, 0))
10613 			_exit(1);
10614 		close(path_beneath.parent_fd);
10615 
10616 		path_beneath.parent_fd =
10617 			open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
10618 		if (path_beneath.parent_fd < 0)
10619 			_exit(1);
10620 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10621 				      &path_beneath, 0))
10622 			_exit(1);
10623 		close(path_beneath.parent_fd);
10624 
10625 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10626 		if (landlock_restrict_self(ruleset_fd, 0))
10627 			_exit(1);
10628 		close(ruleset_fd);
10629 
10630 		fd = open(dir_s1d2, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
10631 		if (fd >= 0)
10632 			close(fd);
10633 		_exit(0);
10634 	}
10635 
10636 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10637 	ASSERT_TRUE(WIFEXITED(status));
10638 	EXPECT_EQ(0, WEXITSTATUS(status));
10639 
10640 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10641 	buf = tracefs_read_trace();
10642 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10643 	ASSERT_NE(NULL, buf);
10644 
10645 	/*
10646 	 * Only 1 check_rule_fs event: the rule on dir_s1d2 fully unmasked the
10647 	 * single layer, so the pathwalk short-circuits before reaching the
10648 	 * dir_s1d1 rule.
10649 	 */
10650 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10651 	EXPECT_EQ(1, count)
10652 	{
10653 		TH_LOG("Expected 1 check_rule_fs event, got %d\n%s", count,
10654 		       buf);
10655 	}
10656 
10657 	free(buf);
10658 }
10659 
10660 /*
10661  * Verifies the grants array is intersected with the request: a handled,
10662  * granted, but unrequested right (execute) is filtered out, leaving only the
10663  * requested read_dir.
10664  */
10665 TEST_F(trace_layout1, check_rule_fs_request_subset)
10666 {
10667 	char *buf;
10668 	char field[64];
10669 
10670 	if (!self->tracefs_ok)
10671 		SKIP(return, "tracefs not available");
10672 
10673 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10674 	ASSERT_EQ(0, tracefs_clear());
10675 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10676 
10677 	/*
10678 	 * Handle and grant READ_DIR|EXECUTE; the open only requests read_dir.
10679 	 */
10680 	sandbox_child_fs_access(
10681 		_metadata, dir_s1d1,
10682 		LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_EXECUTE,
10683 		LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_EXECUTE,
10684 		dir_s1d1);
10685 
10686 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10687 	buf = tracefs_read_trace();
10688 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10689 	ASSERT_NE(NULL, buf);
10690 
10691 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10692 					   "access_request", field,
10693 					   sizeof(field)));
10694 	EXPECT_STREQ("read_dir", field);
10695 
10696 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10697 					   "grants", field, sizeof(field)));
10698 	EXPECT_STREQ("{read_dir}", field);
10699 
10700 	free(buf);
10701 }
10702 
10703 /*
10704  * Verifies that the optional TRUNCATE access right, which hook_file_open()
10705  * speculatively evaluates on every open, appears in the access_request= and
10706  * grants= fields.  Opening file1_s1d1 read-only needs only read_file, but the
10707  * open hook also evaluates truncate; the domain handles and the rule grants
10708  * both, so the event reports access_request=read_file|truncate and
10709  * grants={read_file|truncate}, and the open is allowed.
10710  */
10711 TEST_F(trace_layout1, check_rule_fs_optional_access)
10712 {
10713 	pid_t pid;
10714 	int status;
10715 	char *buf;
10716 	char field[64];
10717 	int count;
10718 
10719 	if (!self->tracefs_ok)
10720 		SKIP(return, "tracefs not available");
10721 
10722 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10723 	ASSERT_EQ(0, tracefs_clear());
10724 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10725 
10726 	pid = fork();
10727 	ASSERT_LE(0, pid);
10728 
10729 	if (pid == 0) {
10730 		struct landlock_ruleset_attr attr = {
10731 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
10732 					     LANDLOCK_ACCESS_FS_TRUNCATE,
10733 		};
10734 		struct landlock_path_beneath_attr path_beneath = {
10735 			.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
10736 					  LANDLOCK_ACCESS_FS_TRUNCATE,
10737 		};
10738 		int ruleset_fd, fd;
10739 
10740 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10741 		if (ruleset_fd < 0)
10742 			_exit(1);
10743 
10744 		path_beneath.parent_fd =
10745 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10746 		if (path_beneath.parent_fd < 0)
10747 			_exit(1);
10748 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10749 				      &path_beneath, 0))
10750 			_exit(1);
10751 		close(path_beneath.parent_fd);
10752 
10753 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10754 		if (landlock_restrict_self(ruleset_fd, 0))
10755 			_exit(1);
10756 		close(ruleset_fd);
10757 
10758 		/* Read-only open needs only read_file; truncate is optional. */
10759 		fd = open(file1_s1d1, O_RDONLY | O_CLOEXEC);
10760 		if (fd < 0)
10761 			_exit(1);
10762 		close(fd);
10763 		_exit(0);
10764 	}
10765 
10766 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10767 	ASSERT_TRUE(WIFEXITED(status));
10768 	/* The open is allowed: the required read_file is granted. */
10769 	EXPECT_EQ(0, WEXITSTATUS(status));
10770 
10771 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10772 	buf = tracefs_read_trace();
10773 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10774 	ASSERT_NE(NULL, buf);
10775 
10776 	/* The rule at dir_s1d1 matches when opening file1_s1d1. */
10777 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10778 	EXPECT_EQ(1, count)
10779 	{
10780 		TH_LOG("Expected 1 check_rule_fs event, got %d\n%s", count,
10781 		       buf);
10782 	}
10783 
10784 	/* The open hook adds the optional truncate to the request. */
10785 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10786 					   "access_request", field,
10787 					   sizeof(field)));
10788 	EXPECT_STREQ("read_file|truncate", field);
10789 
10790 	/* The rule grants both, so truncate appears in the grants array. */
10791 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10792 					   "grants", field, sizeof(field)));
10793 	EXPECT_STREQ("{read_file|truncate}", field);
10794 
10795 	free(buf);
10796 }
10797 
10798 /*
10799  * Verifies that check_rule_fs fires for a rule that matches the inode even when
10800  * it grants none of the requested rights, so the grants set is empty.  Landlock
10801  * cannot know a rule ignores the request before reading it, so the event is
10802  * still emitted (grants={}), which lets a tracer see that the rule matched.
10803  * The domain handles READ_DIR|EXECUTE, dir_s1d2 grants only EXECUTE and its
10804  * parent dir_s1d1 grants only READ_DIR.  Reading dir_s1d2 (requesting read_dir)
10805  * first matches the dir_s1d2 rule, which grants nothing requested (grants={});
10806  * walking up to dir_s1d1 then grants read_dir (grants={read_dir}) and allows
10807  * the access.
10808  */
10809 TEST_F(trace_layout1, check_rule_fs_empty_grant)
10810 {
10811 	pid_t pid;
10812 	int status;
10813 	char *buf;
10814 	int count;
10815 
10816 	if (!self->tracefs_ok)
10817 		SKIP(return, "tracefs not available");
10818 
10819 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10820 	ASSERT_EQ(0, tracefs_clear());
10821 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10822 
10823 	pid = fork();
10824 	ASSERT_LE(0, pid);
10825 
10826 	if (pid == 0) {
10827 		struct landlock_ruleset_attr attr = {
10828 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR |
10829 					     LANDLOCK_ACCESS_FS_EXECUTE,
10830 		};
10831 		struct landlock_path_beneath_attr path_beneath = {};
10832 		int ruleset_fd, fd;
10833 
10834 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10835 		if (ruleset_fd < 0)
10836 			_exit(1);
10837 
10838 		/* Parent dir_s1d1 grants only READ_DIR. */
10839 		path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR;
10840 		path_beneath.parent_fd =
10841 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10842 		if (path_beneath.parent_fd < 0)
10843 			_exit(1);
10844 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10845 				      &path_beneath, 0))
10846 			_exit(1);
10847 		close(path_beneath.parent_fd);
10848 
10849 		/* Child dir_s1d2 grants only EXECUTE. */
10850 		path_beneath.allowed_access = LANDLOCK_ACCESS_FS_EXECUTE;
10851 		path_beneath.parent_fd =
10852 			open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
10853 		if (path_beneath.parent_fd < 0)
10854 			_exit(1);
10855 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10856 				      &path_beneath, 0))
10857 			_exit(1);
10858 		close(path_beneath.parent_fd);
10859 
10860 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10861 		if (landlock_restrict_self(ruleset_fd, 0))
10862 			_exit(1);
10863 		close(ruleset_fd);
10864 
10865 		fd = open(dir_s1d2, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
10866 		if (fd < 0)
10867 			_exit(1);
10868 		close(fd);
10869 		_exit(0);
10870 	}
10871 
10872 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10873 	ASSERT_TRUE(WIFEXITED(status));
10874 	EXPECT_EQ(0, WEXITSTATUS(status));
10875 
10876 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10877 	buf = tracefs_read_trace();
10878 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10879 	ASSERT_NE(NULL, buf);
10880 
10881 	/*
10882 	 * dir_s1d2 (grants nothing requested) then dir_s1d1 (grants read_dir).
10883 	 */
10884 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10885 	EXPECT_EQ(2, count)
10886 	{
10887 		TH_LOG("Expected 2 check_rule_fs events, got %d\n%s", count,
10888 		       buf);
10889 	}
10890 
10891 	/* The dir_s1d2 rule matches the inode but grants none of read_dir. */
10892 	EXPECT_EQ(
10893 		1,
10894 		tracefs_count_matches(
10895 			buf,
10896 			TRACE_PREFIX(
10897 				TRACE_TASK) "landlock_check_rule_fs: domain=[0-9a-f]\\+ "
10898 					    "access_request=read_dir "
10899 					    "dev=[0-9]\\+:[0-9]\\+ ino=[0-9]\\+ "
10900 					    "grants={}$"))
10901 	{
10902 		TH_LOG("Expected a grants={} event\n%s", buf);
10903 	}
10904 
10905 	/* Walking up to dir_s1d1 grants the requested read_dir. */
10906 	EXPECT_EQ(
10907 		1,
10908 		tracefs_count_matches(
10909 			buf,
10910 			TRACE_PREFIX(
10911 				TRACE_TASK) "landlock_check_rule_fs: domain=[0-9a-f]\\+ "
10912 					    "access_request=read_dir "
10913 					    "dev=[0-9]\\+:[0-9]\\+ ino=[0-9]\\+ "
10914 					    "grants={read_dir}$"))
10915 	{
10916 		TH_LOG("Expected a grants={read_dir} event\n%s", buf);
10917 	}
10918 
10919 	free(buf);
10920 }
10921 
10922 TEST_HARNESS_MAIN
10923