xref: /linux/tools/testing/selftests/landlock/fs_test.c (revision a804c5742bff224d4cb4d25dd383554d598be32b)
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 /* Arbitrary command with nonzero bits in both 16-bit halves. */
4150 static const unsigned int unknown_ioctl_cmd = 0xc00ffeee;
4151 
4152 /*
4153  * ioctl_error - generically call the given ioctl with a pointer to a
4154  * sufficiently large zeroed-out memory region.
4155  *
4156  * Returns the IOCTLs error, or 0.
4157  */
4158 static int ioctl_error(struct __test_metadata *const _metadata, int fd,
4159 		       unsigned int cmd)
4160 {
4161 	char buf[128]; /* sufficiently large */
4162 	int res, stdinbak_fd, err;
4163 
4164 	/*
4165 	 * Depending on the IOCTL command, parts of the zeroed-out buffer might
4166 	 * be interpreted as file descriptor numbers.  We do not want to
4167 	 * accidentally operate on file descriptor 0 (stdin), so we temporarily
4168 	 * move stdin to a different FD and close FD 0 for the IOCTL call.
4169 	 */
4170 	stdinbak_fd = dup(0);
4171 	ASSERT_LT(0, stdinbak_fd);
4172 	ASSERT_EQ(0, close(0));
4173 
4174 	/* Invokes the IOCTL with a zeroed-out buffer. */
4175 	bzero(&buf, sizeof(buf));
4176 	res = ioctl(fd, cmd, &buf);
4177 	err = errno;
4178 
4179 	/* Restores the old FD 0 and closes the backup FD. */
4180 	ASSERT_EQ(0, dup2(stdinbak_fd, 0));
4181 	ASSERT_EQ(0, close(stdinbak_fd));
4182 
4183 	if (res < 0)
4184 		return err;
4185 
4186 	return 0;
4187 }
4188 
4189 /* Define some linux/falloc.h IOCTL commands which are not available in uapi headers. */
4190 struct space_resv {
4191 	__s16 l_type;
4192 	__s16 l_whence;
4193 	__s64 l_start;
4194 	__s64 l_len; /* len == 0 means until end of file */
4195 	__s32 l_sysid;
4196 	__u32 l_pid;
4197 	__s32 l_pad[4]; /* reserved area */
4198 };
4199 
4200 #define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
4201 #define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv)
4202 #define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
4203 #define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv)
4204 #define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv)
4205 
4206 /*
4207  * Tests a series of blanket-permitted and denied IOCTLs.
4208  */
4209 TEST_F_FORK(layout1, blanket_permitted_ioctls)
4210 {
4211 	int fd;
4212 
4213 	/* Enables Landlock. */
4214 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4215 
4216 	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
4217 	ASSERT_LE(0, fd);
4218 
4219 	/*
4220 	 * Checks permitted commands.
4221 	 * These ones may return errors, but should not be blocked by Landlock.
4222 	 */
4223 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOCLEX));
4224 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONCLEX));
4225 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONBIO));
4226 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOASYNC));
4227 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOQSIZE));
4228 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIFREEZE));
4229 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FITHAW));
4230 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_FIEMAP));
4231 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIGETBSZ));
4232 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONE));
4233 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONERANGE));
4234 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIDEDUPERANGE));
4235 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSUUID));
4236 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSSYSFSPATH));
4237 
4238 	/*
4239 	 * Checks blocked commands.
4240 	 * A call to a blocked IOCTL command always returns EACCES.
4241 	 */
4242 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIONREAD));
4243 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFLAGS));
4244 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_SETFLAGS));
4245 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSGETXATTR));
4246 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSSETXATTR));
4247 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIBMAP));
4248 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP));
4249 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP64));
4250 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP));
4251 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP64));
4252 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_ZERO_RANGE));
4253 
4254 	/* Default case is also blocked. */
4255 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, unknown_ioctl_cmd));
4256 
4257 	ASSERT_EQ(0, close(fd));
4258 }
4259 
4260 /*
4261  * Named pipes are not governed by the LANDLOCK_ACCESS_FS_IOCTL_DEV right,
4262  * because they are not character or block devices.
4263  */
4264 TEST_F_FORK(layout1, named_pipe_ioctl)
4265 {
4266 	pid_t child_pid;
4267 	int fd;
4268 	const char *const path = file1_s1d1;
4269 
4270 	ASSERT_EQ(0, unlink(path));
4271 	ASSERT_EQ(0, mkfifo(path, 0600));
4272 
4273 	/* Enables Landlock. */
4274 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4275 
4276 	/* The child process opens the pipe for writing. */
4277 	child_pid = fork();
4278 	ASSERT_NE(-1, child_pid);
4279 	if (child_pid == 0) {
4280 		fd = open(path, O_WRONLY);
4281 		close(fd);
4282 		exit(0);
4283 	}
4284 
4285 	fd = open(path, O_RDONLY);
4286 	ASSERT_LE(0, fd);
4287 
4288 	/* FIONREAD is implemented by pipefifo_fops. */
4289 	EXPECT_EQ(0, test_fionread_ioctl(fd));
4290 
4291 	ASSERT_EQ(0, close(fd));
4292 	ASSERT_EQ(0, unlink(path));
4293 
4294 	ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0));
4295 }
4296 
4297 /*
4298  * set_up_named_unix_server - Create a pathname unix socket
4299  *
4300  * If the socket type is not SOCK_DGRAM, also invoke listen(2).
4301  *
4302  * Return: The listening FD - it is the caller responsibility to close it.
4303  */
4304 static int set_up_named_unix_server(struct __test_metadata *const _metadata,
4305 				    int type, const char *const path)
4306 {
4307 	int fd;
4308 	struct sockaddr_un addr = {
4309 		.sun_family = AF_UNIX,
4310 	};
4311 
4312 	fd = socket(AF_UNIX, type, 0);
4313 	ASSERT_LE(0, fd);
4314 
4315 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4316 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4317 
4318 	ASSERT_EQ(0, bind(fd, (struct sockaddr *)&addr, sizeof(addr)));
4319 
4320 	if (type != SOCK_DGRAM)
4321 		ASSERT_EQ(0, listen(fd, 10 /* qlen */));
4322 	return fd;
4323 }
4324 
4325 /*
4326  * test_connect_named_unix - connect to the given named UNIX socket
4327  *
4328  * Return: The errno from connect(), or 0
4329  */
4330 static int test_connect_named_unix(struct __test_metadata *const _metadata,
4331 				   int fd, const char *const path)
4332 {
4333 	struct sockaddr_un addr = {
4334 		.sun_family = AF_UNIX,
4335 	};
4336 
4337 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4338 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4339 
4340 	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
4341 		return errno;
4342 	return 0;
4343 }
4344 
4345 /* For named UNIX domain sockets, no IOCTL restrictions apply. */
4346 TEST_F_FORK(layout1, named_unix_domain_socket_ioctl)
4347 {
4348 	const char *const path = file1_s1d1;
4349 	int srv_fd, cli_fd;
4350 
4351 	/* Sets up a server */
4352 	ASSERT_EQ(0, unlink(path));
4353 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, path);
4354 
4355 	/* Enables Landlock. */
4356 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_IOCTL_DEV, NULL);
4357 
4358 	/* Sets up a client connection to it */
4359 	cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
4360 	ASSERT_LE(0, cli_fd);
4361 
4362 	ASSERT_EQ(0, test_connect_named_unix(_metadata, cli_fd, path));
4363 
4364 	/* FIONREAD and other IOCTLs should not be forbidden. */
4365 	EXPECT_EQ(0, test_fionread_ioctl(cli_fd));
4366 
4367 	EXPECT_EQ(0, close(cli_fd));
4368 	EXPECT_EQ(0, close(srv_fd));
4369 }
4370 
4371 /* clang-format off */
4372 FIXTURE(ioctl) {};
4373 
4374 FIXTURE_SETUP(ioctl) {};
4375 
4376 FIXTURE_TEARDOWN(ioctl) {};
4377 /* clang-format on */
4378 
4379 FIXTURE_VARIANT(ioctl)
4380 {
4381 	const __u64 handled;
4382 	const __u64 allowed;
4383 	const mode_t open_mode;
4384 	/*
4385 	 * FIONREAD is used as a characteristic device-specific IOCTL command.
4386 	 * It is implemented in fs/ioctl.c for regular files,
4387 	 * but we do not blanket-permit it for devices.
4388 	 */
4389 	const int expected_fionread_result;
4390 };
4391 
4392 /* clang-format off */
4393 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_none) {
4394 	/* clang-format on */
4395 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4396 	.allowed = 0,
4397 	.open_mode = O_RDWR,
4398 	.expected_fionread_result = EACCES,
4399 };
4400 
4401 /* clang-format off */
4402 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_i) {
4403 	/* clang-format on */
4404 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4405 	.allowed = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4406 	.open_mode = O_RDWR,
4407 	.expected_fionread_result = 0,
4408 };
4409 
4410 /* clang-format off */
4411 FIXTURE_VARIANT_ADD(ioctl, unhandled) {
4412 	/* clang-format on */
4413 	.handled = LANDLOCK_ACCESS_FS_EXECUTE,
4414 	.allowed = LANDLOCK_ACCESS_FS_EXECUTE,
4415 	.open_mode = O_RDWR,
4416 	.expected_fionread_result = 0,
4417 };
4418 
4419 TEST_F_FORK(ioctl, handle_dir_access_file)
4420 {
4421 	const int flag = 0;
4422 	const struct rule rules[] = {
4423 		{
4424 			.path = "/dev",
4425 			.access = variant->allowed,
4426 		},
4427 		{},
4428 	};
4429 	int fd;
4430 
4431 	/* Enables Landlock. */
4432 	enforce_fs(_metadata, variant->handled, rules);
4433 
4434 	fd = open("/dev/zero", variant->open_mode);
4435 	ASSERT_LE(0, fd);
4436 
4437 	/* Checks that IOCTL commands return the expected errors. */
4438 	EXPECT_EQ(variant->expected_fionread_result, test_fionread_ioctl(fd));
4439 
4440 	/* Checks that unrestrictable commands are unrestricted. */
4441 	EXPECT_EQ(0, ioctl(fd, FIOCLEX));
4442 	EXPECT_EQ(0, ioctl(fd, FIONCLEX));
4443 	EXPECT_EQ(0, ioctl(fd, FIONBIO, &flag));
4444 	EXPECT_EQ(0, ioctl(fd, FIOASYNC, &flag));
4445 	EXPECT_EQ(0, ioctl(fd, FIGETBSZ, &flag));
4446 
4447 	ASSERT_EQ(0, close(fd));
4448 }
4449 
4450 TEST_F_FORK(ioctl, handle_dir_access_dir)
4451 {
4452 	const int flag = 0;
4453 	const struct rule rules[] = {
4454 		{
4455 			.path = "/dev",
4456 			.access = variant->allowed,
4457 		},
4458 		{},
4459 	};
4460 	int dir_fd;
4461 
4462 	/* Enables Landlock. */
4463 	enforce_fs(_metadata, variant->handled, rules);
4464 
4465 	/*
4466 	 * Ignore variant->open_mode for this test, as we intend to open a
4467 	 * directory.  If the directory can not be opened, the variant is
4468 	 * infeasible to test with an opened directory.
4469 	 */
4470 	dir_fd = open("/dev", O_RDONLY);
4471 	if (dir_fd < 0)
4472 		return;
4473 
4474 	/*
4475 	 * Checks that IOCTL commands return the expected errors.
4476 	 * We do not use the expected values from the fixture here.
4477 	 *
4478 	 * When using IOCTL on a directory, no Landlock restrictions apply.
4479 	 */
4480 	EXPECT_EQ(0, test_fionread_ioctl(dir_fd));
4481 
4482 	/* Checks that unrestrictable commands are unrestricted. */
4483 	EXPECT_EQ(0, ioctl(dir_fd, FIOCLEX));
4484 	EXPECT_EQ(0, ioctl(dir_fd, FIONCLEX));
4485 	EXPECT_EQ(0, ioctl(dir_fd, FIONBIO, &flag));
4486 	EXPECT_EQ(0, ioctl(dir_fd, FIOASYNC, &flag));
4487 	EXPECT_EQ(0, ioctl(dir_fd, FIGETBSZ, &flag));
4488 
4489 	ASSERT_EQ(0, close(dir_fd));
4490 }
4491 
4492 TEST_F_FORK(ioctl, handle_file_access_file)
4493 {
4494 	const int flag = 0;
4495 	const struct rule rules[] = {
4496 		{
4497 			.path = "/dev/zero",
4498 			.access = variant->allowed,
4499 		},
4500 		{},
4501 	};
4502 	int fd;
4503 
4504 	/* Enables Landlock. */
4505 	enforce_fs(_metadata, variant->handled, rules);
4506 
4507 	fd = open("/dev/zero", variant->open_mode);
4508 	ASSERT_LE(0, fd)
4509 	{
4510 		TH_LOG("Failed to open /dev/zero: %s", strerror(errno));
4511 	}
4512 
4513 	/* Checks that IOCTL commands return the expected errors. */
4514 	EXPECT_EQ(variant->expected_fionread_result, test_fionread_ioctl(fd));
4515 
4516 	/* Checks that unrestrictable commands are unrestricted. */
4517 	EXPECT_EQ(0, ioctl(fd, FIOCLEX));
4518 	EXPECT_EQ(0, ioctl(fd, FIONCLEX));
4519 	EXPECT_EQ(0, ioctl(fd, FIONBIO, &flag));
4520 	EXPECT_EQ(0, ioctl(fd, FIOASYNC, &flag));
4521 	EXPECT_EQ(0, ioctl(fd, FIGETBSZ, &flag));
4522 
4523 	ASSERT_EQ(0, close(fd));
4524 }
4525 
4526 /*
4527  * test_sendto_named_unix - sendto to the given named UNIX socket
4528  *
4529  * sendto() is equivalent to sendmsg() in this respect.
4530  *
4531  * Return: The errno from sendto(), or 0
4532  */
4533 static int test_sendto_named_unix(struct __test_metadata *const _metadata,
4534 				  int fd, const char *const path)
4535 {
4536 	static const char buf[] = "dummy";
4537 	struct sockaddr_un addr = {
4538 		.sun_family = AF_UNIX,
4539 	};
4540 
4541 	ASSERT_LT(strlen(path), sizeof(addr.sun_path));
4542 	strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
4543 
4544 	if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&addr,
4545 		   sizeof(addr)) == -1)
4546 		return errno;
4547 	return 0;
4548 }
4549 
4550 /* clang-format off */
4551 FIXTURE(scoped_domains) {};
4552 /* clang-format on */
4553 
4554 #include "scoped_base_variants.h"
4555 
4556 FIXTURE_SETUP(scoped_domains)
4557 {
4558 	drop_caps(_metadata);
4559 };
4560 
4561 FIXTURE_TEARDOWN(scoped_domains)
4562 {
4563 }
4564 
4565 /*
4566  * Flags for test_connect_to_parent and test_connect_to_child:
4567  *
4568  * USE_SENDTO: Use sendto() instead of connect() (for SOCK_DGRAM only)
4569  * ENFORCE_ALL: Enforce a Landlock domain even when the variant says
4570  *   we shouldn't.  We enforce a domain where the path is allow-listed,
4571  *   and expect the behavior to be the same as if none was used.
4572  */
4573 #define USE_SENDTO (1 << 0)
4574 #define ENFORCE_ALL (1 << 1)
4575 
4576 static void test_connect_to_parent(struct __test_metadata *const _metadata,
4577 				   const FIXTURE_VARIANT(scoped_domains) *
4578 					   variant,
4579 				   int sock_type, int flags)
4580 {
4581 	const char *const path = "sock";
4582 	const struct rule rules[] = {
4583 		{
4584 			.path = ".",
4585 			.access = LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4586 		},
4587 		{},
4588 	};
4589 	int cli_fd, srv_fd, res, status;
4590 	pid_t child_pid;
4591 	int readiness_pipe[2];
4592 	char buf[1];
4593 
4594 	if (variant->domain_both)
4595 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4596 	else if (flags & ENFORCE_ALL)
4597 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4598 
4599 	unlink(path);
4600 	ASSERT_EQ(0, pipe2(readiness_pipe, O_CLOEXEC));
4601 
4602 	child_pid = fork();
4603 	ASSERT_LE(0, child_pid);
4604 
4605 	if (child_pid == 0) {
4606 		if (variant->domain_child)
4607 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4608 				   NULL);
4609 		else if (flags & ENFORCE_ALL)
4610 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4611 				   rules);
4612 
4613 		/* Wait for server to be available. */
4614 		EXPECT_EQ(0, close(readiness_pipe[1]));
4615 		EXPECT_EQ(1, read(readiness_pipe[0], &buf, 1));
4616 		EXPECT_EQ(0, close(readiness_pipe[0]));
4617 
4618 		/* Talk to server. */
4619 		cli_fd = socket(AF_UNIX, sock_type, 0);
4620 		ASSERT_LE(0, cli_fd);
4621 
4622 		if (flags & USE_SENDTO)
4623 			res = test_sendto_named_unix(_metadata, cli_fd, path);
4624 		else
4625 			res = test_connect_named_unix(_metadata, cli_fd, path);
4626 
4627 		EXPECT_EQ(variant->domain_child ? EACCES : 0, res);
4628 
4629 		/* Clean up. */
4630 		EXPECT_EQ(0, close(cli_fd));
4631 
4632 		_exit(_metadata->exit_code);
4633 		return;
4634 	}
4635 
4636 	if (variant->domain_parent)
4637 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4638 	else if (flags & ENFORCE_ALL)
4639 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4640 
4641 	srv_fd = set_up_named_unix_server(_metadata, sock_type, path);
4642 
4643 	/* Tell the child that it can connect. */
4644 	EXPECT_EQ(0, close(readiness_pipe[0]));
4645 	EXPECT_EQ(sizeof(buf), write(readiness_pipe[1], buf, sizeof(buf)));
4646 	EXPECT_EQ(0, close(readiness_pipe[1]));
4647 
4648 	/* Wait for child. */
4649 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4650 	EXPECT_EQ(1, WIFEXITED(status));
4651 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
4652 
4653 	/* Clean up. */
4654 	EXPECT_EQ(0, close(srv_fd));
4655 	EXPECT_EQ(0, unlink(path));
4656 }
4657 
4658 static void test_connect_to_child(struct __test_metadata *const _metadata,
4659 				  const FIXTURE_VARIANT(scoped_domains) *
4660 					  variant,
4661 				  int sock_type, int flags)
4662 {
4663 	const char *const path = "sock";
4664 	const struct rule rules[] = {
4665 		{
4666 			.path = ".",
4667 			.access = LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4668 		},
4669 		{},
4670 	};
4671 	int readiness_pipe[2];
4672 	int shutdown_pipe[2];
4673 	int cli_fd, srv_fd, res, status;
4674 	pid_t child_pid;
4675 	char buf[1];
4676 
4677 	if (variant->domain_both)
4678 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4679 	else if (flags & ENFORCE_ALL)
4680 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4681 
4682 	unlink(path);
4683 	ASSERT_EQ(0, pipe2(readiness_pipe, O_CLOEXEC));
4684 	ASSERT_EQ(0, pipe2(shutdown_pipe, O_CLOEXEC));
4685 
4686 	child_pid = fork();
4687 	ASSERT_LE(0, child_pid);
4688 
4689 	if (child_pid == 0) {
4690 		if (variant->domain_child)
4691 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4692 				   NULL);
4693 		else if (flags & ENFORCE_ALL)
4694 			enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
4695 				   rules);
4696 
4697 		srv_fd = set_up_named_unix_server(_metadata, sock_type, path);
4698 
4699 		/* Tell the parent that it can connect. */
4700 		EXPECT_EQ(0, close(readiness_pipe[0]));
4701 		EXPECT_EQ(sizeof(buf),
4702 			  write(readiness_pipe[1], buf, sizeof(buf)));
4703 		EXPECT_EQ(0, close(readiness_pipe[1]));
4704 
4705 		/* Wait until it is time to shut down. */
4706 		EXPECT_EQ(0, close(shutdown_pipe[1]));
4707 		EXPECT_EQ(1, read(shutdown_pipe[0], &buf, 1));
4708 		EXPECT_EQ(0, close(shutdown_pipe[0]));
4709 
4710 		/* Cleanup */
4711 		EXPECT_EQ(0, close(srv_fd));
4712 		EXPECT_EQ(0, unlink(path));
4713 
4714 		_exit(_metadata->exit_code);
4715 		return;
4716 	}
4717 
4718 	if (variant->domain_parent)
4719 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4720 	else if (flags & ENFORCE_ALL)
4721 		enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, rules);
4722 
4723 	/* Wait for server to be available. */
4724 	EXPECT_EQ(0, close(readiness_pipe[1]));
4725 	EXPECT_EQ(1, read(readiness_pipe[0], &buf, 1));
4726 	EXPECT_EQ(0, close(readiness_pipe[0]));
4727 
4728 	/* Talk to server. */
4729 	cli_fd = socket(AF_UNIX, sock_type, 0);
4730 	ASSERT_LE(0, cli_fd);
4731 
4732 	if (flags & USE_SENDTO)
4733 		res = test_sendto_named_unix(_metadata, cli_fd, path);
4734 	else
4735 		res = test_connect_named_unix(_metadata, cli_fd, path);
4736 
4737 	EXPECT_EQ(variant->domain_parent ? EACCES : 0, res);
4738 
4739 	/* Clean up. */
4740 	EXPECT_EQ(0, close(cli_fd));
4741 
4742 	/* Tell the server to shut down. */
4743 	EXPECT_EQ(0, close(shutdown_pipe[0]));
4744 	EXPECT_EQ(sizeof(buf), write(shutdown_pipe[1], buf, sizeof(buf)));
4745 	EXPECT_EQ(0, close(shutdown_pipe[1]));
4746 
4747 	/* Wait for child. */
4748 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4749 	EXPECT_EQ(1, WIFEXITED(status));
4750 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
4751 }
4752 
4753 TEST_F(scoped_domains, unix_stream_connect_to_parent)
4754 {
4755 	test_connect_to_parent(_metadata, variant, SOCK_STREAM, 0);
4756 }
4757 
4758 TEST_F(scoped_domains, unix_dgram_connect_to_parent)
4759 {
4760 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, 0);
4761 }
4762 
4763 TEST_F(scoped_domains, unix_dgram_sendmsg_to_parent)
4764 {
4765 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, USE_SENDTO);
4766 }
4767 
4768 TEST_F(scoped_domains, unix_seqpacket_connect_to_parent)
4769 {
4770 	test_connect_to_parent(_metadata, variant, SOCK_SEQPACKET, 0);
4771 }
4772 
4773 TEST_F(scoped_domains, unix_stream_connect_to_parent_full)
4774 {
4775 	test_connect_to_parent(_metadata, variant, SOCK_STREAM, ENFORCE_ALL);
4776 }
4777 
4778 TEST_F(scoped_domains, unix_dgram_connect_to_parent_full)
4779 {
4780 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM, ENFORCE_ALL);
4781 }
4782 
4783 TEST_F(scoped_domains, unix_dgram_sendmsg_to_parent_full)
4784 {
4785 	test_connect_to_parent(_metadata, variant, SOCK_DGRAM,
4786 			       USE_SENDTO | ENFORCE_ALL);
4787 }
4788 
4789 TEST_F(scoped_domains, unix_seqpacket_connect_to_parent_full)
4790 {
4791 	test_connect_to_parent(_metadata, variant, SOCK_SEQPACKET, ENFORCE_ALL);
4792 }
4793 
4794 TEST_F(scoped_domains, unix_stream_connect_to_child)
4795 {
4796 	test_connect_to_child(_metadata, variant, SOCK_STREAM, 0);
4797 }
4798 
4799 TEST_F(scoped_domains, unix_dgram_connect_to_child)
4800 {
4801 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, 0);
4802 }
4803 
4804 TEST_F(scoped_domains, unix_dgram_sendmsg_to_child)
4805 {
4806 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, USE_SENDTO);
4807 }
4808 
4809 TEST_F(scoped_domains, unix_seqpacket_connect_to_child)
4810 {
4811 	test_connect_to_child(_metadata, variant, SOCK_SEQPACKET, 0);
4812 }
4813 
4814 TEST_F(scoped_domains, unix_stream_connect_to_child_full)
4815 {
4816 	test_connect_to_child(_metadata, variant, SOCK_STREAM, ENFORCE_ALL);
4817 }
4818 
4819 TEST_F(scoped_domains, unix_dgram_connect_to_child_full)
4820 {
4821 	test_connect_to_child(_metadata, variant, SOCK_DGRAM, ENFORCE_ALL);
4822 }
4823 
4824 TEST_F(scoped_domains, unix_dgram_sendmsg_to_child_full)
4825 {
4826 	test_connect_to_child(_metadata, variant, SOCK_DGRAM,
4827 			      USE_SENDTO | ENFORCE_ALL);
4828 }
4829 
4830 TEST_F(scoped_domains, unix_seqpacket_connect_to_child_full)
4831 {
4832 	test_connect_to_child(_metadata, variant, SOCK_SEQPACKET, ENFORCE_ALL);
4833 }
4834 
4835 #undef USE_SENDTO
4836 #undef ENFORCE_ALL
4837 
4838 static void read_core_pattern(struct __test_metadata *const _metadata,
4839 			      char *buf, size_t buf_size)
4840 {
4841 	int fd;
4842 	ssize_t ret;
4843 
4844 	fd = open("/proc/sys/kernel/core_pattern", O_RDONLY | O_CLOEXEC);
4845 	ASSERT_LE(0, fd);
4846 
4847 	ret = read(fd, buf, buf_size - 1);
4848 	ASSERT_LE(0, ret);
4849 	EXPECT_EQ(0, close(fd));
4850 
4851 	buf[ret] = '\0';
4852 }
4853 
4854 static void set_core_pattern(struct __test_metadata *const _metadata,
4855 			     const char *pattern)
4856 {
4857 	int fd;
4858 	size_t len = strlen(pattern);
4859 
4860 	/*
4861 	 * Writing to /proc/sys/kernel/core_pattern requires EUID 0 because
4862 	 * sysctl_perm() checks that, ignoring capabilities like
4863 	 * CAP_SYS_ADMIN or CAP_DAC_OVERRIDE.
4864 	 *
4865 	 * Switching EUID clears the dumpable flag, which must be restored
4866 	 * afterwards to allow coredumps.
4867 	 */
4868 	set_cap(_metadata, CAP_SETUID);
4869 	ASSERT_EQ(0, seteuid(0));
4870 	clear_cap(_metadata, CAP_SETUID);
4871 
4872 	fd = open("/proc/sys/kernel/core_pattern", O_WRONLY | O_CLOEXEC);
4873 	ASSERT_LE(0, fd)
4874 	{
4875 		TH_LOG("Failed to open core_pattern for writing: %s",
4876 		       strerror(errno));
4877 	}
4878 
4879 	ASSERT_EQ(len, write(fd, pattern, len));
4880 	EXPECT_EQ(0, close(fd));
4881 
4882 	set_cap(_metadata, CAP_SETUID);
4883 	ASSERT_EQ(0, seteuid(getuid()));
4884 	clear_cap(_metadata, CAP_SETUID);
4885 
4886 	/* Restore dumpable flag cleared by seteuid(). */
4887 	ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1, 0, 0, 0));
4888 }
4889 
4890 FIXTURE(coredump)
4891 {
4892 	char original_core_pattern[256];
4893 };
4894 
4895 FIXTURE_SETUP(coredump)
4896 {
4897 	disable_caps(_metadata);
4898 	read_core_pattern(_metadata, self->original_core_pattern,
4899 			  sizeof(self->original_core_pattern));
4900 }
4901 
4902 FIXTURE_TEARDOWN_PARENT(coredump)
4903 {
4904 	set_core_pattern(_metadata, self->original_core_pattern);
4905 }
4906 
4907 /*
4908  * Test that even when a process is restricted with
4909  * LANDLOCK_ACCESS_FS_RESOLVE_UNIX, the kernel can still initiate a connection
4910  * to the coredump socket on the processes' behalf.
4911  */
4912 TEST_F_FORK(coredump, socket_not_restricted)
4913 {
4914 	static const char core_pattern[] = "@/tmp/landlock_coredump_test.sock";
4915 	const char *const sock_path = core_pattern + 1;
4916 	int srv_fd, conn_fd, status;
4917 	pid_t child_pid;
4918 	struct ucred cred;
4919 	socklen_t cred_len = sizeof(cred);
4920 	char buf[4096];
4921 
4922 	/* Set up the coredump server socket. */
4923 	unlink(sock_path);
4924 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, sock_path);
4925 
4926 	/* Point coredumps at our socket. */
4927 	set_core_pattern(_metadata, core_pattern);
4928 
4929 	/* Restrict LANDLOCK_ACCESS_FS_RESOLVE_UNIX. */
4930 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_RESOLVE_UNIX, NULL);
4931 
4932 	/* Fork a child that crashes. */
4933 	child_pid = fork();
4934 	ASSERT_LE(0, child_pid);
4935 	if (child_pid == 0) {
4936 		struct rlimit rl = {
4937 			.rlim_cur = RLIM_INFINITY,
4938 			.rlim_max = RLIM_INFINITY,
4939 		};
4940 
4941 		ASSERT_EQ(0, setrlimit(RLIMIT_CORE, &rl));
4942 
4943 		/* Crash on purpose. */
4944 		kill(getpid(), SIGSEGV);
4945 		_exit(1);
4946 	}
4947 
4948 	/*
4949 	 * Accept the coredump connection.  If Landlock incorrectly denies the
4950 	 * kernel's coredump connect, accept() will block forever, so the test
4951 	 * would time out.
4952 	 */
4953 	conn_fd = accept(srv_fd, NULL, NULL);
4954 	ASSERT_LE(0, conn_fd);
4955 
4956 	/* Check that the connection came from the crashing child. */
4957 	ASSERT_EQ(0, getsockopt(conn_fd, SOL_SOCKET, SO_PEERCRED, &cred,
4958 				&cred_len));
4959 	EXPECT_EQ(child_pid, cred.pid);
4960 
4961 	/* Drain the coredump data so the kernel can finish. */
4962 	while (read(conn_fd, buf, sizeof(buf)) > 0)
4963 		;
4964 
4965 	EXPECT_EQ(0, close(conn_fd));
4966 
4967 	/* Wait for the child and verify it coredumped. */
4968 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
4969 	ASSERT_TRUE(WIFSIGNALED(status));
4970 	ASSERT_TRUE(WCOREDUMP(status));
4971 
4972 	EXPECT_EQ(0, close(srv_fd));
4973 	EXPECT_EQ(0, unlink(sock_path));
4974 }
4975 
4976 /* clang-format off */
4977 FIXTURE(layout1_bind) {};
4978 /* clang-format on */
4979 
4980 static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
4981 static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
4982 static const char bind_file2_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f2";
4983 
4984 /* Move targets for disconnected path tests. */
4985 static const char dir_s4d1[] = TMP_DIR "/s4d1";
4986 static const char file1_s4d1[] = TMP_DIR "/s4d1/f1";
4987 static const char file2_s4d1[] = TMP_DIR "/s4d1/f2";
4988 static const char dir_s4d2[] = TMP_DIR "/s4d1/s4d2";
4989 static const char file1_s4d2[] = TMP_DIR "/s4d1/s4d2/f1";
4990 static const char file1_name[] = "f1";
4991 static const char file2_name[] = "f2";
4992 
4993 FIXTURE_SETUP(layout1_bind)
4994 {
4995 	prepare_layout(_metadata);
4996 
4997 	create_layout1(_metadata);
4998 
4999 	set_cap(_metadata, CAP_SYS_ADMIN);
5000 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
5001 	clear_cap(_metadata, CAP_SYS_ADMIN);
5002 }
5003 
5004 FIXTURE_TEARDOWN_PARENT(layout1_bind)
5005 {
5006 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
5007 
5008 	remove_path(file1_s4d1);
5009 	remove_path(file2_s4d1);
5010 
5011 	remove_layout1(_metadata);
5012 
5013 	cleanup_layout(_metadata);
5014 }
5015 
5016 /*
5017  * layout1_bind hierarchy:
5018  *
5019  * tmp
5020  * ├── s1d1
5021  * │   ├── f1
5022  * │   ├── f2
5023  * │   └── s1d2
5024  * │       ├── f1
5025  * │       ├── f2
5026  * │       └── s1d3 [disconnected by path_disconnected]
5027  * │           ├── f1
5028  * │           └── f2
5029  * ├── s2d1
5030  * │   ├── f1
5031  * │   └── s2d2 [bind mount from s1d2]
5032  * │       ├── f1
5033  * │       ├── f2
5034  * │       └── s1d3
5035  * │           ├── f1
5036  * │           └── f2
5037  * ├── s3d1
5038  * │   └── s3d2
5039  * │       └── s3d3
5040  * └── s4d1 [renamed from s1d3 by path_disconnected]
5041  *     ├── f1
5042  *     ├── f2
5043  *     └── s4d2
5044  *         └── f1
5045  */
5046 
5047 TEST_F_FORK(layout1_bind, no_restriction)
5048 {
5049 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
5050 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
5051 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
5052 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5053 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
5054 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5055 
5056 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
5057 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
5058 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
5059 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
5060 	ASSERT_EQ(ENOENT, test_open(dir_s2d3, O_RDONLY));
5061 	ASSERT_EQ(ENOENT, test_open(file1_s2d3, O_RDONLY));
5062 
5063 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY));
5064 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
5065 
5066 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
5067 }
5068 
5069 TEST_F_FORK(layout1_bind, same_content_same_file)
5070 {
5071 	/*
5072 	 * Sets access right on parent directories of both source and
5073 	 * destination mount points.
5074 	 */
5075 	const struct rule layer1_parent[] = {
5076 		{
5077 			.path = dir_s1d1,
5078 			.access = ACCESS_RO,
5079 		},
5080 		{
5081 			.path = dir_s2d1,
5082 			.access = ACCESS_RW,
5083 		},
5084 		{},
5085 	};
5086 	/*
5087 	 * Sets access rights on the same bind-mounted directories.  The result
5088 	 * should be ACCESS_RW for both directories, but not both hierarchies
5089 	 * because of the first layer.
5090 	 */
5091 	const struct rule layer2_mount_point[] = {
5092 		{
5093 			.path = dir_s1d2,
5094 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5095 		},
5096 		{
5097 			.path = dir_s2d2,
5098 			.access = ACCESS_RW,
5099 		},
5100 		{},
5101 	};
5102 	/* Only allow read-access to the s1d3 hierarchies. */
5103 	const struct rule layer3_source[] = {
5104 		{
5105 			.path = dir_s1d3,
5106 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5107 		},
5108 		{},
5109 	};
5110 	/* Removes all access rights. */
5111 	const struct rule layer4_destination[] = {
5112 		{
5113 			.path = bind_file1_s1d3,
5114 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
5115 		},
5116 		{},
5117 	};
5118 
5119 	/* Sets rules for the parent directories. */
5120 	enforce_fs(_metadata, ACCESS_RW, layer1_parent);
5121 
5122 	/* Checks source hierarchy. */
5123 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
5124 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
5125 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
5126 
5127 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5128 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5129 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5130 
5131 	/* Checks destination hierarchy. */
5132 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDWR));
5133 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
5134 
5135 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
5136 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5137 
5138 	/* Sets rules for the mount points. */
5139 	enforce_fs(_metadata, ACCESS_RW, layer2_mount_point);
5140 
5141 	/* Checks source hierarchy. */
5142 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
5143 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
5144 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
5145 
5146 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5147 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5148 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5149 
5150 	/* Checks destination hierarchy. */
5151 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_RDONLY));
5152 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_WRONLY));
5153 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
5154 
5155 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
5156 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5157 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
5158 
5159 	/* Sets a (shared) rule only on the source. */
5160 	enforce_fs(_metadata, ACCESS_RW, layer3_source);
5161 
5162 	/* Checks source hierarchy. */
5163 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
5164 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
5165 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
5166 
5167 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5168 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
5169 	ASSERT_EQ(EACCES, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
5170 
5171 	/* Checks destination hierarchy. */
5172 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_RDONLY));
5173 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_WRONLY));
5174 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
5175 
5176 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
5177 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
5178 	ASSERT_EQ(EACCES, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
5179 
5180 	/* Sets a (shared) rule only on the destination. */
5181 	enforce_fs(_metadata, ACCESS_RW, layer4_destination);
5182 
5183 	/* Checks source hierarchy. */
5184 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
5185 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
5186 
5187 	/* Checks destination hierarchy. */
5188 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_RDONLY));
5189 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
5190 }
5191 
5192 TEST_F_FORK(layout1_bind, reparent_cross_mount)
5193 {
5194 	const struct rule layer1[] = {
5195 		{
5196 			/* dir_s2d1 is beneath the dir_s2d2 mount point. */
5197 			.path = dir_s2d1,
5198 			.access = LANDLOCK_ACCESS_FS_REFER,
5199 		},
5200 		{
5201 			.path = bind_dir_s1d3,
5202 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
5203 		},
5204 		{},
5205 	};
5206 
5207 	enforce_fs(_metadata,
5208 		   LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_EXECUTE,
5209 		   layer1);
5210 
5211 	/* Checks basic denied move. */
5212 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s1d2));
5213 	ASSERT_EQ(EXDEV, errno);
5214 
5215 	/* Checks real cross-mount move (Landlock is not involved). */
5216 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s2d2));
5217 	ASSERT_EQ(EXDEV, errno);
5218 
5219 	/* Checks move that will give more accesses. */
5220 	ASSERT_EQ(-1, rename(file1_s2d2, bind_file1_s1d3));
5221 	ASSERT_EQ(EXDEV, errno);
5222 
5223 	/* Checks legitimate downgrade move. */
5224 	ASSERT_EQ(0, rename(bind_file1_s1d3, file1_s2d2));
5225 }
5226 
5227 /*
5228  * Make sure access to file through a disconnected path works as expected.
5229  * This test moves s1d3 to s4d1.
5230  */
5231 TEST_F_FORK(layout1_bind, path_disconnected)
5232 {
5233 	const struct rule layer1_allow_all[] = {
5234 		{
5235 			.path = TMP_DIR,
5236 			.access = ACCESS_ALL,
5237 		},
5238 		{},
5239 	};
5240 	const struct rule layer2_allow_just_f1[] = {
5241 		{
5242 			.path = file1_s1d3,
5243 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5244 		},
5245 		{},
5246 	};
5247 	const struct rule layer3_only_s1d2[] = {
5248 		{
5249 			.path = dir_s1d2,
5250 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5251 		},
5252 		{},
5253 	};
5254 
5255 	/* Landlock should not deny access just because it is disconnected. */
5256 	int ruleset_fd_l1 =
5257 		create_ruleset(_metadata, ACCESS_ALL, layer1_allow_all);
5258 
5259 	/* Creates the new ruleset now before we move the dir containing the file. */
5260 	int ruleset_fd_l2 =
5261 		create_ruleset(_metadata, ACCESS_RW, layer2_allow_just_f1);
5262 	int ruleset_fd_l3 =
5263 		create_ruleset(_metadata, ACCESS_RW, layer3_only_s1d2);
5264 	int bind_s1d3_fd;
5265 
5266 	enforce_ruleset(_metadata, ruleset_fd_l1);
5267 	EXPECT_EQ(0, close(ruleset_fd_l1));
5268 
5269 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5270 	ASSERT_LE(0, bind_s1d3_fd);
5271 
5272 	/* Tests access is possible before we move. */
5273 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5274 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5275 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
5276 
5277 	/* Makes it disconnected. */
5278 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
5279 	{
5280 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
5281 		       strerror(errno));
5282 	}
5283 
5284 	/* Tests that access is still possible. */
5285 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5286 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5287 
5288 	/*
5289 	 * Tests that ".." is not possible (not because of Landlock, but just
5290 	 * because it's disconnected).
5291 	 */
5292 	EXPECT_EQ(ENOENT,
5293 		  test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
5294 
5295 	/* This should still work with a narrower rule. */
5296 	enforce_ruleset(_metadata, ruleset_fd_l2);
5297 	EXPECT_EQ(0, close(ruleset_fd_l2));
5298 
5299 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY));
5300 	/*
5301 	 * Accessing a file through a disconnected file descriptor can still be
5302 	 * allowed by a rule tied to this file, even if it is no longer visible in
5303 	 * its mount point.
5304 	 */
5305 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5306 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5307 
5308 	enforce_ruleset(_metadata, ruleset_fd_l3);
5309 	EXPECT_EQ(0, close(ruleset_fd_l3));
5310 
5311 	EXPECT_EQ(EACCES, test_open(file1_s4d1, O_RDONLY));
5312 	/*
5313 	 * Accessing a file through a disconnected file descriptor can still be
5314 	 * allowed by a rule tied to the original mount point, even if it is no
5315 	 * longer visible in its mount point.
5316 	 */
5317 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5318 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5319 }
5320 
5321 /*
5322  * Test that renameat with disconnected paths works under Landlock.  This test
5323  * moves s1d3 to s4d2, so that we can have a rule allowing refers on the move
5324  * target's immediate parent.
5325  */
5326 TEST_F_FORK(layout1_bind, path_disconnected_rename)
5327 {
5328 	const struct rule layer1[] = {
5329 		{
5330 			.path = dir_s1d2,
5331 			.access = LANDLOCK_ACCESS_FS_REFER |
5332 				  LANDLOCK_ACCESS_FS_MAKE_DIR |
5333 				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
5334 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5335 				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
5336 				  LANDLOCK_ACCESS_FS_READ_FILE,
5337 		},
5338 		{
5339 			.path = dir_s4d1,
5340 			.access = LANDLOCK_ACCESS_FS_REFER |
5341 				  LANDLOCK_ACCESS_FS_MAKE_DIR |
5342 				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
5343 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5344 				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
5345 				  LANDLOCK_ACCESS_FS_READ_FILE,
5346 		},
5347 		{}
5348 	};
5349 
5350 	/* This layer only handles LANDLOCK_ACCESS_FS_READ_FILE. */
5351 	const struct rule layer2_only_s1d2[] = {
5352 		{
5353 			.path = dir_s1d2,
5354 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5355 		},
5356 		{},
5357 	};
5358 	int ruleset_fd_l1, ruleset_fd_l2;
5359 	pid_t child_pid;
5360 	int bind_s1d3_fd, status;
5361 
5362 	ASSERT_EQ(0, mkdir(dir_s4d1, 0755))
5363 	{
5364 		TH_LOG("Failed to create %s: %s", dir_s4d1, strerror(errno));
5365 	}
5366 	ruleset_fd_l1 = create_ruleset(_metadata, ACCESS_ALL, layer1);
5367 	ruleset_fd_l2 = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
5368 				       layer2_only_s1d2);
5369 
5370 	enforce_ruleset(_metadata, ruleset_fd_l1);
5371 	EXPECT_EQ(0, close(ruleset_fd_l1));
5372 
5373 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5374 	ASSERT_LE(0, bind_s1d3_fd);
5375 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5376 
5377 	/* Tests ENOENT priority over EACCES for disconnected directory. */
5378 	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
5379 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
5380 	{
5381 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
5382 		       strerror(errno));
5383 	}
5384 	EXPECT_EQ(ENOENT, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
5385 
5386 	/*
5387 	 * The file is no longer under s1d2 but we should still be able to access it
5388 	 * with layer 2 because its mount point is evaluated as the first valid
5389 	 * directory because it was initially a parent.  Do a fork to test this so
5390 	 * we don't prevent ourselves from renaming it back later.
5391 	 */
5392 	child_pid = fork();
5393 	ASSERT_LE(0, child_pid);
5394 	if (child_pid == 0) {
5395 		enforce_ruleset(_metadata, ruleset_fd_l2);
5396 		EXPECT_EQ(0, close(ruleset_fd_l2));
5397 		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5398 		EXPECT_EQ(EACCES, test_open(file1_s4d2, O_RDONLY));
5399 
5400 		/*
5401 		 * Tests that access widening checks indeed prevents us from renaming it
5402 		 * back.
5403 		 */
5404 		EXPECT_EQ(-1, rename(dir_s4d2, dir_s1d3));
5405 		EXPECT_EQ(EXDEV, errno);
5406 
5407 		/*
5408 		 * Including through the now disconnected fd (but it should return
5409 		 * EXDEV).
5410 		 */
5411 		EXPECT_EQ(-1, renameat(bind_s1d3_fd, file1_name, AT_FDCWD,
5412 				       file1_s2d2));
5413 		EXPECT_EQ(EXDEV, errno);
5414 		_exit(_metadata->exit_code);
5415 		return;
5416 	}
5417 
5418 	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
5419 	EXPECT_EQ(1, WIFEXITED(status));
5420 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
5421 
5422 	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
5423 	{
5424 		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d1, dir_s1d3,
5425 		       strerror(errno));
5426 	}
5427 
5428 	/* Now checks that we can access it under l2. */
5429 	child_pid = fork();
5430 	ASSERT_LE(0, child_pid);
5431 	if (child_pid == 0) {
5432 		enforce_ruleset(_metadata, ruleset_fd_l2);
5433 		EXPECT_EQ(0, close(ruleset_fd_l2));
5434 		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5435 		EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5436 		_exit(_metadata->exit_code);
5437 		return;
5438 	}
5439 
5440 	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
5441 	EXPECT_EQ(1, WIFEXITED(status));
5442 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
5443 
5444 	/*
5445 	 * Also test that we can rename via a disconnected path.  We move the
5446 	 * dir back to the disconnected place first, then we rename file1 to
5447 	 * file2 through our dir fd.
5448 	 */
5449 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
5450 	{
5451 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
5452 		       strerror(errno));
5453 	}
5454 	ASSERT_EQ(0,
5455 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name))
5456 	{
5457 		TH_LOG("Failed to rename %s to %s within disconnected %s: %s",
5458 		       file1_name, file2_name, bind_dir_s1d3, strerror(errno));
5459 	}
5460 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
5461 	ASSERT_EQ(0, renameat(bind_s1d3_fd, file2_name, AT_FDCWD, file1_s2d2))
5462 	{
5463 		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
5464 		       file2_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
5465 	}
5466 	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY));
5467 	EXPECT_EQ(0, test_open(file1_s1d2, O_RDONLY));
5468 
5469 	/* Move it back using the disconnected path as the target. */
5470 	ASSERT_EQ(0, renameat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file1_name))
5471 	{
5472 		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
5473 		       file1_s1d2, file1_name, bind_dir_s1d3, strerror(errno));
5474 	}
5475 
5476 	/* Now make it connected again. */
5477 	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
5478 	{
5479 		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d2, dir_s1d3,
5480 		       strerror(errno));
5481 	}
5482 
5483 	/* Checks again that we can access it under l2. */
5484 	enforce_ruleset(_metadata, ruleset_fd_l2);
5485 	EXPECT_EQ(0, close(ruleset_fd_l2));
5486 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5487 	EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
5488 }
5489 
5490 /*
5491  * Test that linkat(2) with disconnected paths works under Landlock. This
5492  * test moves s1d3 to s4d1.
5493  */
5494 TEST_F_FORK(layout1_bind, path_disconnected_link)
5495 {
5496 	/* Ruleset to be applied after renaming s1d3 to s4d1. */
5497 	const struct rule layer1[] = {
5498 		{
5499 			.path = dir_s4d1,
5500 			.access = LANDLOCK_ACCESS_FS_REFER |
5501 				  LANDLOCK_ACCESS_FS_READ_FILE |
5502 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5503 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
5504 		},
5505 		{
5506 			.path = dir_s2d2,
5507 			.access = LANDLOCK_ACCESS_FS_REFER |
5508 				  LANDLOCK_ACCESS_FS_READ_FILE |
5509 				  LANDLOCK_ACCESS_FS_MAKE_REG |
5510 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
5511 		},
5512 		{}
5513 	};
5514 	int bind_s1d3_fd;
5515 
5516 	/* Removes unneeded files created by layout1, otherwise it will EEXIST. */
5517 	ASSERT_EQ(0, unlink(file1_s1d2));
5518 	ASSERT_EQ(0, unlink(file2_s1d3));
5519 
5520 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
5521 	ASSERT_LE(0, bind_s1d3_fd);
5522 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
5523 
5524 	/* Disconnects bind_s1d3_fd. */
5525 	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
5526 	{
5527 		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
5528 		       strerror(errno));
5529 	}
5530 
5531 	/* Need this later to test different parent link. */
5532 	ASSERT_EQ(0, mkdir(dir_s4d2, 0755))
5533 	{
5534 		TH_LOG("Failed to create %s: %s", dir_s4d2, strerror(errno));
5535 	}
5536 
5537 	enforce_fs(_metadata, ACCESS_ALL, layer1);
5538 
5539 	/* From disconnected to connected. */
5540 	ASSERT_EQ(0, linkat(bind_s1d3_fd, file1_name, AT_FDCWD, file1_s2d2, 0))
5541 	{
5542 		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
5543 		       file1_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
5544 	}
5545 
5546 	/* Tests that we can access via the new link... */
5547 	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY))
5548 	{
5549 		TH_LOG("Failed to open newly linked %s: %s", file1_s2d2,
5550 		       strerror(errno));
5551 	}
5552 
5553 	/* ...as well as the old one. */
5554 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
5555 	{
5556 		TH_LOG("Failed to open original %s: %s", file1_s4d1,
5557 		       strerror(errno));
5558 	}
5559 
5560 	/* From connected to disconnected. */
5561 	ASSERT_EQ(0, unlink(file1_s4d1));
5562 	ASSERT_EQ(0, linkat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file2_name, 0))
5563 	{
5564 		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
5565 		       file1_s2d2, file2_name, bind_dir_s1d3, strerror(errno));
5566 	}
5567 	EXPECT_EQ(0, test_open(file2_s4d1, O_RDONLY));
5568 	ASSERT_EQ(0, unlink(file1_s2d2));
5569 
5570 	/* From disconnected to disconnected (same parent). */
5571 	ASSERT_EQ(0,
5572 		  linkat(bind_s1d3_fd, file2_name, bind_s1d3_fd, file1_name, 0))
5573 	{
5574 		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
5575 		       file2_name, file1_name, bind_dir_s1d3, strerror(errno));
5576 	}
5577 	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
5578 	{
5579 		TH_LOG("Failed to open newly linked %s: %s", file1_s4d1,
5580 		       strerror(errno));
5581 	}
5582 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY))
5583 	{
5584 		TH_LOG("Failed to open %s through newly created link under disconnected path: %s",
5585 		       file1_name, strerror(errno));
5586 	}
5587 	ASSERT_EQ(0, unlink(file2_s4d1));
5588 
5589 	/* From disconnected to disconnected (different parent). */
5590 	ASSERT_EQ(0,
5591 		  linkat(bind_s1d3_fd, file1_name, bind_s1d3_fd, "s4d2/f1", 0))
5592 	{
5593 		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
5594 		       file1_name, "s4d2/f1", bind_dir_s1d3, strerror(errno));
5595 	}
5596 	EXPECT_EQ(0, test_open(file1_s4d2, O_RDONLY))
5597 	{
5598 		TH_LOG("Failed to open %s after link: %s", file1_s4d2,
5599 		       strerror(errno));
5600 	}
5601 	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "s4d2/f1", O_RDONLY))
5602 	{
5603 		TH_LOG("Failed to open %s through disconnected path after link: %s",
5604 		       "s4d2/f1", strerror(errno));
5605 	}
5606 }
5607 
5608 /*
5609  * layout4_disconnected_leafs with bind mount and renames:
5610  *
5611  * tmp
5612  * ├── s1d1
5613  * │   └── s1d2 [source of the bind mount]
5614  * │       ├── s1d31
5615  * │       │   └── s1d41 [now renamed beneath s3d1]
5616  * │       │       ├── f1
5617  * │       │       └── f2
5618  * │       └── s1d32
5619  * │           └── s1d42 [now renamed beneath s4d1]
5620  * │               ├── f3
5621  * │               └── f4
5622  * ├── s2d1
5623  * │   └── s2d2 [bind mount of s1d2]
5624  * │       ├── s1d31
5625  * │       │   └── s1d41 [opened FD, now renamed beneath s3d1]
5626  * │       │       ├── f1
5627  * │       │       └── f2
5628  * │       └── s1d32
5629  * │           └── s1d42 [opened FD, now renamed beneath s4d1]
5630  * │               ├── f3
5631  * │               └── f4
5632  * ├── s3d1
5633  * │   └── s1d41 [renamed here]
5634  * │       ├── f1
5635  * │       └── f2
5636  * └── s4d1
5637  *     └── s1d42 [renamed here]
5638  *         ├── f3
5639  *         └── f4
5640  */
5641 /* clang-format off */
5642 FIXTURE(layout4_disconnected_leafs) {
5643 	int s2d2_fd;
5644 };
5645 /* clang-format on */
5646 
5647 FIXTURE_SETUP(layout4_disconnected_leafs)
5648 {
5649 	prepare_layout(_metadata);
5650 
5651 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1");
5652 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2");
5653 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3");
5654 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f4");
5655 	create_directory(_metadata, TMP_DIR "/s2d1/s2d2");
5656 	create_directory(_metadata, TMP_DIR "/s3d1");
5657 	create_directory(_metadata, TMP_DIR "/s4d1");
5658 
5659 	self->s2d2_fd =
5660 		open(TMP_DIR "/s2d1/s2d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
5661 	ASSERT_LE(0, self->s2d2_fd);
5662 
5663 	set_cap(_metadata, CAP_SYS_ADMIN);
5664 	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2", NULL,
5665 			   MS_BIND, NULL));
5666 	clear_cap(_metadata, CAP_SYS_ADMIN);
5667 }
5668 
5669 FIXTURE_TEARDOWN_PARENT(layout4_disconnected_leafs)
5670 {
5671 	/* umount(TMP_DIR "/s2d1") is handled by namespace lifetime. */
5672 
5673 	/* Removes files after renames. */
5674 	remove_path(TMP_DIR "/s3d1/s1d41/f1");
5675 	remove_path(TMP_DIR "/s3d1/s1d41/f2");
5676 	remove_path(TMP_DIR "/s4d1/s1d42/f1");
5677 	remove_path(TMP_DIR "/s4d1/s1d42/f3");
5678 	remove_path(TMP_DIR "/s4d1/s1d42/f4");
5679 	remove_path(TMP_DIR "/s4d1/s1d42/f5");
5680 
5681 	cleanup_layout(_metadata);
5682 }
5683 
5684 FIXTURE_VARIANT(layout4_disconnected_leafs)
5685 {
5686 	/*
5687 	 * Parent of the bind mount source.  It should always be ignored when
5688 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5689 	 */
5690 	const __u64 allowed_s1d1;
5691 	/*
5692 	 * Source of bind mount (to s2d2).  It should always be enforced when
5693 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5694 	 */
5695 	const __u64 allowed_s1d2;
5696 	/*
5697 	 * Original parent of s1d41.  It should always be ignored when testing
5698 	 * against files under the s1d41 disconnected directory.
5699 	 */
5700 	const __u64 allowed_s1d31;
5701 	/*
5702 	 * Original parent of s1d42.  It should always be ignored when testing
5703 	 * against files under the s1d42 disconnected directory.
5704 	 */
5705 	const __u64 allowed_s1d32;
5706 	/*
5707 	 * Opened and disconnected source directory.  It should always be enforced
5708 	 * when testing against files under the s1d41 disconnected directory.
5709 	 */
5710 	const __u64 allowed_s1d41;
5711 	/*
5712 	 * Opened and disconnected source directory.  It should always be enforced
5713 	 * when testing against files under the s1d42 disconnected directory.
5714 	 */
5715 	const __u64 allowed_s1d42;
5716 	/*
5717 	 * File in the s1d41 disconnected directory.  It should always be enforced
5718 	 * when testing against itself under the s1d41 disconnected directory.
5719 	 */
5720 	const __u64 allowed_f1;
5721 	/*
5722 	 * File in the s1d41 disconnected directory.  It should always be enforced
5723 	 * when testing against itself under the s1d41 disconnected directory.
5724 	 */
5725 	const __u64 allowed_f2;
5726 	/*
5727 	 * File in the s1d42 disconnected directory.  It should always be enforced
5728 	 * when testing against itself under the s1d42 disconnected directory.
5729 	 */
5730 	const __u64 allowed_f3;
5731 	/*
5732 	 * Parent of the bind mount destination.  It should always be enforced when
5733 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5734 	 */
5735 	const __u64 allowed_s2d1;
5736 	/*
5737 	 * Directory covered by the bind mount.  It should always be ignored when
5738 	 * testing against files under the s1d41 or s1d42 disconnected directories.
5739 	 */
5740 	const __u64 allowed_s2d2;
5741 	/*
5742 	 * New parent of the renamed s1d41.  It should always be ignored when
5743 	 * testing against files under the s1d41 disconnected directory.
5744 	 */
5745 	const __u64 allowed_s3d1;
5746 	/*
5747 	 * New parent of the renamed s1d42.  It should always be ignored when
5748 	 * testing against files under the s1d42 disconnected directory.
5749 	 */
5750 	const __u64 allowed_s4d1;
5751 
5752 	/* Expected result of the call to open([fd:s1d41]/f1, O_RDONLY). */
5753 	const int expected_read_result;
5754 	/* Expected result of the call to renameat([fd:s1d41]/f1, [fd:s1d42]/f1). */
5755 	const int expected_rename_result;
5756 	/*
5757 	 * Expected result of the call to renameat([fd:s1d41]/f2, [fd:s1d42]/f3,
5758 	 * RENAME_EXCHANGE).
5759 	 */
5760 	const int expected_exchange_result;
5761 	/* Expected result of the call to renameat([fd:s1d42]/f4, [fd:s1d42]/f5). */
5762 	const int expected_same_dir_rename_result;
5763 };
5764 
5765 /* clang-format off */
5766 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d1_mount_src_parent) {
5767 	/* clang-format on */
5768 	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
5769 			LANDLOCK_ACCESS_FS_READ_FILE |
5770 			LANDLOCK_ACCESS_FS_EXECUTE |
5771 			LANDLOCK_ACCESS_FS_MAKE_REG,
5772 	.expected_read_result = EACCES,
5773 	.expected_same_dir_rename_result = EACCES,
5774 	.expected_rename_result = EACCES,
5775 	.expected_exchange_result = EACCES,
5776 };
5777 
5778 /* clang-format off */
5779 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_refer) {
5780 	/* clang-format on */
5781 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5782 	.expected_read_result = 0,
5783 	.expected_same_dir_rename_result = EACCES,
5784 	.expected_rename_result = EACCES,
5785 	.expected_exchange_result = EACCES,
5786 };
5787 
5788 /* clang-format off */
5789 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_create) {
5790 	/* clang-format on */
5791 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
5792 			LANDLOCK_ACCESS_FS_MAKE_REG,
5793 	.expected_read_result = 0,
5794 	.expected_same_dir_rename_result = 0,
5795 	.expected_rename_result = EXDEV,
5796 	.expected_exchange_result = EXDEV,
5797 };
5798 
5799 /* clang-format off */
5800 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_rename) {
5801 	/* clang-format on */
5802 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5803 	.expected_read_result = EACCES,
5804 	.expected_same_dir_rename_result = 0,
5805 	.expected_rename_result = 0,
5806 	.expected_exchange_result = 0,
5807 };
5808 
5809 /* clang-format off */
5810 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d31_s1d32_old_parent) {
5811 	/* clang-format on */
5812 	.allowed_s1d31 = LANDLOCK_ACCESS_FS_REFER |
5813 			 LANDLOCK_ACCESS_FS_READ_FILE |
5814 			 LANDLOCK_ACCESS_FS_EXECUTE |
5815 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5816 	.allowed_s1d32 = LANDLOCK_ACCESS_FS_REFER |
5817 			 LANDLOCK_ACCESS_FS_READ_FILE |
5818 			 LANDLOCK_ACCESS_FS_EXECUTE |
5819 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5820 	.expected_read_result = EACCES,
5821 	.expected_same_dir_rename_result = EACCES,
5822 	.expected_rename_result = EACCES,
5823 	.expected_exchange_result = EACCES,
5824 };
5825 
5826 /* clang-format off */
5827 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_refer) {
5828 	/* clang-format on */
5829 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
5830 			 LANDLOCK_ACCESS_FS_READ_FILE,
5831 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
5832 			 LANDLOCK_ACCESS_FS_READ_FILE,
5833 	.expected_read_result = 0,
5834 	.expected_same_dir_rename_result = EACCES,
5835 	.expected_rename_result = EACCES,
5836 	.expected_exchange_result = EACCES,
5837 };
5838 
5839 /* clang-format off */
5840 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_create) {
5841 	/* clang-format on */
5842 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_READ_FILE |
5843 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5844 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_READ_FILE |
5845 			 LANDLOCK_ACCESS_FS_MAKE_REG,
5846 	.expected_read_result = 0,
5847 	.expected_same_dir_rename_result = 0,
5848 	.expected_rename_result = EXDEV,
5849 	.expected_exchange_result = EXDEV,
5850 };
5851 
5852 /* clang-format off */
5853 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_even) {
5854 	/* clang-format on */
5855 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5856 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5857 	.expected_read_result = EACCES,
5858 	.expected_same_dir_rename_result = 0,
5859 	.expected_rename_result = 0,
5860 	.expected_exchange_result = 0,
5861 };
5862 
5863 /* The destination directory has more access right. */
5864 /* clang-format off */
5865 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_more) {
5866 	/* clang-format on */
5867 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5868 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
5869 			 LANDLOCK_ACCESS_FS_MAKE_REG |
5870 			 LANDLOCK_ACCESS_FS_EXECUTE,
5871 	.expected_read_result = EACCES,
5872 	.expected_same_dir_rename_result = 0,
5873 	/* Access denied. */
5874 	.expected_rename_result = EXDEV,
5875 	.expected_exchange_result = EXDEV,
5876 };
5877 
5878 /* The destination directory has less access right. */
5879 /* clang-format off */
5880 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_less) {
5881 	/* clang-format on */
5882 	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
5883 			 LANDLOCK_ACCESS_FS_MAKE_REG |
5884 			 LANDLOCK_ACCESS_FS_EXECUTE,
5885 	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5886 	.expected_read_result = EACCES,
5887 	.expected_same_dir_rename_result = 0,
5888 	/* Access allowed. */
5889 	.expected_rename_result = 0,
5890 	.expected_exchange_result = EXDEV,
5891 };
5892 
5893 /* clang-format off */
5894 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_create) {
5895 	/* clang-format on */
5896 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5897 			LANDLOCK_ACCESS_FS_MAKE_REG,
5898 	.expected_read_result = 0,
5899 	.expected_same_dir_rename_result = 0,
5900 	.expected_rename_result = EXDEV,
5901 	.expected_exchange_result = EXDEV,
5902 };
5903 
5904 /* clang-format off */
5905 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_refer) {
5906 	/* clang-format on */
5907 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5908 	.expected_read_result = 0,
5909 	.expected_same_dir_rename_result = EACCES,
5910 	.expected_rename_result = EACCES,
5911 	.expected_exchange_result = EACCES,
5912 };
5913 
5914 /* clang-format off */
5915 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_mini) {
5916 	/* clang-format on */
5917 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
5918 			LANDLOCK_ACCESS_FS_READ_FILE |
5919 			LANDLOCK_ACCESS_FS_MAKE_REG,
5920 	.expected_read_result = 0,
5921 	.expected_same_dir_rename_result = 0,
5922 	.expected_rename_result = 0,
5923 	.expected_exchange_result = 0,
5924 };
5925 
5926 /* clang-format off */
5927 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d2_covered_by_mount) {
5928 	/* clang-format on */
5929 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER |
5930 			LANDLOCK_ACCESS_FS_READ_FILE |
5931 			LANDLOCK_ACCESS_FS_EXECUTE |
5932 			LANDLOCK_ACCESS_FS_MAKE_REG,
5933 	.expected_read_result = EACCES,
5934 	.expected_same_dir_rename_result = EACCES,
5935 	.expected_rename_result = EACCES,
5936 	.expected_exchange_result = EACCES,
5937 };
5938 
5939 /* Tests collect_domain_accesses(). */
5940 /* clang-format off */
5941 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_refer) {
5942 	/* clang-format on */
5943 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5944 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
5945 	.expected_read_result = 0,
5946 	.expected_same_dir_rename_result = EACCES,
5947 	.expected_rename_result = EACCES,
5948 	.expected_exchange_result = EACCES,
5949 };
5950 
5951 /* clang-format off */
5952 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_create) {
5953 	/* clang-format on */
5954 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5955 			LANDLOCK_ACCESS_FS_MAKE_REG,
5956 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
5957 			LANDLOCK_ACCESS_FS_MAKE_REG,
5958 	.expected_read_result = 0,
5959 	.expected_same_dir_rename_result = 0,
5960 	.expected_rename_result = EXDEV,
5961 	.expected_exchange_result = EXDEV,
5962 };
5963 
5964 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs,
5965 		    s3d1_s4d1_disconnected_rename_even){
5966 	/* clang-format on */
5967 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5968 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5969 	.expected_read_result = EACCES,
5970 	.expected_same_dir_rename_result = 0,
5971 	.expected_rename_result = 0,
5972 	.expected_exchange_result = 0,
5973 };
5974 
5975 /* The destination directory has more access right. */
5976 /* clang-format off */
5977 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_more) {
5978 	/* clang-format on */
5979 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5980 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
5981 			LANDLOCK_ACCESS_FS_EXECUTE,
5982 	.expected_read_result = EACCES,
5983 	.expected_same_dir_rename_result = 0,
5984 	/* Access denied. */
5985 	.expected_rename_result = EXDEV,
5986 	.expected_exchange_result = EXDEV,
5987 };
5988 
5989 /* The destination directory has less access right. */
5990 /* clang-format off */
5991 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_less) {
5992 	/* clang-format on */
5993 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
5994 			LANDLOCK_ACCESS_FS_EXECUTE,
5995 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
5996 	.expected_read_result = EACCES,
5997 	.expected_same_dir_rename_result = 0,
5998 	/* Access allowed. */
5999 	.expected_rename_result = 0,
6000 	.expected_exchange_result = EXDEV,
6001 };
6002 
6003 /* clang-format off */
6004 FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, f1_f2_f3) {
6005 	/* clang-format on */
6006 	.allowed_f1 = LANDLOCK_ACCESS_FS_READ_FILE,
6007 	.allowed_f2 = LANDLOCK_ACCESS_FS_READ_FILE,
6008 	.allowed_f3 = LANDLOCK_ACCESS_FS_READ_FILE,
6009 	.expected_read_result = 0,
6010 	.expected_same_dir_rename_result = EACCES,
6011 	.expected_rename_result = EACCES,
6012 	.expected_exchange_result = EACCES,
6013 };
6014 
6015 TEST_F_FORK(layout4_disconnected_leafs, read_rename_exchange)
6016 {
6017 	const __u64 handled_access =
6018 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
6019 		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
6020 	const struct rule rules[] = {
6021 		{
6022 			.path = TMP_DIR "/s1d1",
6023 			.access = variant->allowed_s1d1,
6024 		},
6025 		{
6026 			.path = TMP_DIR "/s1d1/s1d2",
6027 			.access = variant->allowed_s1d2,
6028 		},
6029 		{
6030 			.path = TMP_DIR "/s1d1/s1d2/s1d31",
6031 			.access = variant->allowed_s1d31,
6032 		},
6033 		{
6034 			.path = TMP_DIR "/s1d1/s1d2/s1d32",
6035 			.access = variant->allowed_s1d32,
6036 		},
6037 		{
6038 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
6039 			.access = variant->allowed_s1d41,
6040 		},
6041 		{
6042 			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
6043 			.access = variant->allowed_s1d42,
6044 		},
6045 		{
6046 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1",
6047 			.access = variant->allowed_f1,
6048 		},
6049 		{
6050 			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2",
6051 			.access = variant->allowed_f2,
6052 		},
6053 		{
6054 			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3",
6055 			.access = variant->allowed_f3,
6056 		},
6057 		{
6058 			.path = TMP_DIR "/s2d1",
6059 			.access = variant->allowed_s2d1,
6060 		},
6061 		/* s2d2_fd */
6062 		{
6063 			.path = TMP_DIR "/s3d1",
6064 			.access = variant->allowed_s3d1,
6065 		},
6066 		{
6067 			.path = TMP_DIR "/s4d1",
6068 			.access = variant->allowed_s4d1,
6069 		},
6070 		{},
6071 	};
6072 	int ruleset_fd, s1d41_bind_fd, s1d42_bind_fd;
6073 
6074 	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
6075 
6076 	/* Adds rule for the covered directory. */
6077 	if (variant->allowed_s2d2) {
6078 		ASSERT_EQ(0, landlock_add_rule(
6079 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6080 				     &(struct landlock_path_beneath_attr){
6081 					     .parent_fd = self->s2d2_fd,
6082 					     .allowed_access =
6083 						     variant->allowed_s2d2,
6084 				     },
6085 				     0));
6086 	}
6087 	EXPECT_EQ(0, close(self->s2d2_fd));
6088 
6089 	s1d41_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d31/s1d41",
6090 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6091 	ASSERT_LE(0, s1d41_bind_fd);
6092 	s1d42_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d32/s1d42",
6093 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6094 	ASSERT_LE(0, s1d42_bind_fd);
6095 
6096 	/* Disconnects and checks source and destination directories. */
6097 	EXPECT_EQ(0, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
6098 	EXPECT_EQ(0, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
6099 	/* Renames to make it accessible through s3d1/s1d41 */
6100 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
6101 				   AT_FDCWD, TMP_DIR "/s3d1/s1d41"));
6102 	/* Renames to make it accessible through s4d1/s1d42 */
6103 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
6104 				   AT_FDCWD, TMP_DIR "/s4d1/s1d42"));
6105 	EXPECT_EQ(ENOENT, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
6106 	EXPECT_EQ(ENOENT, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
6107 
6108 	enforce_ruleset(_metadata, ruleset_fd);
6109 	EXPECT_EQ(0, close(ruleset_fd));
6110 
6111 	EXPECT_EQ(variant->expected_read_result,
6112 		  test_open_rel(s1d41_bind_fd, "f1", O_RDONLY));
6113 
6114 	EXPECT_EQ(variant->expected_rename_result,
6115 		  test_renameat(s1d41_bind_fd, "f1", s1d42_bind_fd, "f1"));
6116 	EXPECT_EQ(variant->expected_exchange_result,
6117 		  test_exchangeat(s1d41_bind_fd, "f2", s1d42_bind_fd, "f3"));
6118 
6119 	EXPECT_EQ(variant->expected_same_dir_rename_result,
6120 		  test_renameat(s1d42_bind_fd, "f4", s1d42_bind_fd, "f5"));
6121 }
6122 
6123 /*
6124  * layout5_disconnected_branch before rename:
6125  *
6126  * tmp
6127  * ├── s1d1
6128  * │   └── s1d2 [source of the first bind mount]
6129  * │       └── s1d3
6130  * │           ├── s1d41
6131  * │           │   ├── f1
6132  * │           │   └── f2
6133  * │           └── s1d42
6134  * │               ├── f3
6135  * │               └── f4
6136  * ├── s2d1
6137  * │   └── s2d2 [source of the second bind mount]
6138  * │       └── s2d3
6139  * │           └── s2d4 [first s1d2 bind mount]
6140  * │               └── s1d3
6141  * │                   ├── s1d41
6142  * │                   │   ├── f1
6143  * │                   │   └── f2
6144  * │                   └── s1d42
6145  * │                       ├── f3
6146  * │                       └── f4
6147  * ├── s3d1
6148  * │   └── s3d2 [second s2d2 bind mount]
6149  * │       └── s2d3
6150  * │           └── s2d4 [first s1d2 bind mount]
6151  * │               └── s1d3
6152  * │                   ├── s1d41
6153  * │                   │   ├── f1
6154  * │                   │   └── f2
6155  * │                   └── s1d42
6156  * │                       ├── f3
6157  * │                       └── f4
6158  * └── s4d1
6159  *
6160  * After rename:
6161  *
6162  * tmp
6163  * ├── s1d1
6164  * │   └── s1d2 [source of the first bind mount]
6165  * │       └── s1d3
6166  * │           ├── s1d41
6167  * │           │   ├── f1
6168  * │           │   └── f2
6169  * │           └── s1d42
6170  * │               ├── f3
6171  * │               └── f4
6172  * ├── s2d1
6173  * │   └── s2d2 [source of the second bind mount]
6174  * ├── s3d1
6175  * │   └── s3d2 [second s2d2 bind mount]
6176  * └── s4d1
6177  *     └── s2d3 [renamed here]
6178  *         └── s2d4 [first s1d2 bind mount]
6179  *             └── s1d3
6180  *                 ├── s1d41
6181  *                 │   ├── f1
6182  *                 │   └── f2
6183  *                 └── s1d42
6184  *                     ├── f3
6185  *                     └── f4
6186  *
6187  * Decision path for access from the s3d1/s3d2/s2d3/s2d4/s1d3 file descriptor:
6188  *   1. first bind mount:   s1d3 -> s1d2
6189  *   2. second bind mount:    s2d3
6190  *   3. tmp mount:              s4d1 -> tmp [disconnected branch]
6191  *   4. second bind mount:        s2d2
6192  *   5. tmp mount:                  s3d1 -> tmp
6193  *   6. parent mounts:                [...] -> /
6194  *
6195  * The s4d1 directory is evaluated even if it is not in the s2d2 mount.
6196  */
6197 
6198 /* clang-format off */
6199 FIXTURE(layout5_disconnected_branch) {
6200 	int s2d4_fd, s3d2_fd;
6201 };
6202 /* clang-format on */
6203 
6204 FIXTURE_SETUP(layout5_disconnected_branch)
6205 {
6206 	prepare_layout(_metadata);
6207 
6208 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
6209 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
6210 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
6211 	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
6212 	create_directory(_metadata, TMP_DIR "/s2d1/s2d2/s2d3/s2d4");
6213 	create_directory(_metadata, TMP_DIR "/s3d1/s3d2");
6214 	create_directory(_metadata, TMP_DIR "/s4d1");
6215 
6216 	self->s2d4_fd = open(TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
6217 			     O_DIRECTORY | O_PATH | O_CLOEXEC);
6218 	ASSERT_LE(0, self->s2d4_fd);
6219 
6220 	self->s3d2_fd =
6221 		open(TMP_DIR "/s3d1/s3d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
6222 	ASSERT_LE(0, self->s3d2_fd);
6223 
6224 	set_cap(_metadata, CAP_SYS_ADMIN);
6225 	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
6226 			   NULL, MS_BIND, NULL));
6227 	ASSERT_EQ(0, mount(TMP_DIR "/s2d1/s2d2", TMP_DIR "/s3d1/s3d2", NULL,
6228 			   MS_BIND | MS_REC, NULL));
6229 	clear_cap(_metadata, CAP_SYS_ADMIN);
6230 }
6231 
6232 FIXTURE_TEARDOWN_PARENT(layout5_disconnected_branch)
6233 {
6234 	/* Bind mounts are handled by namespace lifetime. */
6235 
6236 	/* Removes files after renames. */
6237 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
6238 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
6239 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f1");
6240 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
6241 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
6242 	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f5");
6243 
6244 	cleanup_layout(_metadata);
6245 }
6246 
6247 FIXTURE_VARIANT(layout5_disconnected_branch)
6248 {
6249 	/*
6250 	 * Parent of all files.  It should always be enforced when testing against
6251 	 * files under the s1d41 or s1d42 disconnected directories.
6252 	 */
6253 	const __u64 allowed_base;
6254 	/*
6255 	 * Parent of the first bind mount source.  It should always be ignored when
6256 	 * testing against files under the s1d41 or s1d42 disconnected directories.
6257 	 */
6258 	const __u64 allowed_s1d1;
6259 	const __u64 allowed_s1d2;
6260 	const __u64 allowed_s1d3;
6261 	const __u64 allowed_s2d1;
6262 	const __u64 allowed_s2d2;
6263 	const __u64 allowed_s2d3;
6264 	const __u64 allowed_s2d4;
6265 	const __u64 allowed_s3d1;
6266 	const __u64 allowed_s3d2;
6267 	const __u64 allowed_s4d1;
6268 
6269 	/* Expected result of the call to open([fd:s1d3]/s1d41/f1, O_RDONLY). */
6270 	const int expected_read_result;
6271 	/*
6272 	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f1,
6273 	 * [fd:s1d3]/s1d42/f1).
6274 	 */
6275 	const int expected_rename_result;
6276 	/*
6277 	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f2,
6278 	 * [fd:s1d3]/s1d42/f3,  RENAME_EXCHANGE).
6279 	 */
6280 	const int expected_exchange_result;
6281 	/*
6282 	 * Expected result of the call to renameat([fd:s1d3]/s1d42/f4,
6283 	 * [fd:s1d3]/s1d42/f5).
6284 	 */
6285 	const int expected_same_dir_rename_result;
6286 };
6287 
6288 /* clang-format off */
6289 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d1_mount1_src_parent) {
6290 	/* clang-format on */
6291 	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
6292 			LANDLOCK_ACCESS_FS_READ_FILE |
6293 			LANDLOCK_ACCESS_FS_EXECUTE |
6294 			LANDLOCK_ACCESS_FS_MAKE_REG,
6295 	.expected_read_result = EACCES,
6296 	.expected_same_dir_rename_result = EACCES,
6297 	.expected_rename_result = EACCES,
6298 	.expected_exchange_result = EACCES,
6299 };
6300 
6301 /* clang-format off */
6302 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_refer) {
6303 	/* clang-format on */
6304 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6305 	.expected_read_result = 0,
6306 	.expected_same_dir_rename_result = EACCES,
6307 	.expected_rename_result = EACCES,
6308 	.expected_exchange_result = EACCES,
6309 };
6310 
6311 /* clang-format off */
6312 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_create) {
6313 	/* clang-format on */
6314 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
6315 			LANDLOCK_ACCESS_FS_MAKE_REG,
6316 	.expected_read_result = 0,
6317 	.expected_same_dir_rename_result = 0,
6318 	.expected_rename_result = EXDEV,
6319 	.expected_exchange_result = EXDEV,
6320 };
6321 
6322 /* clang-format off */
6323 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_rename) {
6324 	/* clang-format on */
6325 	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6326 	.expected_read_result = EACCES,
6327 	.expected_same_dir_rename_result = 0,
6328 	.expected_rename_result = 0,
6329 	.expected_exchange_result = 0,
6330 };
6331 
6332 /* clang-format off */
6333 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_refer) {
6334 	/* clang-format on */
6335 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6336 	.expected_read_result = 0,
6337 	.expected_same_dir_rename_result = EACCES,
6338 	.expected_rename_result = EACCES,
6339 	.expected_exchange_result = EACCES,
6340 };
6341 
6342 /* clang-format off */
6343 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_create) {
6344 	/* clang-format on */
6345 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_READ_FILE |
6346 			LANDLOCK_ACCESS_FS_MAKE_REG,
6347 	.expected_read_result = 0,
6348 	.expected_same_dir_rename_result = 0,
6349 	.expected_rename_result = EXDEV,
6350 	.expected_exchange_result = EXDEV,
6351 };
6352 
6353 /* clang-format off */
6354 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_rename) {
6355 	/* clang-format on */
6356 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6357 	.expected_read_result = EACCES,
6358 	.expected_same_dir_rename_result = 0,
6359 	.expected_rename_result = 0,
6360 	.expected_exchange_result = 0,
6361 };
6362 
6363 /* clang-format off */
6364 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_full) {
6365 	/* clang-format on */
6366 	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER |
6367 			LANDLOCK_ACCESS_FS_READ_FILE |
6368 			LANDLOCK_ACCESS_FS_EXECUTE |
6369 			LANDLOCK_ACCESS_FS_MAKE_REG,
6370 	.expected_read_result = 0,
6371 	.expected_same_dir_rename_result = 0,
6372 	.expected_rename_result = 0,
6373 	.expected_exchange_result = 0,
6374 };
6375 
6376 /* clang-format off */
6377 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d1_mount2_src_parent) {
6378 	/* clang-format on */
6379 	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
6380 			LANDLOCK_ACCESS_FS_READ_FILE |
6381 			LANDLOCK_ACCESS_FS_EXECUTE |
6382 			LANDLOCK_ACCESS_FS_MAKE_REG,
6383 	.expected_read_result = EACCES,
6384 	.expected_same_dir_rename_result = EACCES,
6385 	.expected_rename_result = EACCES,
6386 	.expected_exchange_result = EACCES,
6387 };
6388 
6389 /* clang-format off */
6390 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_refer) {
6391 	/* clang-format on */
6392 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6393 	.expected_read_result = 0,
6394 	.expected_same_dir_rename_result = EACCES,
6395 	.expected_rename_result = EACCES,
6396 	.expected_exchange_result = EACCES,
6397 };
6398 
6399 /* clang-format off */
6400 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_create) {
6401 	/* clang-format on */
6402 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_READ_FILE |
6403 			LANDLOCK_ACCESS_FS_MAKE_REG,
6404 	.expected_read_result = 0,
6405 	.expected_same_dir_rename_result = 0,
6406 	.expected_rename_result = EXDEV,
6407 	.expected_exchange_result = EXDEV,
6408 };
6409 
6410 /* clang-format off */
6411 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_rename) {
6412 	/* clang-format on */
6413 	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6414 	.expected_read_result = EACCES,
6415 	.expected_same_dir_rename_result = 0,
6416 	.expected_rename_result = 0,
6417 	.expected_exchange_result = 0,
6418 };
6419 
6420 /* clang-format off */
6421 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_refer) {
6422 	/* clang-format on */
6423 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6424 	.expected_read_result = 0,
6425 	.expected_same_dir_rename_result = EACCES,
6426 	.expected_rename_result = EACCES,
6427 	.expected_exchange_result = EACCES,
6428 };
6429 
6430 /* clang-format off */
6431 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_create) {
6432 	/* clang-format on */
6433 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_READ_FILE |
6434 			LANDLOCK_ACCESS_FS_MAKE_REG,
6435 	.expected_read_result = 0,
6436 	.expected_same_dir_rename_result = 0,
6437 	.expected_rename_result = EXDEV,
6438 	.expected_exchange_result = EXDEV,
6439 };
6440 
6441 /* clang-format off */
6442 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_rename) {
6443 	/* clang-format on */
6444 	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6445 	.expected_read_result = EACCES,
6446 	.expected_same_dir_rename_result = 0,
6447 	.expected_rename_result = 0,
6448 	.expected_exchange_result = 0,
6449 };
6450 
6451 /* clang-format off */
6452 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d4_mount1_dst) {
6453 	/* clang-format on */
6454 	.allowed_s2d4 = LANDLOCK_ACCESS_FS_REFER |
6455 			LANDLOCK_ACCESS_FS_READ_FILE |
6456 			LANDLOCK_ACCESS_FS_EXECUTE |
6457 			LANDLOCK_ACCESS_FS_MAKE_REG,
6458 	.expected_read_result = EACCES,
6459 	.expected_same_dir_rename_result = EACCES,
6460 	.expected_rename_result = EACCES,
6461 	.expected_exchange_result = EACCES,
6462 };
6463 
6464 /* clang-format off */
6465 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_refer) {
6466 	/* clang-format on */
6467 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6468 	.expected_read_result = 0,
6469 	.expected_same_dir_rename_result = EACCES,
6470 	.expected_rename_result = EACCES,
6471 	.expected_exchange_result = EACCES,
6472 };
6473 
6474 /* clang-format off */
6475 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_create) {
6476 	/* clang-format on */
6477 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
6478 			LANDLOCK_ACCESS_FS_MAKE_REG,
6479 	.expected_read_result = 0,
6480 	.expected_same_dir_rename_result = 0,
6481 	.expected_rename_result = EXDEV,
6482 	.expected_exchange_result = EXDEV,
6483 };
6484 
6485 /* clang-format off */
6486 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_rename) {
6487 	/* clang-format on */
6488 	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6489 	.expected_read_result = EACCES,
6490 	.expected_same_dir_rename_result = 0,
6491 	.expected_rename_result = 0,
6492 	.expected_exchange_result = 0,
6493 };
6494 
6495 /* clang-format off */
6496 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d2_mount1_dst) {
6497 	/* clang-format on */
6498 	.allowed_s3d2 = LANDLOCK_ACCESS_FS_REFER |
6499 			LANDLOCK_ACCESS_FS_READ_FILE |
6500 			LANDLOCK_ACCESS_FS_EXECUTE |
6501 			LANDLOCK_ACCESS_FS_MAKE_REG,
6502 	.expected_read_result = EACCES,
6503 	.expected_same_dir_rename_result = EACCES,
6504 	.expected_rename_result = EACCES,
6505 	.expected_exchange_result = EACCES,
6506 };
6507 
6508 /* clang-format off */
6509 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_refer) {
6510 	/* clang-format on */
6511 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
6512 	.expected_read_result = 0,
6513 	.expected_same_dir_rename_result = EACCES,
6514 	.expected_rename_result = EACCES,
6515 	.expected_exchange_result = EACCES,
6516 };
6517 
6518 /* clang-format off */
6519 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_create) {
6520 	/* clang-format on */
6521 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
6522 			LANDLOCK_ACCESS_FS_MAKE_REG,
6523 	.expected_read_result = 0,
6524 	.expected_same_dir_rename_result = 0,
6525 	.expected_rename_result = EXDEV,
6526 	.expected_exchange_result = EXDEV,
6527 };
6528 
6529 /* clang-format off */
6530 FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_rename) {
6531 	/* clang-format on */
6532 	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
6533 	.expected_read_result = EACCES,
6534 	.expected_same_dir_rename_result = 0,
6535 	.expected_rename_result = 0,
6536 	.expected_exchange_result = 0,
6537 };
6538 
6539 TEST_F_FORK(layout5_disconnected_branch, read_rename_exchange)
6540 {
6541 	const __u64 handled_access =
6542 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
6543 		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
6544 	const struct rule rules[] = {
6545 		{
6546 			.path = TMP_DIR "/s1d1",
6547 			.access = variant->allowed_s1d1,
6548 		},
6549 		{
6550 			.path = TMP_DIR "/s1d1/s1d2",
6551 			.access = variant->allowed_s1d2,
6552 		},
6553 		{
6554 			.path = TMP_DIR "/s1d1/s1d2/s1d3",
6555 			.access = variant->allowed_s1d3,
6556 		},
6557 		{
6558 			.path = TMP_DIR "/s2d1",
6559 			.access = variant->allowed_s2d1,
6560 		},
6561 		{
6562 			.path = TMP_DIR "/s2d1/s2d2",
6563 			.access = variant->allowed_s2d2,
6564 		},
6565 		{
6566 			.path = TMP_DIR "/s2d1/s2d2/s2d3",
6567 			.access = variant->allowed_s2d3,
6568 		},
6569 		/* s2d4_fd */
6570 		{
6571 			.path = TMP_DIR "/s3d1",
6572 			.access = variant->allowed_s3d1,
6573 		},
6574 		/* s3d2_fd */
6575 		{
6576 			.path = TMP_DIR "/s4d1",
6577 			.access = variant->allowed_s4d1,
6578 		},
6579 		{},
6580 	};
6581 	int ruleset_fd, s1d3_bind_fd;
6582 
6583 	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
6584 	ASSERT_LE(0, ruleset_fd);
6585 
6586 	/* Adds rules for the covered directories. */
6587 	if (variant->allowed_s2d4) {
6588 		ASSERT_EQ(0, landlock_add_rule(
6589 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6590 				     &(struct landlock_path_beneath_attr){
6591 					     .parent_fd = self->s2d4_fd,
6592 					     .allowed_access =
6593 						     variant->allowed_s2d4,
6594 				     },
6595 				     0));
6596 	}
6597 	EXPECT_EQ(0, close(self->s2d4_fd));
6598 
6599 	if (variant->allowed_s3d2) {
6600 		ASSERT_EQ(0, landlock_add_rule(
6601 				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
6602 				     &(struct landlock_path_beneath_attr){
6603 					     .parent_fd = self->s3d2_fd,
6604 					     .allowed_access =
6605 						     variant->allowed_s3d2,
6606 				     },
6607 				     0));
6608 	}
6609 	EXPECT_EQ(0, close(self->s3d2_fd));
6610 
6611 	s1d3_bind_fd = open(TMP_DIR "/s3d1/s3d2/s2d3/s2d4/s1d3",
6612 			    O_DIRECTORY | O_PATH | O_CLOEXEC);
6613 	ASSERT_LE(0, s1d3_bind_fd);
6614 
6615 	/* Disconnects and checks source and destination directories. */
6616 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
6617 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
6618 	/* Renames to make it accessible through s3d1/s1d41 */
6619 	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s2d1/s2d2/s2d3",
6620 				   AT_FDCWD, TMP_DIR "/s4d1/s2d3"));
6621 	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
6622 	EXPECT_EQ(ENOENT, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
6623 
6624 	enforce_ruleset(_metadata, ruleset_fd);
6625 	EXPECT_EQ(0, close(ruleset_fd));
6626 
6627 	EXPECT_EQ(variant->expected_read_result,
6628 		  test_open_rel(s1d3_bind_fd, "s1d41/f1", O_RDONLY));
6629 
6630 	EXPECT_EQ(variant->expected_rename_result,
6631 		  test_renameat(s1d3_bind_fd, "s1d41/f1", s1d3_bind_fd,
6632 				"s1d42/f1"));
6633 	EXPECT_EQ(variant->expected_exchange_result,
6634 		  test_exchangeat(s1d3_bind_fd, "s1d41/f2", s1d3_bind_fd,
6635 				  "s1d42/f3"));
6636 
6637 	EXPECT_EQ(variant->expected_same_dir_rename_result,
6638 		  test_renameat(s1d3_bind_fd, "s1d42/f4", s1d3_bind_fd,
6639 				"s1d42/f5"));
6640 }
6641 
6642 #define LOWER_BASE TMP_DIR "/lower"
6643 #define LOWER_DATA LOWER_BASE "/data"
6644 static const char lower_fl1[] = LOWER_DATA "/fl1";
6645 static const char lower_dl1[] = LOWER_DATA "/dl1";
6646 static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2";
6647 static const char lower_fo1[] = LOWER_DATA "/fo1";
6648 static const char lower_do1[] = LOWER_DATA "/do1";
6649 static const char lower_do1_fo2[] = LOWER_DATA "/do1/fo2";
6650 static const char lower_do1_fl3[] = LOWER_DATA "/do1/fl3";
6651 /* lower_pl1 is a FIFO and is deliberately not in the lists below. */
6652 static const char lower_pl1[] = LOWER_DATA "/pl1";
6653 
6654 static const char (*lower_base_files[])[] = {
6655 	&lower_fl1,
6656 	&lower_fo1,
6657 	NULL,
6658 };
6659 static const char (*lower_base_directories[])[] = {
6660 	&lower_dl1,
6661 	&lower_do1,
6662 	NULL,
6663 };
6664 static const char (*lower_sub_files[])[] = {
6665 	&lower_dl1_fl2,
6666 	&lower_do1_fo2,
6667 	&lower_do1_fl3,
6668 	NULL,
6669 };
6670 
6671 #define UPPER_BASE TMP_DIR "/upper"
6672 #define UPPER_DATA UPPER_BASE "/data"
6673 #define UPPER_WORK UPPER_BASE "/work"
6674 static const char upper_fu1[] = UPPER_DATA "/fu1";
6675 static const char upper_du1[] = UPPER_DATA "/du1";
6676 static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2";
6677 static const char upper_fo1[] = UPPER_DATA "/fo1";
6678 static const char upper_do1[] = UPPER_DATA "/do1";
6679 static const char upper_do1_fo2[] = UPPER_DATA "/do1/fo2";
6680 static const char upper_do1_fu3[] = UPPER_DATA "/do1/fu3";
6681 
6682 static const char (*upper_base_files[])[] = {
6683 	&upper_fu1,
6684 	&upper_fo1,
6685 	NULL,
6686 };
6687 static const char (*upper_base_directories[])[] = {
6688 	&upper_du1,
6689 	&upper_do1,
6690 	NULL,
6691 };
6692 static const char (*upper_sub_files[])[] = {
6693 	&upper_du1_fu2,
6694 	&upper_do1_fo2,
6695 	&upper_do1_fu3,
6696 	NULL,
6697 };
6698 
6699 #define MERGE_BASE TMP_DIR "/merge"
6700 #define MERGE_DATA MERGE_BASE "/data"
6701 static const char merge_fl1[] = MERGE_DATA "/fl1";
6702 /* merge_pl1 is a FIFO and is deliberately not in the lists below. */
6703 static const char merge_pl1[] = MERGE_DATA "/pl1";
6704 static const char merge_dl1[] = MERGE_DATA "/dl1";
6705 static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2";
6706 static const char merge_fu1[] = MERGE_DATA "/fu1";
6707 static const char merge_du1[] = MERGE_DATA "/du1";
6708 static const char merge_du1_fu2[] = MERGE_DATA "/du1/fu2";
6709 static const char merge_fo1[] = MERGE_DATA "/fo1";
6710 static const char merge_do1[] = MERGE_DATA "/do1";
6711 static const char merge_do1_fo2[] = MERGE_DATA "/do1/fo2";
6712 static const char merge_do1_fl3[] = MERGE_DATA "/do1/fl3";
6713 static const char merge_do1_fu3[] = MERGE_DATA "/do1/fu3";
6714 
6715 static const char (*merge_base_files[])[] = {
6716 	&merge_fl1,
6717 	&merge_fu1,
6718 	&merge_fo1,
6719 	NULL,
6720 };
6721 static const char (*merge_base_directories[])[] = {
6722 	&merge_dl1,
6723 	&merge_du1,
6724 	&merge_do1,
6725 	NULL,
6726 };
6727 static const char (*merge_sub_files[])[] = {
6728 	&merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2,
6729 	&merge_do1_fl3, &merge_do1_fu3, NULL,
6730 };
6731 
6732 /*
6733  * layout2_overlay hierarchy:
6734  *
6735  * tmp
6736  * ├── lower
6737  * │   └── data
6738  * │       ├── dl1
6739  * │       │   └── fl2
6740  * │       ├── do1
6741  * │       │   ├── fl3
6742  * │       │   └── fo2
6743  * │       ├── fl1
6744  * │       ├── fo1
6745  * │       └── pl1 [FIFO]
6746  * ├── merge
6747  * │   └── data
6748  * │       ├── dl1
6749  * │       │   └── fl2
6750  * │       ├── do1
6751  * │       │   ├── fl3
6752  * │       │   ├── fo2
6753  * │       │   └── fu3
6754  * │       ├── du1
6755  * │       │   └── fu2
6756  * │       ├── fl1
6757  * │       ├── fo1
6758  * │       ├── fu1
6759  * │       └── pl1 [FIFO]
6760  * └── upper
6761  *     ├── data
6762  *     │   ├── do1
6763  *     │   │   ├── fo2
6764  *     │   │   └── fu3
6765  *     │   ├── du1
6766  *     │   │   └── fu2
6767  *     │   ├── fo1
6768  *     │   └── fu1
6769  *     └── work
6770  *         └── work
6771  */
6772 
6773 FIXTURE(layout2_overlay)
6774 {
6775 	bool skip_test;
6776 };
6777 
6778 FIXTURE_SETUP(layout2_overlay)
6779 {
6780 	if (!supports_filesystem("overlay")) {
6781 		self->skip_test = true;
6782 		SKIP(return, "overlayfs is not supported (setup)");
6783 	}
6784 
6785 	prepare_layout(_metadata);
6786 
6787 	create_directory(_metadata, LOWER_BASE);
6788 	set_cap(_metadata, CAP_SYS_ADMIN);
6789 	/* Creates tmpfs mount points to get deterministic overlayfs. */
6790 	ASSERT_EQ(0, mount_opt(&mnt_tmp, LOWER_BASE));
6791 	clear_cap(_metadata, CAP_SYS_ADMIN);
6792 	create_file(_metadata, lower_fl1);
6793 	create_file(_metadata, lower_dl1_fl2);
6794 	create_file(_metadata, lower_fo1);
6795 	create_file(_metadata, lower_do1_fo2);
6796 	create_file(_metadata, lower_do1_fl3);
6797 	ASSERT_EQ(0, mknod(lower_pl1, S_IFIFO | 0600, 0));
6798 
6799 	create_directory(_metadata, UPPER_BASE);
6800 	set_cap(_metadata, CAP_SYS_ADMIN);
6801 	ASSERT_EQ(0, mount_opt(&mnt_tmp, UPPER_BASE));
6802 	clear_cap(_metadata, CAP_SYS_ADMIN);
6803 	create_file(_metadata, upper_fu1);
6804 	create_file(_metadata, upper_du1_fu2);
6805 	create_file(_metadata, upper_fo1);
6806 	create_file(_metadata, upper_do1_fo2);
6807 	create_file(_metadata, upper_do1_fu3);
6808 	ASSERT_EQ(0, mkdir(UPPER_WORK, 0700));
6809 
6810 	create_directory(_metadata, MERGE_DATA);
6811 	set_cap(_metadata, CAP_SYS_ADMIN);
6812 	set_cap(_metadata, CAP_DAC_OVERRIDE);
6813 	ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0,
6814 			   "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA
6815 			   ",workdir=" UPPER_WORK));
6816 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
6817 	clear_cap(_metadata, CAP_SYS_ADMIN);
6818 }
6819 
6820 FIXTURE_TEARDOWN_PARENT(layout2_overlay)
6821 {
6822 	if (self->skip_test)
6823 		SKIP(return, "overlayfs is not supported (teardown)");
6824 
6825 	EXPECT_EQ(0, remove_path(lower_do1_fl3));
6826 	EXPECT_EQ(0, remove_path(lower_dl1_fl2));
6827 	EXPECT_EQ(0, remove_path(lower_fl1));
6828 	EXPECT_EQ(0, remove_path(lower_do1_fo2));
6829 	EXPECT_EQ(0, remove_path(lower_fo1));
6830 	EXPECT_EQ(0, remove_path(lower_pl1));
6831 
6832 	/* umount(LOWER_BASE)) is handled by namespace lifetime. */
6833 	EXPECT_EQ(0, remove_path(LOWER_BASE));
6834 
6835 	EXPECT_EQ(0, remove_path(upper_do1_fu3));
6836 	EXPECT_EQ(0, remove_path(upper_du1_fu2));
6837 	EXPECT_EQ(0, remove_path(upper_fu1));
6838 	EXPECT_EQ(0, remove_path(upper_do1_fo2));
6839 	EXPECT_EQ(0, remove_path(upper_fo1));
6840 	EXPECT_EQ(0, remove_path(UPPER_WORK "/work"));
6841 
6842 	/* umount(UPPER_BASE)) is handled by namespace lifetime. */
6843 	EXPECT_EQ(0, remove_path(UPPER_BASE));
6844 
6845 	/* umount(MERGE_DATA)) is handled by namespace lifetime. */
6846 	EXPECT_EQ(0, remove_path(MERGE_DATA));
6847 
6848 	cleanup_layout(_metadata);
6849 }
6850 
6851 TEST_F_FORK(layout2_overlay, no_restriction)
6852 {
6853 	if (self->skip_test)
6854 		SKIP(return, "overlayfs is not supported (test)");
6855 
6856 	ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
6857 	ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
6858 	ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
6859 	ASSERT_EQ(0, test_open(lower_fo1, O_RDONLY));
6860 	ASSERT_EQ(0, test_open(lower_do1, O_RDONLY));
6861 	ASSERT_EQ(0, test_open(lower_do1_fo2, O_RDONLY));
6862 	ASSERT_EQ(0, test_open(lower_do1_fl3, O_RDONLY));
6863 
6864 	ASSERT_EQ(0, test_open(upper_fu1, O_RDONLY));
6865 	ASSERT_EQ(0, test_open(upper_du1, O_RDONLY));
6866 	ASSERT_EQ(0, test_open(upper_du1_fu2, O_RDONLY));
6867 	ASSERT_EQ(0, test_open(upper_fo1, O_RDONLY));
6868 	ASSERT_EQ(0, test_open(upper_do1, O_RDONLY));
6869 	ASSERT_EQ(0, test_open(upper_do1_fo2, O_RDONLY));
6870 	ASSERT_EQ(0, test_open(upper_do1_fu3, O_RDONLY));
6871 
6872 	ASSERT_EQ(0, test_open(merge_fl1, O_RDONLY));
6873 	ASSERT_EQ(0, test_open(merge_dl1, O_RDONLY));
6874 	ASSERT_EQ(0, test_open(merge_dl1_fl2, O_RDONLY));
6875 	ASSERT_EQ(0, test_open(merge_fu1, O_RDONLY));
6876 	ASSERT_EQ(0, test_open(merge_du1, O_RDONLY));
6877 	ASSERT_EQ(0, test_open(merge_du1_fu2, O_RDONLY));
6878 	ASSERT_EQ(0, test_open(merge_fo1, O_RDONLY));
6879 	ASSERT_EQ(0, test_open(merge_do1, O_RDONLY));
6880 	ASSERT_EQ(0, test_open(merge_do1_fo2, O_RDONLY));
6881 	ASSERT_EQ(0, test_open(merge_do1_fl3, O_RDONLY));
6882 	ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY));
6883 }
6884 
6885 #define for_each_path(path_list, path_entry, i)               \
6886 	for (i = 0, path_entry = *path_list[i]; path_list[i]; \
6887 	     path_entry = *path_list[++i])
6888 
6889 TEST_F_FORK(layout2_overlay, same_content_different_file)
6890 {
6891 	/* Sets access right on parent directories of both layers. */
6892 	const struct rule layer1_base[] = {
6893 		{
6894 			.path = LOWER_BASE,
6895 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6896 		},
6897 		{
6898 			.path = UPPER_BASE,
6899 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6900 		},
6901 		{
6902 			.path = MERGE_BASE,
6903 			.access = ACCESS_RW,
6904 		},
6905 		{},
6906 	};
6907 	const struct rule layer2_data[] = {
6908 		{
6909 			.path = LOWER_DATA,
6910 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6911 		},
6912 		{
6913 			.path = UPPER_DATA,
6914 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6915 		},
6916 		{
6917 			.path = MERGE_DATA,
6918 			.access = ACCESS_RW,
6919 		},
6920 		{},
6921 	};
6922 	/* Sets access right on directories inside both layers. */
6923 	const struct rule layer3_subdirs[] = {
6924 		{
6925 			.path = lower_dl1,
6926 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6927 		},
6928 		{
6929 			.path = lower_do1,
6930 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6931 		},
6932 		{
6933 			.path = upper_du1,
6934 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6935 		},
6936 		{
6937 			.path = upper_do1,
6938 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6939 		},
6940 		{
6941 			.path = merge_dl1,
6942 			.access = ACCESS_RW,
6943 		},
6944 		{
6945 			.path = merge_du1,
6946 			.access = ACCESS_RW,
6947 		},
6948 		{
6949 			.path = merge_do1,
6950 			.access = ACCESS_RW,
6951 		},
6952 		{},
6953 	};
6954 	/* Tighten access rights to the files. */
6955 	const struct rule layer4_files[] = {
6956 		{
6957 			.path = lower_dl1_fl2,
6958 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6959 		},
6960 		{
6961 			.path = lower_do1_fo2,
6962 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6963 		},
6964 		{
6965 			.path = lower_do1_fl3,
6966 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6967 		},
6968 		{
6969 			.path = upper_du1_fu2,
6970 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6971 		},
6972 		{
6973 			.path = upper_do1_fo2,
6974 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6975 		},
6976 		{
6977 			.path = upper_do1_fu3,
6978 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
6979 		},
6980 		{
6981 			.path = merge_dl1_fl2,
6982 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6983 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6984 		},
6985 		{
6986 			.path = merge_du1_fu2,
6987 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6988 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6989 		},
6990 		{
6991 			.path = merge_do1_fo2,
6992 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6993 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6994 		},
6995 		{
6996 			.path = merge_do1_fl3,
6997 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
6998 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
6999 		},
7000 		{
7001 			.path = merge_do1_fu3,
7002 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
7003 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
7004 		},
7005 		{},
7006 	};
7007 	const struct rule layer5_merge_only[] = {
7008 		{
7009 			.path = MERGE_DATA,
7010 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
7011 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
7012 		},
7013 		{},
7014 	};
7015 	size_t i;
7016 	const char *path_entry;
7017 
7018 	if (self->skip_test)
7019 		SKIP(return, "overlayfs is not supported (test)");
7020 
7021 	/* Sets rules on base directories (i.e. outside overlay scope). */
7022 	enforce_fs(_metadata, ACCESS_RW, layer1_base);
7023 
7024 	/* Checks lower layer. */
7025 	for_each_path(lower_base_files, path_entry, i) {
7026 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7027 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7028 	}
7029 	for_each_path(lower_base_directories, path_entry, i) {
7030 		ASSERT_EQ(EACCES,
7031 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7032 	}
7033 	for_each_path(lower_sub_files, path_entry, i) {
7034 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7035 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7036 	}
7037 	/* Checks upper layer. */
7038 	for_each_path(upper_base_files, path_entry, i) {
7039 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7040 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7041 	}
7042 	for_each_path(upper_base_directories, path_entry, i) {
7043 		ASSERT_EQ(EACCES,
7044 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7045 	}
7046 	for_each_path(upper_sub_files, path_entry, i) {
7047 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7048 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7049 	}
7050 	/*
7051 	 * Checks that access rights are independent from the lower and upper
7052 	 * layers: write access to upper files viewed through the merge point
7053 	 * is still allowed, and write access to lower file viewed (and copied)
7054 	 * through the merge point is still allowed.
7055 	 */
7056 	for_each_path(merge_base_files, path_entry, i) {
7057 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7058 	}
7059 	for_each_path(merge_base_directories, path_entry, i) {
7060 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7061 	}
7062 	for_each_path(merge_sub_files, path_entry, i) {
7063 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7064 	}
7065 
7066 	/* Sets rules on data directories (i.e. inside overlay scope). */
7067 	enforce_fs(_metadata, ACCESS_RW, layer2_data);
7068 
7069 	/* Checks merge. */
7070 	for_each_path(merge_base_files, path_entry, i) {
7071 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7072 	}
7073 	for_each_path(merge_base_directories, path_entry, i) {
7074 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7075 	}
7076 	for_each_path(merge_sub_files, path_entry, i) {
7077 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7078 	}
7079 
7080 	/* Same checks with tighter rules. */
7081 	enforce_fs(_metadata, ACCESS_RW, layer3_subdirs);
7082 
7083 	/* Checks changes for lower layer. */
7084 	for_each_path(lower_base_files, path_entry, i) {
7085 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7086 	}
7087 	/* Checks changes for upper layer. */
7088 	for_each_path(upper_base_files, path_entry, i) {
7089 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7090 	}
7091 	/* Checks all merge accesses. */
7092 	for_each_path(merge_base_files, path_entry, i) {
7093 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7094 	}
7095 	for_each_path(merge_base_directories, path_entry, i) {
7096 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
7097 	}
7098 	for_each_path(merge_sub_files, path_entry, i) {
7099 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7100 	}
7101 
7102 	/* Sets rules directly on overlayed files. */
7103 	enforce_fs(_metadata, ACCESS_RW, layer4_files);
7104 
7105 	/* Checks unchanged accesses on lower layer. */
7106 	for_each_path(lower_sub_files, path_entry, i) {
7107 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7108 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7109 	}
7110 	/* Checks unchanged accesses on upper layer. */
7111 	for_each_path(upper_sub_files, path_entry, i) {
7112 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
7113 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
7114 	}
7115 	/* Checks all merge accesses. */
7116 	for_each_path(merge_base_files, path_entry, i) {
7117 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7118 	}
7119 	for_each_path(merge_base_directories, path_entry, i) {
7120 		ASSERT_EQ(EACCES,
7121 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7122 	}
7123 	for_each_path(merge_sub_files, path_entry, i) {
7124 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7125 	}
7126 
7127 	/* Only allows access to the merge hierarchy. */
7128 	enforce_fs(_metadata, ACCESS_RW, layer5_merge_only);
7129 
7130 	/* Checks new accesses on lower layer. */
7131 	for_each_path(lower_sub_files, path_entry, i) {
7132 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7133 	}
7134 	/* Checks new accesses on upper layer. */
7135 	for_each_path(upper_sub_files, path_entry, i) {
7136 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
7137 	}
7138 	/* Checks all merge accesses. */
7139 	for_each_path(merge_base_files, path_entry, i) {
7140 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
7141 	}
7142 	for_each_path(merge_base_directories, path_entry, i) {
7143 		ASSERT_EQ(EACCES,
7144 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
7145 	}
7146 	for_each_path(merge_sub_files, path_entry, i) {
7147 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
7148 	}
7149 }
7150 
7151 TEST_F_FORK(layout2_overlay, rename_in_overlay_without_make_reg)
7152 {
7153 	const char *const merge_pl1_renamed = MERGE_DATA "/pl1_renamed";
7154 
7155 	if (self->skip_test)
7156 		SKIP(return, "overlayfs is not supported (test)");
7157 
7158 	/*
7159 	 * merge_pl1 is a FIFO which only exists in the lower layer.  Before
7160 	 * the rename, the upper layer has no entry under this name.
7161 	 */
7162 	ASSERT_TRUE(is_fifo(merge_pl1));
7163 	ASSERT_TRUE(is_missing(UPPER_DATA "/pl1"));
7164 
7165 	/* MAKE_REG is restricted, but MAKE_FIFO is not. */
7166 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, NULL);
7167 
7168 	/*
7169 	 * Rename the FIFO through OverlayFS.  merge_pl1 originates from the
7170 	 * lower layer, so this triggers a copy-up and creates the whiteout in
7171 	 * the upper layer to hide the lower layer FIFO file.  Even though
7172 	 * MAKE_REG is restricted, the rename on the OverlayFS works.
7173 	 */
7174 	EXPECT_EQ(0, rename(merge_pl1, merge_pl1_renamed));
7175 
7176 	/* Check that the rename worked. */
7177 	EXPECT_TRUE(is_fifo(merge_pl1_renamed));
7178 	EXPECT_TRUE(is_missing(merge_pl1));
7179 
7180 	/*
7181 	 * Check that the whiteout object was created on the underlying "upper"
7182 	 * filesystem during the rename.  This is OK because the whiteout object
7183 	 * was created by OverlayFS, not by the calling task.
7184 	 */
7185 	EXPECT_TRUE(is_whiteout(UPPER_DATA "/pl1"));
7186 }
7187 
7188 FIXTURE(layout3_fs)
7189 {
7190 	bool has_created_dir;
7191 	bool has_created_file;
7192 	bool skip_test;
7193 };
7194 
7195 FIXTURE_VARIANT(layout3_fs)
7196 {
7197 	const struct mnt_opt mnt;
7198 	const char *const file_path;
7199 	unsigned int cwd_fs_magic;
7200 };
7201 
7202 /* clang-format off */
7203 FIXTURE_VARIANT_ADD(layout3_fs, tmpfs) {
7204 	/* clang-format on */
7205 	.mnt = {
7206 		.type = "tmpfs",
7207 		.data = MNT_TMP_DATA,
7208 	},
7209 	.file_path = file1_s1d1,
7210 };
7211 
7212 FIXTURE_VARIANT_ADD(layout3_fs, ramfs) {
7213 	.mnt = {
7214 		.type = "ramfs",
7215 		.data = "mode=700",
7216 	},
7217 	.file_path = TMP_DIR "/dir/file",
7218 };
7219 
7220 FIXTURE_VARIANT_ADD(layout3_fs, cgroup2) {
7221 	.mnt = {
7222 		.type = "cgroup2",
7223 	},
7224 	.file_path = TMP_DIR "/test/cgroup.procs",
7225 };
7226 
7227 FIXTURE_VARIANT_ADD(layout3_fs, proc) {
7228 	.mnt = {
7229 		.type = "proc",
7230 	},
7231 	.file_path = TMP_DIR "/self/status",
7232 };
7233 
7234 FIXTURE_VARIANT_ADD(layout3_fs, sysfs) {
7235 	.mnt = {
7236 		.type = "sysfs",
7237 	},
7238 	.file_path = TMP_DIR "/kernel/notes",
7239 };
7240 
7241 FIXTURE_VARIANT_ADD(layout3_fs, hostfs) {
7242 	.mnt = {
7243 		.source = TMP_DIR,
7244 		.flags = MS_BIND,
7245 	},
7246 	.file_path = TMP_DIR "/dir/file",
7247 	.cwd_fs_magic = HOSTFS_SUPER_MAGIC,
7248 };
7249 
7250 static char *dirname_alloc(const char *path)
7251 {
7252 	char *dup;
7253 
7254 	if (!path)
7255 		return NULL;
7256 
7257 	dup = strdup(path);
7258 	if (!dup)
7259 		return NULL;
7260 
7261 	return dirname(dup);
7262 }
7263 
7264 FIXTURE_SETUP(layout3_fs)
7265 {
7266 	struct stat statbuf;
7267 	char *dir_path = dirname_alloc(variant->file_path);
7268 
7269 	if (!supports_filesystem(variant->mnt.type) ||
7270 	    !cwd_matches_fs(variant->cwd_fs_magic)) {
7271 		self->skip_test = true;
7272 		SKIP(return, "this filesystem is not supported (setup)");
7273 	}
7274 
7275 	prepare_layout_opt(_metadata, &variant->mnt);
7276 
7277 	/* Creates directory when required. */
7278 	if (stat(dir_path, &statbuf)) {
7279 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7280 		EXPECT_EQ(0, mkdir(dir_path, 0700))
7281 		{
7282 			TH_LOG("Failed to create directory \"%s\": %s",
7283 			       dir_path, strerror(errno));
7284 		}
7285 		self->has_created_dir = true;
7286 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7287 	}
7288 
7289 	/* Creates file when required. */
7290 	if (stat(variant->file_path, &statbuf)) {
7291 		int fd;
7292 
7293 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7294 		fd = creat(variant->file_path, 0600);
7295 		EXPECT_LE(0, fd)
7296 		{
7297 			TH_LOG("Failed to create file \"%s\": %s",
7298 			       variant->file_path, strerror(errno));
7299 		}
7300 		EXPECT_EQ(0, close(fd));
7301 		self->has_created_file = true;
7302 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7303 	}
7304 
7305 	free(dir_path);
7306 }
7307 
7308 FIXTURE_TEARDOWN_PARENT(layout3_fs)
7309 {
7310 	if (self->skip_test)
7311 		SKIP(return, "this filesystem is not supported (teardown)");
7312 
7313 	if (self->has_created_file) {
7314 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7315 		/*
7316 		 * Don't check for error because the file might already
7317 		 * have been removed (cf. release_inode test).
7318 		 */
7319 		unlink(variant->file_path);
7320 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7321 	}
7322 
7323 	if (self->has_created_dir) {
7324 		char *dir_path = dirname_alloc(variant->file_path);
7325 
7326 		set_cap(_metadata, CAP_DAC_OVERRIDE);
7327 		/*
7328 		 * Don't check for error because the directory might already
7329 		 * have been removed (cf. release_inode test).
7330 		 */
7331 		rmdir(dir_path);
7332 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
7333 		free(dir_path);
7334 	}
7335 
7336 	cleanup_layout(_metadata);
7337 }
7338 
7339 static void layer3_fs_tag_inode(struct __test_metadata *const _metadata,
7340 				FIXTURE_DATA(layout3_fs) * self,
7341 				const FIXTURE_VARIANT(layout3_fs) * variant,
7342 				const char *const rule_path)
7343 {
7344 	const struct rule layer1_allow_read_file[] = {
7345 		{
7346 			.path = rule_path,
7347 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
7348 		},
7349 		{},
7350 	};
7351 	const char *const dev_null_path = "/dev/null";
7352 
7353 	if (self->skip_test)
7354 		SKIP(return, "this filesystem is not supported (test)");
7355 
7356 	/* Checks without Landlock. */
7357 	EXPECT_EQ(0, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7358 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7359 
7360 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
7361 		   layer1_allow_read_file);
7362 
7363 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7364 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7365 
7366 	/* Forbids directory reading. */
7367 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, NULL);
7368 
7369 	/* Checks with Landlock and forbidden access. */
7370 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
7371 	EXPECT_EQ(EACCES, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
7372 }
7373 
7374 /* Matrix of tests to check file hierarchy evaluation. */
7375 
7376 TEST_F_FORK(layout3_fs, tag_inode_dir_parent)
7377 {
7378 	/* The current directory must not be the root for this test. */
7379 	layer3_fs_tag_inode(_metadata, self, variant, ".");
7380 }
7381 
7382 TEST_F_FORK(layout3_fs, tag_inode_dir_mnt)
7383 {
7384 	layer3_fs_tag_inode(_metadata, self, variant, TMP_DIR);
7385 }
7386 
7387 TEST_F_FORK(layout3_fs, tag_inode_dir_child)
7388 {
7389 	char *dir_path = dirname_alloc(variant->file_path);
7390 
7391 	layer3_fs_tag_inode(_metadata, self, variant, dir_path);
7392 	free(dir_path);
7393 }
7394 
7395 TEST_F_FORK(layout3_fs, tag_inode_file)
7396 {
7397 	layer3_fs_tag_inode(_metadata, self, variant, variant->file_path);
7398 }
7399 
7400 /* Light version of layout1.release_inodes */
7401 TEST_F_FORK(layout3_fs, release_inodes)
7402 {
7403 	const struct rule layer1[] = {
7404 		{
7405 			.path = TMP_DIR,
7406 			.access = LANDLOCK_ACCESS_FS_READ_DIR,
7407 		},
7408 		{},
7409 	};
7410 	int ruleset_fd;
7411 
7412 	if (self->skip_test)
7413 		SKIP(return, "this filesystem is not supported (test)");
7414 
7415 	/* Clean up for the teardown to not fail. */
7416 	if (self->has_created_file)
7417 		EXPECT_EQ(0, remove_path(variant->file_path));
7418 
7419 	if (self->has_created_dir) {
7420 		char *dir_path = dirname_alloc(variant->file_path);
7421 
7422 		/* Don't check for error because of cgroup specificities. */
7423 		remove_path(dir_path);
7424 		free(dir_path);
7425 	}
7426 
7427 	ruleset_fd =
7428 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
7429 
7430 	/* Unmount the filesystem while it is being used by a ruleset. */
7431 	set_cap(_metadata, CAP_SYS_ADMIN);
7432 	ASSERT_EQ(0, umount(TMP_DIR));
7433 	clear_cap(_metadata, CAP_SYS_ADMIN);
7434 
7435 	/* Replaces with a new mount point to simplify FIXTURE_TEARDOWN. */
7436 	set_cap(_metadata, CAP_SYS_ADMIN);
7437 	ASSERT_EQ(0, mount_opt(&mnt_tmp, TMP_DIR));
7438 	clear_cap(_metadata, CAP_SYS_ADMIN);
7439 
7440 	enforce_ruleset(_metadata, ruleset_fd);
7441 	ASSERT_EQ(0, close(ruleset_fd));
7442 
7443 	/* Checks that access to the new mount point is denied. */
7444 	ASSERT_EQ(EACCES, test_open(TMP_DIR, O_RDONLY));
7445 }
7446 
7447 static int matches_log_fs_extra(struct __test_metadata *const _metadata,
7448 				int audit_fd, const char *const blockers,
7449 				const char *const path, const char *const extra)
7450 {
7451 	static const char log_template[] = REGEX_LANDLOCK_PREFIX
7452 		" blockers=fs\\.%s path=\"%s\" dev=\"[^\"]\\+\" ino=[0-9]\\+$";
7453 	char *absolute_path = NULL;
7454 	size_t log_match_remaining = sizeof(log_template) + strlen(blockers) +
7455 				     PATH_MAX * 2 +
7456 				     (extra ? strlen(extra) : 0) + 1;
7457 	char log_match[log_match_remaining];
7458 	char *log_match_cursor = log_match;
7459 	size_t chunk_len;
7460 
7461 	chunk_len = snprintf(log_match_cursor, log_match_remaining,
7462 			     REGEX_LANDLOCK_PREFIX " blockers=%s path=\"",
7463 			     blockers);
7464 	if (chunk_len < 0 || chunk_len >= log_match_remaining)
7465 		return -E2BIG;
7466 
7467 	/*
7468 	 * It is assumed that absolute_path does not contain control
7469 	 * characters nor spaces, see audit_string_contains_control().
7470 	 */
7471 	absolute_path = realpath(path, NULL);
7472 	if (!absolute_path)
7473 		return -errno;
7474 
7475 	log_match_remaining -= chunk_len;
7476 	log_match_cursor += chunk_len;
7477 	log_match_cursor = regex_escape(absolute_path, log_match_cursor,
7478 					log_match_remaining);
7479 	free(absolute_path);
7480 	if (log_match_cursor < 0)
7481 		return (long long)log_match_cursor;
7482 
7483 	log_match_remaining -= log_match_cursor - log_match;
7484 	chunk_len = snprintf(log_match_cursor, log_match_remaining,
7485 			     "\" dev=\"[^\"]\\+\" ino=[0-9]\\+%s$",
7486 			     extra ?: "");
7487 	if (chunk_len < 0 || chunk_len >= log_match_remaining)
7488 		return -E2BIG;
7489 
7490 	return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
7491 				  NULL);
7492 }
7493 
7494 static int matches_log_fs(struct __test_metadata *const _metadata, int audit_fd,
7495 			  const char *const blockers, const char *const path)
7496 {
7497 	return matches_log_fs_extra(_metadata, audit_fd, blockers, path, NULL);
7498 }
7499 
7500 FIXTURE(audit_layout1)
7501 {
7502 	struct audit_filter audit_filter;
7503 	int audit_fd;
7504 };
7505 
7506 FIXTURE_SETUP(audit_layout1)
7507 {
7508 	prepare_layout(_metadata);
7509 
7510 	create_layout1(_metadata);
7511 
7512 	set_cap(_metadata, CAP_AUDIT_CONTROL);
7513 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
7514 	EXPECT_LE(0, self->audit_fd);
7515 	disable_caps(_metadata);
7516 }
7517 
7518 FIXTURE_TEARDOWN_PARENT(audit_layout1)
7519 {
7520 	remove_layout1(_metadata);
7521 
7522 	cleanup_layout(_metadata);
7523 
7524 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
7525 }
7526 
7527 TEST_F(audit_layout1, execute_make)
7528 {
7529 	struct audit_records records;
7530 
7531 	copy_file(_metadata, bin_true, file1_s1d1);
7532 	test_execute(_metadata, 0, file1_s1d1);
7533 	test_check_exec(_metadata, 0, file1_s1d1);
7534 
7535 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, NULL);
7536 
7537 	test_execute(_metadata, EACCES, file1_s1d1);
7538 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.execute",
7539 				    file1_s1d1));
7540 	test_check_exec(_metadata, EACCES, file1_s1d1);
7541 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.execute",
7542 				    file1_s1d1));
7543 
7544 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7545 	EXPECT_EQ(0, records.access);
7546 	EXPECT_EQ(0, records.domain);
7547 }
7548 
7549 /*
7550  * Using a set of handled/denied access rights make it possible to check that
7551  * only the blocked ones are logged.
7552  */
7553 
7554 TEST_F(audit_layout1, execute_read)
7555 {
7556 	struct audit_records records;
7557 
7558 	copy_file(_metadata, bin_true, file1_s1d1);
7559 	test_execute(_metadata, 0, file1_s1d1);
7560 	test_check_exec(_metadata, 0, file1_s1d1);
7561 
7562 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7563 
7564 	/*
7565 	 * The only difference with the previous audit_layout1.execute_read test is
7566 	 * the extra ",fs\\.read_file" blocked by the executable file.
7567 	 */
7568 	test_execute(_metadata, EACCES, file1_s1d1);
7569 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7570 				    "fs\\.execute,fs\\.read_file", file1_s1d1));
7571 	test_check_exec(_metadata, EACCES, file1_s1d1);
7572 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7573 				    "fs\\.execute,fs\\.read_file", file1_s1d1));
7574 
7575 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7576 	EXPECT_EQ(0, records.access);
7577 	EXPECT_EQ(0, records.domain);
7578 }
7579 
7580 TEST_F(audit_layout1, write_file)
7581 {
7582 	struct audit_records records;
7583 
7584 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7585 
7586 	EXPECT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
7587 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7588 				    "fs\\.write_file", file1_s1d1));
7589 
7590 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7591 	EXPECT_EQ(0, records.access);
7592 	EXPECT_EQ(1, records.domain);
7593 }
7594 
7595 TEST_F(audit_layout1, read_file)
7596 {
7597 	struct audit_records records;
7598 
7599 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7600 
7601 	EXPECT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
7602 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.read_file",
7603 				    file1_s1d1));
7604 
7605 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7606 	EXPECT_EQ(0, records.access);
7607 	EXPECT_EQ(1, records.domain);
7608 }
7609 
7610 TEST_F(audit_layout1, read_dir)
7611 {
7612 	struct audit_records records;
7613 
7614 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7615 
7616 	EXPECT_EQ(EACCES, test_open(dir_s1d1, O_DIRECTORY));
7617 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.read_dir",
7618 				    dir_s1d1));
7619 
7620 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7621 	EXPECT_EQ(0, records.access);
7622 	EXPECT_EQ(1, records.domain);
7623 }
7624 
7625 TEST_F(audit_layout1, remove_dir)
7626 {
7627 	struct audit_records records;
7628 
7629 	EXPECT_EQ(0, unlink(file1_s1d3));
7630 	EXPECT_EQ(0, unlink(file2_s1d3));
7631 
7632 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7633 
7634 	EXPECT_EQ(-1, rmdir(dir_s1d3));
7635 	EXPECT_EQ(EACCES, errno);
7636 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7637 				    "fs\\.remove_dir", dir_s1d2));
7638 
7639 	EXPECT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
7640 	EXPECT_EQ(EACCES, errno);
7641 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7642 				    "fs\\.remove_dir", dir_s1d2));
7643 
7644 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7645 	EXPECT_EQ(0, records.access);
7646 	EXPECT_EQ(0, records.domain);
7647 }
7648 
7649 TEST_F(audit_layout1, remove_file)
7650 {
7651 	struct audit_records records;
7652 
7653 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7654 
7655 	EXPECT_EQ(-1, unlink(file1_s1d3));
7656 	EXPECT_EQ(EACCES, errno);
7657 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7658 				    "fs\\.remove_file", dir_s1d3));
7659 
7660 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7661 	EXPECT_EQ(0, records.access);
7662 	EXPECT_EQ(1, records.domain);
7663 }
7664 
7665 TEST_F(audit_layout1, make_char)
7666 {
7667 	struct audit_records records;
7668 
7669 	EXPECT_EQ(0, unlink(file1_s1d3));
7670 
7671 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7672 
7673 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFCHR | 0644, makedev(7, 0)));
7674 	EXPECT_EQ(EACCES, errno);
7675 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_char",
7676 				    dir_s1d3));
7677 
7678 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7679 	EXPECT_EQ(0, records.access);
7680 	EXPECT_EQ(1, records.domain);
7681 }
7682 
7683 TEST_F(audit_layout1, make_whiteout)
7684 {
7685 	struct audit_records records;
7686 
7687 	EXPECT_EQ(0, unlink(file1_s1d3));
7688 
7689 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7690 
7691 	/* Whiteout creation is denied and logged as fs.make_reg. */
7692 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFCHR | 0644, makedev(0, 0)));
7693 	EXPECT_EQ(EACCES, errno);
7694 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_reg",
7695 				    dir_s1d3));
7696 
7697 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7698 	EXPECT_EQ(0, records.access);
7699 	EXPECT_EQ(1, records.domain);
7700 }
7701 
7702 TEST_F(audit_layout1, make_dir)
7703 {
7704 	struct audit_records records;
7705 
7706 	EXPECT_EQ(0, unlink(file1_s1d3));
7707 
7708 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7709 
7710 	EXPECT_EQ(-1, mkdir(file1_s1d3, 0755));
7711 	EXPECT_EQ(EACCES, errno);
7712 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_dir",
7713 				    dir_s1d3));
7714 
7715 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7716 	EXPECT_EQ(0, records.access);
7717 	EXPECT_EQ(1, records.domain);
7718 }
7719 
7720 TEST_F(audit_layout1, make_reg)
7721 {
7722 	struct audit_records records;
7723 
7724 	EXPECT_EQ(0, unlink(file1_s1d3));
7725 
7726 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7727 
7728 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFREG | 0644, 0));
7729 	EXPECT_EQ(EACCES, errno);
7730 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_reg",
7731 				    dir_s1d3));
7732 
7733 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7734 	EXPECT_EQ(0, records.access);
7735 	EXPECT_EQ(1, records.domain);
7736 }
7737 
7738 TEST_F(audit_layout1, make_sock)
7739 {
7740 	struct audit_records records;
7741 
7742 	EXPECT_EQ(0, unlink(file1_s1d3));
7743 
7744 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7745 
7746 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFSOCK | 0644, 0));
7747 	EXPECT_EQ(EACCES, errno);
7748 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_sock",
7749 				    dir_s1d3));
7750 
7751 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7752 	EXPECT_EQ(0, records.access);
7753 	EXPECT_EQ(1, records.domain);
7754 }
7755 
7756 TEST_F(audit_layout1, make_fifo)
7757 {
7758 	struct audit_records records;
7759 
7760 	EXPECT_EQ(0, unlink(file1_s1d3));
7761 
7762 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7763 
7764 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFIFO | 0644, 0));
7765 	EXPECT_EQ(EACCES, errno);
7766 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_fifo",
7767 				    dir_s1d3));
7768 
7769 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7770 	EXPECT_EQ(0, records.access);
7771 	EXPECT_EQ(1, records.domain);
7772 }
7773 
7774 TEST_F(audit_layout1, make_block)
7775 {
7776 	struct audit_records records;
7777 
7778 	EXPECT_EQ(0, unlink(file1_s1d3));
7779 
7780 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7781 
7782 	EXPECT_EQ(-1, mknod(file1_s1d3, S_IFBLK | 0644, 0));
7783 	EXPECT_EQ(EACCES, errno);
7784 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7785 				    "fs\\.make_block", dir_s1d3));
7786 
7787 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7788 	EXPECT_EQ(0, records.access);
7789 	EXPECT_EQ(1, records.domain);
7790 }
7791 
7792 TEST_F(audit_layout1, make_sym)
7793 {
7794 	struct audit_records records;
7795 
7796 	EXPECT_EQ(0, unlink(file1_s1d3));
7797 
7798 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7799 
7800 	EXPECT_EQ(-1, symlink("target", file1_s1d3));
7801 	EXPECT_EQ(EACCES, errno);
7802 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.make_sym",
7803 				    dir_s1d3));
7804 
7805 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7806 	EXPECT_EQ(0, records.access);
7807 	EXPECT_EQ(1, records.domain);
7808 }
7809 
7810 TEST_F(audit_layout1, refer_handled)
7811 {
7812 	struct audit_records records;
7813 
7814 	EXPECT_EQ(0, unlink(file1_s1d3));
7815 
7816 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REFER, NULL);
7817 
7818 	EXPECT_EQ(-1, link(file1_s1d1, file1_s1d3));
7819 	EXPECT_EQ(EXDEV, errno);
7820 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7821 				    dir_s1d1));
7822 	EXPECT_EQ(0,
7823 		  matches_log_domain_allocated(self->audit_fd, getpid(), NULL));
7824 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7825 				    dir_s1d3));
7826 
7827 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7828 	EXPECT_EQ(0, records.access);
7829 	EXPECT_EQ(0, records.domain);
7830 }
7831 
7832 TEST_F(audit_layout1, refer_make)
7833 {
7834 	struct audit_records records;
7835 
7836 	EXPECT_EQ(0, unlink(file1_s1d3));
7837 
7838 	enforce_fs(_metadata,
7839 		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
7840 		   NULL);
7841 
7842 	EXPECT_EQ(-1, link(file1_s1d1, file1_s1d3));
7843 	EXPECT_EQ(EACCES, errno);
7844 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7845 				    dir_s1d1));
7846 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7847 				    "fs\\.make_reg,fs\\.refer", dir_s1d3));
7848 
7849 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7850 	EXPECT_EQ(0, records.access);
7851 	EXPECT_EQ(0, records.domain);
7852 }
7853 
7854 TEST_F(audit_layout1, refer_rename)
7855 {
7856 	struct audit_records records;
7857 
7858 	EXPECT_EQ(0, unlink(file1_s1d3));
7859 
7860 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7861 
7862 	EXPECT_EQ(EACCES, test_rename(file1_s1d2, file1_s2d3));
7863 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7864 				    "fs\\.remove_file,fs\\.refer", dir_s1d2));
7865 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7866 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7867 				    dir_s2d3));
7868 
7869 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7870 	EXPECT_EQ(0, records.access);
7871 	EXPECT_EQ(0, records.domain);
7872 }
7873 
7874 TEST_F(audit_layout1, refer_exchange)
7875 {
7876 	struct audit_records records;
7877 
7878 	EXPECT_EQ(0, unlink(file1_s1d3));
7879 
7880 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7881 
7882 	/*
7883 	 * The only difference with the previous audit_layout1.refer_rename test is
7884 	 * the extra ",fs\\.make_reg" blocked by the source directory.
7885 	 */
7886 	EXPECT_EQ(EACCES, test_exchange(file1_s1d2, file1_s2d3));
7887 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7888 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7889 				    dir_s1d2));
7890 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
7891 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
7892 				    dir_s2d3));
7893 
7894 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7895 	EXPECT_EQ(0, records.access);
7896 	EXPECT_EQ(0, records.domain);
7897 }
7898 
7899 /*
7900  * This test checks that the audit record is correctly generated when the
7901  * operation is only partially denied.  This is the case for rename(2) when the
7902  * source file is allowed to be referenced but the destination directory is not.
7903  *
7904  * This is also a regression test for commit d617f0d72d80 ("landlock: Optimize
7905  * file path walks and prepare for audit support") and commit 058518c20920
7906  * ("landlock: Align partial refer access checks with final ones").
7907  */
7908 TEST_F(audit_layout1, refer_rename_half)
7909 {
7910 	struct audit_records records;
7911 	const struct rule layer1[] = {
7912 		{
7913 			.path = dir_s2d2,
7914 			.access = LANDLOCK_ACCESS_FS_REFER,
7915 		},
7916 		{},
7917 	};
7918 
7919 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_REFER, layer1);
7920 
7921 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d3));
7922 	ASSERT_EQ(EXDEV, errno);
7923 
7924 	/* Only half of the request is denied. */
7925 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
7926 				    dir_s1d1));
7927 
7928 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7929 	EXPECT_EQ(0, records.access);
7930 	EXPECT_EQ(1, records.domain);
7931 }
7932 
7933 TEST_F(audit_layout1, truncate)
7934 {
7935 	struct audit_records records;
7936 
7937 	enforce_fs(_metadata, ACCESS_ALL, NULL);
7938 
7939 	EXPECT_EQ(-1, truncate(file1_s1d3, 0));
7940 	EXPECT_EQ(EACCES, errno);
7941 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.truncate",
7942 				    file1_s1d3));
7943 
7944 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7945 	EXPECT_EQ(0, records.access);
7946 	EXPECT_EQ(1, records.domain);
7947 }
7948 
7949 /* Checks that audit records preserve every ioctl command bit. */
7950 TEST_F(audit_layout1, ioctl_dev)
7951 {
7952 	struct audit_records records;
7953 	int fd;
7954 
7955 	enforce_fs(_metadata, ACCESS_ALL & ~LANDLOCK_ACCESS_FS_READ_FILE, NULL);
7956 
7957 	fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
7958 	ASSERT_LE(0, fd);
7959 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, unknown_ioctl_cmd));
7960 	EXPECT_EQ(0, matches_log_fs_extra(_metadata, self->audit_fd,
7961 					  "fs\\.ioctl_dev", "/dev/null",
7962 					  " ioctlcmd=0xc00ffeee"));
7963 
7964 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
7965 	EXPECT_EQ(0, records.access);
7966 	EXPECT_EQ(1, records.domain);
7967 }
7968 
7969 TEST_F(audit_layout1, resolve_unix)
7970 {
7971 	struct audit_records records;
7972 	const char *const path = "sock";
7973 	int srv_fd, cli_fd, status;
7974 	pid_t child_pid;
7975 
7976 	srv_fd = set_up_named_unix_server(_metadata, SOCK_STREAM, path);
7977 
7978 	child_pid = fork();
7979 	ASSERT_LE(0, child_pid);
7980 	if (!child_pid) {
7981 		enforce_fs(_metadata, ACCESS_ALL, NULL);
7982 
7983 		cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
7984 		ASSERT_LE(0, cli_fd);
7985 		EXPECT_EQ(EACCES,
7986 			  test_connect_named_unix(_metadata, cli_fd, path));
7987 
7988 		EXPECT_EQ(0, close(cli_fd));
7989 		_exit(_metadata->exit_code);
7990 	}
7991 
7992 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
7993 	EXPECT_EQ(1, WIFEXITED(status));
7994 	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
7995 
7996 	EXPECT_EQ(0, matches_log_fs_extra(_metadata, self->audit_fd,
7997 					  "fs\\.resolve_unix", path, NULL));
7998 
7999 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
8000 	EXPECT_EQ(0, records.access);
8001 	EXPECT_EQ(1, records.domain);
8002 
8003 	EXPECT_EQ(0, close(srv_fd));
8004 }
8005 
8006 TEST_F(audit_layout1, mount)
8007 {
8008 	struct audit_records records;
8009 
8010 	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, NULL);
8011 
8012 	set_cap(_metadata, CAP_SYS_ADMIN);
8013 	EXPECT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
8014 	EXPECT_EQ(EPERM, errno);
8015 	clear_cap(_metadata, CAP_SYS_ADMIN);
8016 	EXPECT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
8017 				    "fs\\.change_topology", dir_s3d2));
8018 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
8019 	EXPECT_EQ(0, records.access);
8020 	EXPECT_EQ(1, records.domain);
8021 }
8022 
8023 static bool debug_quiet_tests;
8024 
8025 FIXTURE(audit_quiet_layout1)
8026 {
8027 	struct audit_filter audit_filter;
8028 	int audit_fd;
8029 };
8030 
8031 FIXTURE_SETUP(audit_quiet_layout1)
8032 {
8033 	prepare_layout(_metadata);
8034 	create_layout1(_metadata);
8035 
8036 	set_cap(_metadata, CAP_AUDIT_CONTROL);
8037 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
8038 	EXPECT_LE(0, self->audit_fd);
8039 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
8040 
8041 	if (getenv("DEBUG_QUIET_TESTS"))
8042 		debug_quiet_tests = true;
8043 }
8044 
8045 FIXTURE_TEARDOWN_PARENT(audit_quiet_layout1)
8046 {
8047 	remove_layout1(_metadata);
8048 	cleanup_layout(_metadata);
8049 
8050 	set_cap(_metadata, CAP_AUDIT_CONTROL);
8051 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
8052 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
8053 }
8054 
8055 struct a_rule {
8056 	const char *path;
8057 	__u64 access;
8058 	bool quiet;
8059 };
8060 
8061 struct a_layer {
8062 	__u64 handled_access_fs;
8063 	__u64 quiet_access_fs;
8064 	struct a_rule rules[6];
8065 	__u64 restrict_flags;
8066 };
8067 
8068 struct a_target {
8069 	/* File/dir to try open. */
8070 	const char *target;
8071 	/* Open mode (one of O_RDONLY, O_WRONLY, or O_RDWR). */
8072 	int open_mode;
8073 	/* Should open succeed? */
8074 	bool expect_open_success;
8075 	/* If open fails, whether to expect an audit log for read. */
8076 	bool audit_read_blocked;
8077 	/* If open fails, whether to expect an audit log for write. */
8078 	bool audit_write_blocked;
8079 	/* If ftruncate() is expected to be allowed. */
8080 	bool expect_truncate_success;
8081 	/* If ftruncate fails, whether to expect an audit log. */
8082 	bool audit_truncate;
8083 	/*
8084 	 * If ioctl() is expected to be allowed (ioctl not attempted if neither
8085 	 * this nor expect_ioctl_denied is set).
8086 	 */
8087 	bool expect_ioctl_allowed;
8088 	/* If ioctl() is expected to be denied. */
8089 	bool expect_ioctl_denied;
8090 	/* If ioctl fails, whether to expect an audit log. */
8091 	bool audit_ioctl;
8092 };
8093 
8094 #define AUDIT_QUIET_MAX_TARGETS 10
8095 
8096 FIXTURE_VARIANT(audit_quiet_layout1)
8097 {
8098 	struct a_layer layers[3];
8099 	struct a_target targets[AUDIT_QUIET_MAX_TARGETS];
8100 };
8101 
8102 #define FS_R LANDLOCK_ACCESS_FS_READ_FILE
8103 #define FS_W LANDLOCK_ACCESS_FS_WRITE_FILE
8104 #define FS_TRUNC LANDLOCK_ACCESS_FS_TRUNCATE
8105 #define FS_IOCTL LANDLOCK_ACCESS_FS_IOCTL_DEV
8106 
8107 static int sprint_access_bits(char *buf, size_t buflen, __u64 access)
8108 {
8109 	size_t offset = 0;
8110 
8111 	if (buflen < strlen("rwti make_reg remove_file refer") + 1)
8112 		abort();
8113 
8114 	buf[0] = '\0';
8115 	if (access & FS_R)
8116 		offset += snprintf(buf + offset, buflen - offset, "r");
8117 	if (access & FS_W)
8118 		offset += snprintf(buf + offset, buflen - offset, "w");
8119 	if (access & FS_TRUNC)
8120 		offset += snprintf(buf + offset, buflen - offset, "t");
8121 	if (access & FS_IOCTL)
8122 		offset += snprintf(buf + offset, buflen - offset, "i");
8123 	if (access & LANDLOCK_ACCESS_FS_MAKE_REG)
8124 		offset += snprintf(buf + offset, buflen - offset, ",make_reg");
8125 	if (access & LANDLOCK_ACCESS_FS_REMOVE_FILE)
8126 		offset +=
8127 			snprintf(buf + offset, buflen - offset, ",remove_file");
8128 	if (access & LANDLOCK_ACCESS_FS_REFER)
8129 		offset += snprintf(buf + offset, buflen - offset, ",refer");
8130 
8131 	if (buf[0] == ',') {
8132 		offset--;
8133 		memmove(buf, buf + 1, offset);
8134 		buf[offset] = '\0';
8135 	}
8136 
8137 	return offset;
8138 }
8139 
8140 static int apply_a_layer(struct __test_metadata *const _metadata,
8141 			 const struct a_layer *l)
8142 {
8143 	struct landlock_ruleset_attr rs_attr = {
8144 		.handled_access_fs = l->handled_access_fs,
8145 		.quiet_access_fs = l->quiet_access_fs,
8146 	};
8147 	int rs_fd;
8148 	int i;
8149 	const struct a_rule *r;
8150 	char handled_access_s[33], quiet_access_s[33], rule_access_s[33];
8151 
8152 	if (!l->handled_access_fs)
8153 		return 0;
8154 
8155 	rs_fd = landlock_create_ruleset(&rs_attr, sizeof(rs_attr), 0);
8156 	ASSERT_LE(0, rs_fd);
8157 
8158 	for (i = 0; i < ARRAY_SIZE(l->rules); i++) {
8159 		r = &l->rules[i];
8160 		if (!r->path)
8161 			continue;
8162 
8163 		add_path_beneath(_metadata, rs_fd, r->access, r->path,
8164 				 r->quiet ? LANDLOCK_ADD_RULE_QUIET : 0);
8165 	}
8166 
8167 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
8168 	ASSERT_EQ(0, landlock_restrict_self(rs_fd, l->restrict_flags))
8169 	{
8170 		TH_LOG("Failed to enforce ruleset: %s", strerror(errno));
8171 	}
8172 	ASSERT_EQ(0, close(rs_fd));
8173 
8174 	if (debug_quiet_tests) {
8175 		sprint_access_bits(handled_access_s, sizeof(handled_access_s),
8176 				   l->handled_access_fs);
8177 		sprint_access_bits(quiet_access_s, sizeof(quiet_access_s),
8178 				   l->quiet_access_fs);
8179 		TH_LOG("applied layer: handled=%s quiet=%s restrict_flags=0x%llx",
8180 		       handled_access_s, quiet_access_s,
8181 		       (unsigned long long)l->restrict_flags);
8182 		for (i = 0; i < ARRAY_SIZE(l->rules); i++) {
8183 			r = &l->rules[i];
8184 			if (!r->path)
8185 				continue;
8186 
8187 			sprint_access_bits(rule_access_s, sizeof(rule_access_s),
8188 					   r->access);
8189 			TH_LOG("  rule[%d]: path=%s access=%s quiet=%d", i,
8190 			       r->path, rule_access_s, r->quiet);
8191 		}
8192 	}
8193 	return 0;
8194 }
8195 
8196 void audit_quiet_layout1_test_body(struct __test_metadata *const _metadata,
8197 				   FIXTURE_DATA(audit_quiet_layout1) * self,
8198 				   const struct a_target *targets)
8199 {
8200 	struct audit_records records = {};
8201 	int i;
8202 	const struct a_target *target;
8203 	int fd = -1;
8204 	int open_mode;
8205 	int ret;
8206 	bool expect_audit;
8207 	const char *blocker;
8208 
8209 	for (i = 0; i < AUDIT_QUIET_MAX_TARGETS; i++) {
8210 		target = &targets[i];
8211 		if (!target->target)
8212 			continue;
8213 
8214 		open_mode = target->open_mode & (O_RDONLY | O_WRONLY | O_RDWR);
8215 
8216 		EXPECT_TRUE(open_mode == O_RDONLY || open_mode == O_WRONLY ||
8217 			    open_mode == O_RDWR);
8218 
8219 		if (target->expect_open_success) {
8220 			EXPECT_FALSE(target->audit_read_blocked);
8221 			EXPECT_FALSE(target->audit_write_blocked);
8222 		}
8223 		if (target->expect_truncate_success)
8224 			EXPECT_TRUE(target->expect_open_success &&
8225 				    !target->audit_truncate);
8226 
8227 		if (debug_quiet_tests)
8228 			TH_LOG("Try open \"%s\" with %s%s", target->target,
8229 			       open_mode != O_WRONLY ? "r" : "",
8230 			       open_mode != O_RDONLY ? "w" : "");
8231 
8232 		fd = openat(AT_FDCWD, target->target, open_mode | O_CLOEXEC);
8233 		if (target->expect_open_success) {
8234 			ASSERT_LE(0, fd)
8235 			{
8236 				TH_LOG("Failed to open \"%s\": %s",
8237 				       target->target, strerror(errno));
8238 			};
8239 		} else {
8240 			ASSERT_EQ(-1, fd);
8241 			ASSERT_EQ(EACCES, errno);
8242 		}
8243 
8244 		expect_audit = true;
8245 
8246 		if (target->audit_read_blocked && target->audit_write_blocked)
8247 			blocker = "fs\\.write_file,fs\\.read_file";
8248 		else if (target->audit_read_blocked)
8249 			blocker = "fs\\.read_file";
8250 		else if (target->audit_write_blocked)
8251 			blocker = "fs\\.write_file";
8252 		else
8253 			expect_audit = false;
8254 
8255 		if (expect_audit)
8256 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
8257 						    blocker, target->target));
8258 
8259 		/* Check that we see no (other) logs. */
8260 		EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
8261 		ASSERT_EQ(0, records.access);
8262 
8263 		if (target->expect_open_success && fd >= 0) {
8264 			if (debug_quiet_tests)
8265 				TH_LOG("Try ftruncate \"%s\"", target->target);
8266 
8267 			ret = ftruncate(fd, 0);
8268 			if (target->expect_truncate_success) {
8269 				ASSERT_EQ(0, ret);
8270 			} else {
8271 				ASSERT_EQ(-1, ret);
8272 				if (open_mode != O_RDONLY)
8273 					ASSERT_EQ(EACCES, errno);
8274 			}
8275 
8276 			if (target->audit_truncate)
8277 				ASSERT_EQ(0, matches_log_fs(_metadata,
8278 							    self->audit_fd,
8279 							    "fs\\.truncate",
8280 							    target->target));
8281 
8282 			if (target->expect_ioctl_allowed ||
8283 			    target->expect_ioctl_denied) {
8284 				if (debug_quiet_tests)
8285 					TH_LOG("Try ioctl FIONREAD on \"%s\"",
8286 					       target->target);
8287 
8288 				ret = ioctl_error(_metadata, fd, FIONREAD);
8289 				if (target->expect_ioctl_allowed) {
8290 					ASSERT_NE(EACCES, ret);
8291 				} else {
8292 					ASSERT_EQ(EACCES, ret);
8293 				}
8294 			}
8295 
8296 			if (target->audit_ioctl)
8297 				ASSERT_EQ(0, matches_log_fs_extra(
8298 						     _metadata, self->audit_fd,
8299 						     "fs\\.ioctl_dev",
8300 						     target->target,
8301 						     " ioctlcmd=0x541b\\+"));
8302 
8303 			/* Check that we see no other logs. */
8304 			EXPECT_EQ(0, audit_count_records(self->audit_fd,
8305 							 &records));
8306 			ASSERT_EQ(0, records.access);
8307 			ASSERT_EQ(0, close(fd));
8308 		}
8309 	}
8310 }
8311 
8312 TEST_F(audit_quiet_layout1, base)
8313 {
8314 	int i;
8315 
8316 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
8317 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
8318 
8319 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
8320 }
8321 
8322 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_simple) {
8323 	.layers = {
8324 		{
8325 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8326 			.quiet_access_fs = FS_R,
8327 			.rules = {
8328 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8329 			},
8330 		},
8331 	},
8332 	.targets = {
8333 		{
8334 			.target = file1_s1d1,
8335 			.open_mode = O_RDONLY,
8336 		},
8337 		/* Not covered by quiet */
8338 		{
8339 			.target = file1_s2d1,
8340 			.open_mode = O_RDONLY,
8341 			.audit_read_blocked = true,
8342 		},
8343 		/* Access not quieted */
8344 		{
8345 			.target = file1_s1d1,
8346 			.open_mode = O_WRONLY,
8347 			.audit_write_blocked = true,
8348 		},
8349 		/*
8350 		 * Quiet flag only takes effect if all blocked access bits are
8351 		 * quieted, otherwise audit log emitted as normal (with all
8352 		 * blockers)
8353 		 */
8354 		{
8355 			.target = file1_s1d1,
8356 			.open_mode = O_RDWR,
8357 			.audit_read_blocked = true,
8358 			.audit_write_blocked = true,
8359 		},
8360 	},
8361 };
8362 
8363 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_allow_read) {
8364 	.layers = {
8365 		{
8366 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8367 			.quiet_access_fs = FS_W,
8368 			.rules = {
8369 				{ .path = dir_s1d1, .access = FS_R, .quiet = true },
8370 				/* Quiet flags inherit down and are not overridden */
8371 				{ .path = file1_s1d1, .access = FS_R, .quiet = false },
8372 				{ .path = file1_s2d3, .access = 0, .quiet = true },
8373 			},
8374 		},
8375 	},
8376 	.targets = {
8377 		/* Read ok */
8378 		{
8379 			.target = file1_s1d1,
8380 			.open_mode = O_RDONLY,
8381 			.expect_open_success = true,
8382 		},
8383 		/* Write quieted */
8384 		{
8385 			.target = file1_s1d1,
8386 			.open_mode = O_WRONLY,
8387 		},
8388 		/* Read allowed, write quieted so no audit */
8389 		{
8390 			.target = file1_s1d1,
8391 			.open_mode = O_RDWR,
8392 		},
8393 		/* Not covered by quiet */
8394 		{
8395 			.target = file1_s2d2,
8396 			.open_mode = O_WRONLY,
8397 			.audit_write_blocked = true,
8398 		},
8399 		{
8400 			.target = file1_s2d2,
8401 			.open_mode = O_RDWR,
8402 			.audit_read_blocked = true,
8403 			.audit_write_blocked = true,
8404 		},
8405 		/* Single file quiet */
8406 		{
8407 			.target = file1_s2d3,
8408 			.open_mode = O_WRONLY,
8409 		},
8410 		/* Wrong file */
8411 		{
8412 			.target = file2_s2d3,
8413 			.open_mode = O_WRONLY,
8414 			.audit_write_blocked = true,
8415 		},
8416 		/* Access not quieted */
8417 		{
8418 			.target = file1_s2d3,
8419 			.open_mode = O_RDONLY,
8420 			.audit_read_blocked = true,
8421 		},
8422 		/* Some access not quieted */
8423 		{
8424 			.target = file1_s2d3,
8425 			.open_mode = O_RDWR,
8426 			.audit_read_blocked = true,
8427 			.audit_write_blocked = true,
8428 		},
8429 	},
8430 };
8431 
8432 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_allow_write) {
8433 	.layers = {
8434 		{
8435 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8436 			.quiet_access_fs = FS_R,
8437 			.rules = {
8438 				{ .path = dir_s1d1, .access = FS_W, .quiet = true },
8439 			},
8440 		},
8441 	},
8442 	.targets = {
8443 		/* Read quieted */
8444 		{
8445 			.target = file1_s1d1,
8446 			.open_mode = O_RDONLY,
8447 		},
8448 		/* Truncate not quieted */
8449 		{
8450 			.target = file1_s1d1,
8451 			.open_mode = O_WRONLY,
8452 			.expect_open_success = true,
8453 			.audit_truncate = true,
8454 		},
8455 		/* Not covered by quiet */
8456 		{
8457 			.target = file1_s2d1,
8458 			.open_mode = O_RDONLY,
8459 			.audit_read_blocked = true,
8460 		},
8461 		/* Write allowed, read quieted so no audit */
8462 		{
8463 			.target = file1_s1d1,
8464 			.open_mode = O_RDWR,
8465 		},
8466 	},
8467 };
8468 
8469 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_write_quiet_trunc) {
8470 	.layers = {
8471 		{
8472 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8473 			.quiet_access_fs = FS_TRUNC,
8474 			.rules = {
8475 				{ .path = dir_s1d1, .access = FS_W, .quiet = true },
8476 				{ .path = dir_s2d1, .access = FS_W, .quiet = false },
8477 			},
8478 		},
8479 	},
8480 	.targets = {
8481 		/* Read not allowed and not quieted */
8482 		{
8483 			.target = file1_s1d1,
8484 			.open_mode = O_RDONLY,
8485 			.audit_read_blocked = true,
8486 		},
8487 		/* Truncate quieted */
8488 		{
8489 			.target = file1_s1d1,
8490 			.open_mode = O_WRONLY,
8491 			.expect_open_success = true,
8492 		},
8493 		/* Not covered by quiet (truncate) */
8494 		{
8495 			.target = file1_s2d1,
8496 			.open_mode = O_WRONLY,
8497 			.expect_open_success = true,
8498 			.audit_truncate = true,
8499 		},
8500 		/* Not covered by quiet (read/write) */
8501 		{
8502 			.target = file1_s3d1,
8503 			.open_mode = O_RDWR,
8504 			.audit_read_blocked = true,
8505 			.audit_write_blocked = true,
8506 		},
8507 	},
8508 };
8509 
8510 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_rw_quiet_trunc) {
8511 	.layers = {
8512 		{
8513 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8514 			.quiet_access_fs = FS_TRUNC,
8515 			.rules = {
8516 				{ .path = dir_s1d1, .access = FS_R | FS_W, .quiet = true },
8517 				{ .path = dir_s2d1, .access = FS_R | FS_W, .quiet = false },
8518 			},
8519 		},
8520 	},
8521 	.targets = {
8522 		{
8523 			.target = file1_s1d1,
8524 			.open_mode = O_RDWR,
8525 			.expect_open_success = true,
8526 		},
8527 		{
8528 			.target = file1_s2d1,
8529 			.open_mode = O_RDWR,
8530 			.expect_open_success = true,
8531 			.audit_truncate = true,
8532 		},
8533 	},
8534 };
8535 
8536 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_all) {
8537 	.layers = {
8538 		{
8539 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8540 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8541 			.rules = {
8542 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8543 				{ .path = file1_s2d1, .access = FS_R | FS_W, .quiet = true },
8544 				{ .path = file1_s2d3, .access = 0, .quiet = true },
8545 				{ .path = dir_s3d1, .access = FS_W, .quiet = false },
8546 				{ .path = "/dev/zero", .access = FS_R, .quiet = false },
8547 				{ .path = "/dev/null", .access = FS_R, .quiet = true },
8548 			},
8549 		},
8550 	},
8551 	.targets = {
8552 		/* No logs */
8553 		{
8554 			.target = file1_s1d1,
8555 			.open_mode = O_RDONLY,
8556 		},
8557 		{
8558 			.target = file1_s1d1,
8559 			.open_mode = O_WRONLY,
8560 		},
8561 		{
8562 			.target = file1_s1d1,
8563 			.open_mode = O_RDWR,
8564 		},
8565 		/* Truncate quieted - no log */
8566 		{
8567 			.target = file1_s2d1,
8568 			.open_mode = O_RDWR,
8569 			.expect_open_success = true,
8570 		},
8571 		/* Truncate not covered by quiet */
8572 		{
8573 			.target = file1_s3d1,
8574 			.open_mode = O_WRONLY,
8575 			.expect_open_success = true,
8576 			.audit_truncate = true,
8577 		},
8578 		/* Not covered by quiet */
8579 		{
8580 			.target = file1_s3d1,
8581 			.open_mode = O_RDONLY,
8582 			.audit_read_blocked = true,
8583 		},
8584 		/* Single file quiet */
8585 		{
8586 			.target = file1_s2d3,
8587 			.open_mode = O_RDWR,
8588 		},
8589 		/* Wrong file */
8590 		{
8591 			.target = file2_s2d3,
8592 			.open_mode = O_RDWR,
8593 			.audit_read_blocked = true,
8594 			.audit_write_blocked = true,
8595 		},
8596 		/* Ioctl quieted */
8597 		{
8598 			.target = "/dev/null",
8599 			.open_mode = O_RDONLY,
8600 			.expect_open_success = true,
8601 			.expect_ioctl_denied = true,
8602 		},
8603 		/* Ioctl not quieted */
8604 		{
8605 			.target = "/dev/zero",
8606 			.open_mode = O_RDONLY,
8607 			.expect_open_success = true,
8608 			.expect_ioctl_denied = true,
8609 			.audit_ioctl = true,
8610 		},
8611 	},
8612 };
8613 
8614 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_across_mountpoint) {
8615 	.layers = {
8616 		{
8617 			.handled_access_fs = FS_R | FS_W | FS_TRUNC,
8618 			.quiet_access_fs = FS_R,
8619 			.rules = {
8620 				{ .path = dir_s3d1, .access = 0, .quiet = true },
8621 			},
8622 		},
8623 	},
8624 	.targets = {
8625 		{
8626 			.target = file1_s3d3,
8627 			.open_mode = O_RDONLY,
8628 		},
8629 		/* Not covered by quiet */
8630 		{
8631 			.target = file1_s1d1,
8632 			.open_mode = O_RDONLY,
8633 			.audit_read_blocked = true,
8634 		},
8635 		{
8636 			.target = file1_s1d1,
8637 			.open_mode = O_RDWR,
8638 			.audit_read_blocked = true,
8639 			.audit_write_blocked = true,
8640 		},
8641 		/* Access not quieted */
8642 		{
8643 			.target = file1_s3d3,
8644 			.open_mode = O_WRONLY,
8645 			.audit_write_blocked = true,
8646 		},
8647 	},
8648 };
8649 
8650 FIXTURE_VARIANT_ADD(audit_quiet_layout1, allow_all_quiet) {
8651 	.layers = {
8652 		{
8653 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8654 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8655 			.rules = {
8656 				{
8657 					.path = dir_s1d1,
8658 					.access = FS_R | FS_W | FS_TRUNC,
8659 					.quiet = true
8660 				},
8661 				{
8662 					.path = "/dev/null",
8663 					.access = FS_R | FS_W | FS_IOCTL,
8664 					.quiet = true
8665 				},
8666 			},
8667 		},
8668 	},
8669 	.targets = {
8670 		{
8671 			.target = file1_s1d1,
8672 			.open_mode = O_RDWR,
8673 			.expect_open_success = true,
8674 			.expect_truncate_success = true,
8675 		},
8676 		{
8677 			.target = "/dev/null",
8678 			.open_mode = O_RDONLY,
8679 			.expect_open_success = true,
8680 			.expect_ioctl_allowed = true,
8681 		},
8682 	},
8683 };
8684 
8685 /*
8686  * With LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, it doesn't matter what the
8687  * quiet flags below the layer say.
8688  */
8689 FIXTURE_VARIANT_ADD(audit_quiet_layout1, subdomains_off) {
8690 	.layers = {
8691 		{
8692 			.handled_access_fs = FS_R,
8693 			.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
8694 			.rules = {
8695 				{ .path = "/", .access = FS_R, .quiet = false },
8696 			}
8697 		},
8698 		{
8699 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8700 			.quiet_access_fs = FS_R,
8701 			.rules = {
8702 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8703 				{ .path = file1_s2d2, .access = FS_R | FS_W, .quiet = true },
8704 				{ .path = file1_s2d3, .access = FS_R | FS_W, .quiet = false },
8705 				{ .path = "/dev/null", .access = FS_R | FS_W, .quiet = true },
8706 				{ .path = "/dev/zero", .access = FS_R | FS_W, .quiet = false },
8707 			},
8708 		},
8709 	},
8710 	.targets = {
8711 		{
8712 			.target = file1_s1d1,
8713 			.open_mode = O_RDWR,
8714 		},
8715 		{
8716 			.target = file1_s2d1,
8717 			.open_mode = O_RDWR,
8718 		},
8719 		{
8720 			.target = file1_s2d2,
8721 			.open_mode = O_RDWR,
8722 			.expect_open_success = true,
8723 			/* No audit_truncate */
8724 		},
8725 		{
8726 			.target = file1_s2d3,
8727 			.open_mode = O_RDWR,
8728 			.expect_open_success = true,
8729 			/* No audit_truncate */
8730 		},
8731 		{
8732 			.target = "/dev/null",
8733 			.open_mode = O_RDONLY,
8734 			.expect_open_success = true,
8735 			.expect_ioctl_denied = true,
8736 			/* No audit_ioctl */
8737 		},
8738 		{
8739 			.target = "/dev/zero",
8740 			.open_mode = O_RDONLY,
8741 			.expect_open_success = true,
8742 			.expect_ioctl_denied = true,
8743 			/* No audit_ioctl */
8744 		},
8745 	},
8746 };
8747 
8748 /*
8749  * With LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF, it doesn't matter what the
8750  * quiet flags on the layer say.
8751  */
8752 FIXTURE_VARIANT_ADD(audit_quiet_layout1, same_exec_off) {
8753 	.layers = {
8754 		{
8755 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8756 			.quiet_access_fs = FS_R,
8757 			.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
8758 			.rules = {
8759 				{ .path = dir_s1d1, .access = 0, .quiet = true },
8760 				{ .path = file1_s2d2, .access = FS_R | FS_W, .quiet = true },
8761 				{ .path = file1_s2d3, .access = FS_R | FS_W, .quiet = false },
8762 				{ .path = "/dev/null", .access = FS_R | FS_W, .quiet = true },
8763 				{ .path = "/dev/zero", .access = FS_R | FS_W, .quiet = false },
8764 			},
8765 		},
8766 	},
8767 	.targets = {
8768 		{
8769 			.target = file1_s1d1,
8770 			.open_mode = O_RDWR,
8771 		},
8772 		{
8773 			.target = file1_s2d1,
8774 			.open_mode = O_RDWR,
8775 		},
8776 		{
8777 			.target = file1_s2d2,
8778 			.open_mode = O_RDWR,
8779 			.expect_open_success = true,
8780 			/* No audit_truncate */
8781 		},
8782 		{
8783 			.target = file1_s2d3,
8784 			.open_mode = O_RDWR,
8785 			.expect_open_success = true,
8786 			/* No audit_truncate */
8787 		},
8788 		{
8789 			.target = "/dev/null",
8790 			.open_mode = O_RDONLY,
8791 			.expect_open_success = true,
8792 			.expect_ioctl_denied = true,
8793 			/* No audit_ioctl */
8794 		},
8795 		{
8796 			.target = "/dev/zero",
8797 			.open_mode = O_RDONLY,
8798 			.expect_open_success = true,
8799 			.expect_ioctl_denied = true,
8800 			/* No audit_ioctl */
8801 		},
8802 	},
8803 };
8804 
8805 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_1) {
8806 	/* Here, rules that deny access are always quiet. */
8807 	.layers = {
8808 		{
8809 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8810 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8811 			.rules = {
8812 				{
8813 					.path = dir_s1d1,
8814 					.access = FS_W,
8815 					.quiet = true,
8816 				},
8817 				{
8818 					.path = dir_s2d1,
8819 					.access = FS_R | FS_W | FS_TRUNC,
8820 					.quiet = false,
8821 				},
8822 				{
8823 					.path = "/dev/null",
8824 					.access = FS_R,
8825 					.quiet = true,
8826 				},
8827 				{
8828 					.path = "/dev/zero",
8829 					.access = FS_R | FS_W | FS_IOCTL,
8830 					.quiet = false,
8831 				},
8832 			},
8833 		},
8834 		{
8835 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8836 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8837 			.rules = {
8838 				{
8839 					.path = dir_s1d1,
8840 					.access = FS_R | FS_W | FS_TRUNC,
8841 					.quiet = false,
8842 				},
8843 				{
8844 					.path = dir_s2d1,
8845 					.access = FS_W,
8846 					.quiet = true,
8847 				},
8848 				{
8849 					.path = "/dev/null",
8850 					.access = FS_R | FS_W | FS_IOCTL,
8851 					.quiet = false,
8852 				},
8853 				{
8854 					.path = "/dev/zero",
8855 					.access = FS_R,
8856 					.quiet = true,
8857 				},
8858 			},
8859 		},
8860 	},
8861 	.targets = {
8862 		{
8863 			.target = file1_s1d1,
8864 			.open_mode = O_RDONLY,
8865 		},
8866 		{
8867 			.target = file1_s1d1,
8868 			.open_mode = O_WRONLY,
8869 			.expect_open_success = true,
8870 		},
8871 		{
8872 			.target = file1_s2d1,
8873 			.open_mode = O_RDONLY,
8874 		},
8875 		{
8876 			.target = file1_s2d1,
8877 			.open_mode = O_WRONLY,
8878 			.expect_open_success = true,
8879 		},
8880 		{
8881 			.target = "/dev/null",
8882 			.open_mode = O_RDONLY,
8883 			.expect_open_success = true,
8884 			.expect_ioctl_denied = true,
8885 		},
8886 		{
8887 			.target = "/dev/zero",
8888 			.open_mode = O_RDONLY,
8889 			.expect_open_success = true,
8890 			.expect_ioctl_denied = true,
8891 		},
8892 	},
8893 };
8894 
8895 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_2) {
8896 	/* Here, rules that deny access are never quiet. */
8897 	.layers = {
8898 		{
8899 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8900 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8901 			.rules = {
8902 				{
8903 					.path = dir_s1d1,
8904 					.access = FS_W,
8905 					.quiet = false
8906 				},
8907 				{
8908 					.path = dir_s2d1,
8909 					.access = FS_R | FS_W | FS_TRUNC,
8910 					.quiet = true
8911 				},
8912 				{
8913 					.path = "/dev/null",
8914 					.access = FS_R,
8915 					.quiet = false
8916 				},
8917 				{
8918 					.path = "/dev/zero",
8919 					.access = FS_R | FS_W | FS_IOCTL,
8920 					.quiet = true
8921 				},
8922 			},
8923 		},
8924 		{
8925 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8926 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8927 			.rules = {
8928 				{
8929 					.path = dir_s1d1,
8930 					.access = FS_R | FS_W | FS_TRUNC,
8931 					.quiet = true
8932 				},
8933 				{
8934 					.path = dir_s2d1,
8935 					.access = FS_W,
8936 					.quiet = false
8937 				},
8938 				{
8939 					.path = "/dev/null",
8940 					.access = FS_R | FS_W | FS_IOCTL,
8941 					.quiet = true
8942 				},
8943 				{
8944 					.path = "/dev/zero",
8945 					.access = FS_R,
8946 					.quiet = false
8947 				},
8948 			},
8949 		},
8950 	},
8951 	.targets = {
8952 		{
8953 			.target = file1_s1d1,
8954 			.open_mode = O_RDONLY,
8955 			.audit_read_blocked = true,
8956 		},
8957 		{
8958 			.target = file1_s1d1,
8959 			.open_mode = O_WRONLY,
8960 			.expect_open_success = true,
8961 			.audit_truncate	= true,
8962 		},
8963 		{
8964 			.target = file1_s2d1,
8965 			.open_mode = O_RDONLY,
8966 			.audit_read_blocked = true,
8967 		},
8968 		{
8969 			.target = file1_s2d1,
8970 			.open_mode = O_WRONLY,
8971 			.expect_open_success = true,
8972 			.audit_truncate	= true,
8973 		},
8974 		{
8975 			.target = "/dev/null",
8976 			.open_mode = O_RDONLY,
8977 			.expect_open_success = true,
8978 			.expect_ioctl_denied = true,
8979 			.audit_ioctl = true,
8980 		},
8981 		{
8982 			.target = "/dev/zero",
8983 			.open_mode = O_RDONLY,
8984 			.expect_open_success = true,
8985 			.expect_ioctl_denied = true,
8986 			.audit_ioctl = true,
8987 		},
8988 	},
8989 };
8990 
8991 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_3) {
8992 	/* This time only the second layer quiets things. */
8993 	.layers = {
8994 		{
8995 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8996 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
8997 			.rules = {
8998 				{
8999 					.path = dir_s1d1,
9000 					.access = FS_W,
9001 					.quiet = false,
9002 				},
9003 				{
9004 					.path = dir_s2d1,
9005 					.access = FS_R | FS_W | FS_TRUNC,
9006 					.quiet = false,
9007 				},
9008 				{
9009 					.path = "/dev/null",
9010 					.access = FS_R,
9011 					.quiet = false,
9012 				},
9013 				{
9014 					.path = "/dev/zero",
9015 					.access = FS_R | FS_W | FS_IOCTL,
9016 					.quiet = false,
9017 				},
9018 			},
9019 		},
9020 		{
9021 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9022 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9023 			.rules = {
9024 				{
9025 					.path = dir_s1d1,
9026 					.access = FS_R | FS_W | FS_TRUNC,
9027 					.quiet = false,
9028 				},
9029 				{
9030 					.path = dir_s2d1,
9031 					.access = FS_W,
9032 					.quiet = true,
9033 				},
9034 				{
9035 					.path = "/dev/null",
9036 					.access = FS_R | FS_W | FS_IOCTL,
9037 					.quiet = false,
9038 				},
9039 				{
9040 					.path = "/dev/zero",
9041 					.access = FS_R,
9042 					.quiet = true,
9043 				},
9044 			},
9045 		},
9046 	},
9047 	.targets = {
9048 		{
9049 			.target = file1_s1d1,
9050 			.open_mode = O_RDONLY,
9051 			.audit_read_blocked = true,
9052 		},
9053 		{
9054 			.target = file1_s1d1,
9055 			.open_mode = O_WRONLY,
9056 			.expect_open_success = true,
9057 			.audit_truncate = true,
9058 		},
9059 		{
9060 			.target = file1_s2d1,
9061 			.open_mode = O_RDONLY,
9062 		},
9063 		{
9064 			.target = file1_s2d1,
9065 			.open_mode = O_WRONLY,
9066 			.expect_open_success = true,
9067 		},
9068 		{
9069 			.target = "/dev/null",
9070 			.open_mode = O_RDONLY,
9071 			.expect_open_success = true,
9072 			.expect_ioctl_denied = true,
9073 			.audit_ioctl = true,
9074 		},
9075 		{
9076 			.target = "/dev/zero",
9077 			.open_mode = O_RDONLY,
9078 			.expect_open_success = true,
9079 			.expect_ioctl_denied = true,
9080 		},
9081 	},
9082 };
9083 
9084 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_quiet_access) {
9085 	/* Here, rules that deny access are always quiet. */
9086 	.layers = {
9087 		{
9088 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9089 			.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9090 			.rules = {
9091 				{
9092 					.path = dir_s1d1,
9093 					.access = FS_W,
9094 					.quiet = true,
9095 				},
9096 				{
9097 					.path = dir_s2d1,
9098 					.access = FS_R | FS_W | FS_TRUNC,
9099 					.quiet = false,
9100 				},
9101 				{
9102 					.path = "/dev/null",
9103 					.access = FS_R,
9104 					.quiet = true,
9105 				},
9106 				{
9107 					.path = "/dev/zero",
9108 					.access = FS_R | FS_W | FS_IOCTL,
9109 					.quiet = false,
9110 				},
9111 			},
9112 		},
9113 		{
9114 			.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9115 			.quiet_access_fs = FS_IOCTL,
9116 			.rules = {
9117 				{
9118 					.path = dir_s1d1,
9119 					.access = FS_R | FS_W | FS_TRUNC,
9120 					.quiet = false,
9121 				},
9122 				{
9123 					.path = dir_s2d1,
9124 					.access = FS_W,
9125 					.quiet = true,
9126 				},
9127 				{
9128 					.path = "/dev/null",
9129 					.access = FS_R | FS_W | FS_IOCTL,
9130 					.quiet = false,
9131 				},
9132 				{
9133 					.path = "/dev/zero",
9134 					.access = FS_R,
9135 					.quiet = true,
9136 				},
9137 			},
9138 		},
9139 	},
9140 	.targets = {
9141 		{
9142 			.target = file1_s1d1,
9143 			.open_mode = O_RDONLY,
9144 		},
9145 		{
9146 			.target = file1_s1d1,
9147 			.open_mode = O_WRONLY,
9148 			.expect_open_success = true,
9149 		},
9150 		{
9151 			.target = file1_s2d1,
9152 			.open_mode = O_RDONLY,
9153 			.audit_read_blocked = true,
9154 		},
9155 		{
9156 			.target = file1_s2d1,
9157 			.open_mode = O_WRONLY,
9158 			.expect_open_success = true,
9159 			.audit_truncate	= true,
9160 		},
9161 		{
9162 			.target = "/dev/null",
9163 			.open_mode = O_RDONLY,
9164 			.expect_open_success = true,
9165 			.expect_ioctl_denied = true,
9166 		},
9167 		{
9168 			.target = "/dev/zero",
9169 			.open_mode = O_RDONLY,
9170 			.expect_open_success = true,
9171 			.expect_ioctl_denied = true,
9172 		},
9173 	},
9174 };
9175 
9176 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_1) {
9177 	/* Quiet from layer 1 */
9178 	.layers = {
9179 		{
9180 			.handled_access_fs = FS_R,
9181 			.quiet_access_fs = FS_R,
9182 			.rules = {
9183 				{
9184 					.path = file1_s1d1,
9185 					.access = FS_R,
9186 					.quiet = true,
9187 				},
9188 				{
9189 					.path = file2_s1d1,
9190 					.access = 0,
9191 					.quiet = true,
9192 				},
9193 				{
9194 					.path = file1_s1d2,
9195 					.access = 0,
9196 					.quiet = true,
9197 				},
9198 				{
9199 					.path = file2_s1d2,
9200 					.access = FS_R,
9201 					.quiet = true,
9202 				},
9203 			},
9204 		},
9205 		{
9206 			.handled_access_fs = FS_W,
9207 			.quiet_access_fs = FS_W,
9208 			.rules = {
9209 				{
9210 					.path = file1_s1d1,
9211 					.access = FS_W,
9212 					.quiet = false,
9213 				},
9214 				/* Nothing for file2_s1d1 */
9215 				{
9216 					.path = file1_s1d2,
9217 					.access = FS_W,
9218 					.quiet = false,
9219 				},
9220 				/* Nothing for file2_s1d2 */
9221 			},
9222 		},
9223 	},
9224 	.targets = {
9225 		{
9226 			.target = file1_s1d1,
9227 			.open_mode = O_RDWR,
9228 			.expect_open_success = true,
9229 			.expect_truncate_success = true,
9230 		},
9231 		/* Missing both, youngest layer denies write, not quiet */
9232 		{
9233 			.target = file2_s1d1,
9234 			.open_mode = O_RDWR,
9235 			.audit_write_blocked = true,
9236 		},
9237 		/* Missing read, denied and quieted by layer 1 */
9238 		{
9239 			.target = file1_s1d2,
9240 			.open_mode = O_RDWR,
9241 		},
9242 		/* Missing write, denied and not quieted by layer 2 */
9243 		{
9244 			.target = file2_s1d2,
9245 			.open_mode = O_RDWR,
9246 			.audit_write_blocked = true,
9247 		},
9248 	},
9249 };
9250 
9251 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_2) {
9252 	/* Quiet from layer 2 */
9253 	.layers = {
9254 		{
9255 			.handled_access_fs = FS_R,
9256 			.quiet_access_fs = FS_R,
9257 			.rules = {
9258 				{
9259 					.path = file1_s1d1,
9260 					.access = FS_R,
9261 					.quiet = false,
9262 				},
9263 				/* Nothing for file2_s1d1 and file1_s1d2 */
9264 				{
9265 					.path = file2_s1d2,
9266 					.access = FS_R,
9267 					.quiet = false,
9268 				},
9269 			},
9270 		},
9271 		{
9272 			.handled_access_fs = FS_W,
9273 			.quiet_access_fs = FS_W,
9274 			.rules = {
9275 				{
9276 					.path = file1_s1d1,
9277 					.access = FS_W,
9278 					.quiet = true,
9279 				},
9280 				{
9281 					.path = file2_s1d1,
9282 					.access = 0,
9283 					.quiet = true,
9284 				},
9285 				{
9286 					.path = file1_s1d2,
9287 					.access = FS_W,
9288 					.quiet = true,
9289 				},
9290 				{
9291 					.path = file2_s1d2,
9292 					.access = 0,
9293 					.quiet = true,
9294 				},
9295 			},
9296 		},
9297 	},
9298 	.targets = {
9299 		{
9300 			.target = file1_s1d1,
9301 			.open_mode = O_RDWR,
9302 			.expect_open_success = true,
9303 			.expect_truncate_success = true,
9304 		},
9305 		/* Missing both, youngest layer denies write, quiet */
9306 		{
9307 			.target = file2_s1d1,
9308 			.open_mode = O_RDWR,
9309 		},
9310 		/* Missing read, denied and not quieted by layer 1 */
9311 		{
9312 			.target = file1_s1d2,
9313 			.open_mode = O_RDWR,
9314 			.audit_read_blocked = true,
9315 		},
9316 		/* Missing write, denied and quieted by layer 2 */
9317 		{
9318 			.target = file2_s1d2,
9319 			.open_mode = O_RDWR,
9320 		},
9321 	},
9322 };
9323 
9324 FIXTURE_VARIANT_ADD(audit_quiet_layout1, quiet_two_layers_different_handled_3) {
9325 	/* Quiet from both layers */
9326 	.layers = {
9327 		{
9328 			.handled_access_fs = FS_R,
9329 			.quiet_access_fs = FS_R,
9330 			.rules = {
9331 				{
9332 					.path = file1_s1d1,
9333 					.access = FS_R,
9334 					.quiet = true,
9335 				},
9336 				{
9337 					.path = file2_s1d1,
9338 					.access = 0,
9339 					.quiet = true,
9340 				},
9341 				{
9342 					.path = file1_s1d2,
9343 					.access = 0,
9344 					.quiet = true,
9345 				},
9346 				{
9347 					.path = file2_s1d2,
9348 					.access = FS_R,
9349 					.quiet = true,
9350 				},
9351 			},
9352 		},
9353 		{
9354 			.handled_access_fs = FS_W,
9355 			.quiet_access_fs = FS_W,
9356 			.rules = {
9357 				{
9358 					.path = file1_s1d1,
9359 					.access = FS_W,
9360 					.quiet = true,
9361 				},
9362 				{
9363 					.path = file2_s1d1,
9364 					.access = 0,
9365 					.quiet = true,
9366 				},
9367 				{
9368 					.path = file1_s1d2,
9369 					.access = FS_W,
9370 					.quiet = true,
9371 				},
9372 				{
9373 					.path = file2_s1d2,
9374 					.access = 0,
9375 					.quiet = true,
9376 				},
9377 			},
9378 		},
9379 	},
9380 	.targets = {
9381 		{
9382 			.target = file1_s1d1,
9383 			.open_mode = O_RDWR,
9384 			.expect_open_success = true,
9385 			.expect_truncate_success = true,
9386 		},
9387 		{
9388 			.target = file2_s1d1,
9389 			.open_mode = O_RDWR,
9390 		},
9391 		{
9392 			.target = file1_s1d2,
9393 			.open_mode = O_RDWR,
9394 		},
9395 		{
9396 			.target = file2_s1d2,
9397 			.open_mode = O_RDWR,
9398 		},
9399 	},
9400 };
9401 
9402 FIXTURE_VARIANT_ADD(audit_quiet_layout1, without_quiet_then_with_quiet) {
9403 	.layers = {
9404 		{
9405 			.handled_access_fs = FS_R | FS_W,
9406 			.quiet_access_fs = FS_R,
9407 			.rules = {
9408 				{ .path = dir_s1d1, .access = FS_W, .quiet = false },
9409 				{ .path = dir_s1d1, .access = 0, .quiet = true },
9410 			},
9411 		},
9412 	},
9413 	.targets = {
9414 		/* Read denied and quieted */
9415 		{
9416 			.target = file1_s1d1,
9417 			.open_mode = O_RDONLY,
9418 		},
9419 		/* Write ok */
9420 		{
9421 			.target = file1_s1d1,
9422 			.open_mode = O_WRONLY,
9423 			.expect_open_success = true,
9424 			.expect_truncate_success = true,
9425 		},
9426 		/* Write ok, read denied and quieted */
9427 		{
9428 			.target = file1_s1d1,
9429 			.open_mode = O_RDWR,
9430 		},
9431 		/* Not covered by quiet */
9432 		{
9433 			.target = file1_s2d1,
9434 			.open_mode = O_RDONLY,
9435 			.audit_read_blocked = true,
9436 		},
9437 	},
9438 };
9439 
9440 /*
9441  * The following TEST_F extend the above test cases to test more layers, with
9442  * the inserted layers having varying configurations.
9443  */
9444 
9445 /* Extra allow all layers, quiet or not, does not change any behaviour. */
9446 TEST_F(audit_quiet_layout1, allow_all_layer)
9447 {
9448 	struct a_layer allow_all_layer = {
9449 		.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9450 		.quiet_access_fs = 0,
9451 		.rules = {
9452 			{
9453 				.path = "/",
9454 				.access = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9455 				.quiet = false,
9456 			},
9457 		},
9458 	};
9459 	int i;
9460 
9461 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9462 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9463 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9464 
9465 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9466 
9467 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9468 
9469 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9470 
9471 	/*
9472 	 * SELF_LOG flags or quiet bits from inner allowing layers should not
9473 	 * affect behaviour.
9474 	 */
9475 	allow_all_layer.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL;
9476 	allow_all_layer.rules[0].quiet = true;
9477 	/*
9478 	 * Note: this only works because we're not checking counts of domain
9479 	 * alloc/dealloc logs
9480 	 */
9481 	allow_all_layer.restrict_flags =
9482 		LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
9483 		LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF;
9484 	ASSERT_EQ(0, apply_a_layer(_metadata, &allow_all_layer));
9485 
9486 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9487 }
9488 
9489 /*
9490  * Add useless outer layers until we reach the layer limit.  Should not change
9491  * anything.
9492  */
9493 TEST_F(audit_quiet_layout1, many_outer_layers)
9494 {
9495 	struct a_layer useless_layer = {
9496 		.handled_access_fs = FS_R | FS_W | FS_TRUNC,
9497 		.quiet_access_fs = FS_R | FS_W | FS_TRUNC,
9498 		.rules = {
9499 			{ .path = "/", .access = FS_R | FS_W | FS_TRUNC, .quiet = true },
9500 		},
9501 	};
9502 	int i;
9503 
9504 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++) {
9505 		if (variant->layers[i].handled_access_fs == 0)
9506 			break;
9507 	}
9508 
9509 	for (; i < LANDLOCK_MAX_NUM_LAYERS; i++)
9510 		ASSERT_EQ(0, apply_a_layer(_metadata, &useless_layer));
9511 
9512 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9513 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9514 
9515 	audit_quiet_layout1_test_body(_metadata, self, variant->targets);
9516 }
9517 
9518 /* An inner layer that denies and quiets everything should result in no logs. */
9519 TEST_F(audit_quiet_layout1, deny_all_quiet_layer)
9520 {
9521 	struct a_layer deny_all_layer = {
9522 		.handled_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9523 		.quiet_access_fs = FS_R | FS_W | FS_TRUNC | FS_IOCTL,
9524 		.rules = {
9525 			{ .path = "/", .access = 0, .quiet = true },
9526 		},
9527 	};
9528 	int i;
9529 	FIXTURE_VARIANT(audit_quiet_layout1) variant_2 = {};
9530 
9531 	/* Any open should fail with no logs. */
9532 	for (i = 0; i < ARRAY_SIZE(variant->targets); i++) {
9533 		const struct a_target *target = &variant->targets[i];
9534 
9535 		variant_2.targets[i] = (struct a_target){
9536 			.target = target->target,
9537 			.open_mode = target->open_mode,
9538 			/* We denied everything, open should always fail. */
9539 			.expect_open_success = false,
9540 		};
9541 	}
9542 
9543 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9544 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9545 	ASSERT_EQ(0, apply_a_layer(_metadata, &deny_all_layer));
9546 
9547 	audit_quiet_layout1_test_body(_metadata, self, variant_2.targets);
9548 }
9549 
9550 /*
9551  * An inner layer that denies everything without quiet should produce logs for
9552  * all access.
9553  */
9554 TEST_F(audit_quiet_layout1, deny_all_layer)
9555 {
9556 	struct a_layer deny_all_layer = {
9557 		.handled_access_fs = FS_R | FS_W,
9558 		.quiet_access_fs = FS_R | FS_W,
9559 	};
9560 	int i;
9561 	FIXTURE_VARIANT(audit_quiet_layout1) variant_2 = {};
9562 	bool test_has_subdomains_off = false;
9563 
9564 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++) {
9565 		if (variant->layers[i].restrict_flags &
9566 		    LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF) {
9567 			test_has_subdomains_off = true;
9568 			break;
9569 		}
9570 	}
9571 
9572 	for (i = 0; i < ARRAY_SIZE(variant->targets); i++) {
9573 		const struct a_target *target = &variant->targets[i];
9574 
9575 		variant_2.targets[i] = (struct a_target){
9576 			.target = target->target,
9577 			.open_mode = target->open_mode,
9578 
9579 			/* We denied everything, open should always fail. */
9580 			.expect_open_success = false,
9581 			/* Audit should always happen as long as open request contains read. */
9582 			.audit_read_blocked = !test_has_subdomains_off &&
9583 					      target->open_mode != O_WRONLY,
9584 			/* Audit should always happen as long as open request contains write. */
9585 			.audit_write_blocked = !test_has_subdomains_off &&
9586 					       target->open_mode != O_RDONLY,
9587 		};
9588 	}
9589 
9590 	for (i = 0; i < ARRAY_SIZE(variant->layers); i++)
9591 		ASSERT_EQ(0, apply_a_layer(_metadata, &variant->layers[i]));
9592 	ASSERT_EQ(0, apply_a_layer(_metadata, &deny_all_layer));
9593 
9594 	audit_quiet_layout1_test_body(_metadata, self, variant_2.targets);
9595 }
9596 
9597 /* Uses layout1_bind hierarchy */
9598 FIXTURE(audit_quiet_rename)
9599 {
9600 	struct audit_filter audit_filter;
9601 	int audit_fd;
9602 };
9603 
9604 FIXTURE_SETUP(audit_quiet_rename)
9605 {
9606 	prepare_layout(_metadata);
9607 	create_layout1(_metadata);
9608 
9609 	set_cap(_metadata, CAP_SYS_ADMIN);
9610 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
9611 	clear_cap(_metadata, CAP_SYS_ADMIN);
9612 
9613 	set_cap(_metadata, CAP_AUDIT_CONTROL);
9614 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
9615 	EXPECT_LE(0, self->audit_fd);
9616 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
9617 
9618 	if (getenv("DEBUG_QUIET_TESTS"))
9619 		debug_quiet_tests = true;
9620 }
9621 
9622 FIXTURE_TEARDOWN_PARENT(audit_quiet_rename)
9623 {
9624 	remove_layout1(_metadata);
9625 	cleanup_layout(_metadata);
9626 
9627 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
9628 
9629 	remove_path(file1_s4d1);
9630 	remove_path(file2_s4d1);
9631 
9632 	set_cap(_metadata, CAP_AUDIT_CONTROL);
9633 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
9634 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
9635 }
9636 
9637 static void simple_quiet_rename(struct __test_metadata *const _metadata,
9638 				FIXTURE_DATA(audit_quiet_rename) *const self,
9639 				__u64 handled_access, __u64 quiet_access,
9640 				bool source_allow, bool dest_allow,
9641 				bool source_quiet, bool dest_quiet,
9642 				const char *source_blockers,
9643 				const char *dest_blockers)
9644 {
9645 	/* We will move file1_s1d1 to file1_s2d1 */
9646 	struct a_layer layer = {
9647 		.handled_access_fs = handled_access,
9648 		.quiet_access_fs = quiet_access,
9649 		.rules = {
9650 			{
9651 				.path = dir_s1d1,
9652 				.access = source_allow ? handled_access : 0,
9653 				.quiet = source_quiet,
9654 			},
9655 			{
9656 				.path = dir_s2d1,
9657 				.access = dest_allow ? handled_access : 0,
9658 				.quiet = dest_quiet,
9659 			},
9660 		},
9661 	};
9662 	struct audit_records records = {};
9663 	int ret, err;
9664 
9665 	/* Skip landlock_add_rule for useless rules. */
9666 	if (!source_allow && !source_quiet)
9667 		layer.rules[0].path = NULL;
9668 	if (!dest_allow && !dest_quiet)
9669 		layer.rules[1].path = NULL;
9670 
9671 	EXPECT_EQ(0, unlink(file1_s2d1));
9672 	EXPECT_EQ(0, apply_a_layer(_metadata, &layer));
9673 
9674 	if (debug_quiet_tests)
9675 		TH_LOG("Try renameat \"%s\" to \"%s\"", file1_s1d1, file1_s2d1);
9676 	ret = renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1);
9677 	err = errno;
9678 	if (ret != 0 && debug_quiet_tests) {
9679 		TH_LOG("renameat error: %s", err == EXDEV  ? "EXDEV" :
9680 					     err == EACCES ? "EACCES" :
9681 							     strerror(err));
9682 	}
9683 	if (source_allow && dest_allow) {
9684 		ASSERT_EQ(0, ret);
9685 	} else {
9686 		ASSERT_EQ(-1, ret);
9687 		if (handled_access & (LANDLOCK_ACCESS_FS_MAKE_REG |
9688 				      LANDLOCK_ACCESS_FS_REMOVE_FILE)) {
9689 			ASSERT_EQ(EACCES, err);
9690 		} else {
9691 			ASSERT_EQ(EXDEV, err);
9692 		}
9693 
9694 		if (source_blockers)
9695 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9696 						    source_blockers, dir_s1d1));
9697 		if (dest_blockers)
9698 			ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9699 						    dest_blockers, dir_s2d1));
9700 	}
9701 	/*
9702 	 * No other logs. records.domain not checked per reasoning in
9703 	 * audit_quiet_layout1_test_body.
9704 	 */
9705 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9706 	ASSERT_EQ(0, records.access);
9707 }
9708 
9709 TEST_F(audit_quiet_rename, rename_ok)
9710 {
9711 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9712 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9713 		       LANDLOCK_ACCESS_FS_REFER;
9714 
9715 	simple_quiet_rename(_metadata, self, access, access, true, true, false,
9716 			    false, NULL, NULL);
9717 }
9718 
9719 TEST_F(audit_quiet_rename, no_quiet)
9720 {
9721 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9722 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9723 		       LANDLOCK_ACCESS_FS_REFER;
9724 
9725 	simple_quiet_rename(_metadata, self, access, access, false, false,
9726 			    false, false, "fs\\.remove_file,fs\\.refer",
9727 			    "fs\\.make_reg,fs\\.refer");
9728 }
9729 
9730 TEST_F(audit_quiet_rename, quiet)
9731 {
9732 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9733 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9734 		       LANDLOCK_ACCESS_FS_REFER;
9735 
9736 	simple_quiet_rename(_metadata, self, access, access, false, false, true,
9737 			    true, NULL, NULL);
9738 }
9739 
9740 TEST_F(audit_quiet_rename, source_no_quiet_dest_quiet)
9741 {
9742 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9743 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9744 		       LANDLOCK_ACCESS_FS_REFER;
9745 
9746 	simple_quiet_rename(_metadata, self, access, access, false, false,
9747 			    false, true, "fs\\.remove_file,fs\\.refer", NULL);
9748 }
9749 
9750 TEST_F(audit_quiet_rename, source_quiet_dest_no_quiet)
9751 {
9752 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9753 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9754 		       LANDLOCK_ACCESS_FS_REFER;
9755 
9756 	simple_quiet_rename(_metadata, self, access, access, false, false, true,
9757 			    false, NULL, "fs\\.make_reg,fs\\.refer");
9758 }
9759 
9760 TEST_F(audit_quiet_rename, only_quiet_refer)
9761 {
9762 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9763 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9764 		       LANDLOCK_ACCESS_FS_REFER;
9765 
9766 	simple_quiet_rename(_metadata, self, access, LANDLOCK_ACCESS_FS_REFER,
9767 			    false, false, true, true,
9768 			    "fs\\.remove_file,fs\\.refer",
9769 			    "fs\\.make_reg,fs\\.refer");
9770 }
9771 
9772 TEST_F(audit_quiet_rename, source_allow_dest_quiet)
9773 {
9774 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9775 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9776 		       LANDLOCK_ACCESS_FS_REFER;
9777 
9778 	simple_quiet_rename(_metadata, self, access, access, true, false, false,
9779 			    true, NULL, NULL);
9780 }
9781 
9782 TEST_F(audit_quiet_rename, source_quiet_dest_allow)
9783 {
9784 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9785 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9786 		       LANDLOCK_ACCESS_FS_REFER;
9787 
9788 	simple_quiet_rename(_metadata, self, access, access, false, true, true,
9789 			    false, NULL, NULL);
9790 }
9791 
9792 TEST_F(audit_quiet_rename, handle_all_deny_quiet_refer)
9793 {
9794 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9795 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9796 		       LANDLOCK_ACCESS_FS_REFER;
9797 	struct a_layer layer = {
9798 		.handled_access_fs = access,
9799 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
9800 		.rules = {
9801 			{
9802 				.path = dir_s1d1,
9803 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9804 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9805 				.quiet = true,
9806 			},
9807 			{
9808 				.path = dir_s2d1,
9809 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9810 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9811 				.quiet = true,
9812 			},
9813 		},
9814 	};
9815 	struct audit_records records = {};
9816 
9817 	EXPECT_EQ(0, unlink(file1_s2d1));
9818 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9819 
9820 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9821 	ASSERT_EQ(EXDEV, errno);
9822 
9823 	/* No logs */
9824 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9825 	ASSERT_EQ(0, records.access);
9826 }
9827 
9828 TEST_F(audit_quiet_rename, handle_all_deny_not_quiet_refer)
9829 {
9830 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9831 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9832 		       LANDLOCK_ACCESS_FS_REFER;
9833 	struct a_layer layer = {
9834 		.handled_access_fs = access,
9835 		.quiet_access_fs = 0,
9836 		.rules = {
9837 			{
9838 				.path = dir_s1d1,
9839 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9840 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9841 				.quiet = false,
9842 			},
9843 			{
9844 				.path = dir_s2d1,
9845 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9846 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9847 				.quiet = false,
9848 			},
9849 		},
9850 	};
9851 	struct audit_records records = {};
9852 
9853 	EXPECT_EQ(0, unlink(file1_s2d1));
9854 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9855 
9856 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9857 	ASSERT_EQ(EXDEV, errno);
9858 
9859 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9860 				    dir_s1d1));
9861 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9862 				    dir_s2d1));
9863 
9864 	/* No other logs */
9865 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9866 	ASSERT_EQ(0, records.access);
9867 }
9868 
9869 TEST_F(audit_quiet_rename, handle_all_deny_refer_quiet_source_not_quiet_dest)
9870 {
9871 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9872 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9873 		       LANDLOCK_ACCESS_FS_REFER;
9874 	struct a_layer layer = {
9875 		.handled_access_fs = access,
9876 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
9877 		.rules = {
9878 			{
9879 				.path = dir_s1d1,
9880 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9881 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9882 				.quiet = true,
9883 			},
9884 			{
9885 				.path = dir_s2d1,
9886 				.access = LANDLOCK_ACCESS_FS_MAKE_REG |
9887 					LANDLOCK_ACCESS_FS_REMOVE_FILE,
9888 				.quiet = false,
9889 			},
9890 		},
9891 	};
9892 	struct audit_records records = {};
9893 
9894 	EXPECT_EQ(0, unlink(file1_s2d1));
9895 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9896 
9897 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9898 	ASSERT_EQ(EXDEV, errno);
9899 
9900 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd, "fs\\.refer",
9901 				    dir_s2d1));
9902 
9903 	/* No other logs */
9904 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9905 	ASSERT_EQ(0, records.access);
9906 }
9907 
9908 TEST_F(audit_quiet_rename, quiet_same_dir)
9909 {
9910 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9911 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9912 		       LANDLOCK_ACCESS_FS_REFER;
9913 	struct a_layer layer = {
9914 		.handled_access_fs = access,
9915 		.quiet_access_fs = access,
9916 		.rules = {
9917 			{
9918 				.path = dir_s1d1,
9919 				.access = 0,
9920 				.quiet = true,
9921 			},
9922 		},
9923 	};
9924 	struct audit_records records = {};
9925 
9926 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9927 
9928 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1));
9929 	ASSERT_EQ(EACCES, errno);
9930 
9931 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9932 	ASSERT_EQ(0, records.access);
9933 }
9934 
9935 TEST_F(audit_quiet_rename, quiet_flag_on_file_ignored)
9936 {
9937 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9938 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9939 		       LANDLOCK_ACCESS_FS_REFER;
9940 	struct a_layer layer = {
9941 		.handled_access_fs = access,
9942 		.quiet_access_fs = access,
9943 		.rules = {
9944 			{
9945 				.path = file1_s1d1,
9946 				.access = 0,
9947 				.quiet = true,
9948 			},
9949 			{
9950 				.path = file1_s2d1,
9951 				.access = 0,
9952 				.quiet = true,
9953 			},
9954 		},
9955 	};
9956 	struct audit_records records = {};
9957 
9958 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9959 
9960 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
9961 	ASSERT_EQ(EACCES, errno);
9962 
9963 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9964 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
9965 	/* We didn't unlink destination file */
9966 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
9967 				    "fs\\.remove_file,fs\\.make_reg,fs\\.refer",
9968 				    dir_s2d1));
9969 
9970 	/* No other logs */
9971 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
9972 	ASSERT_EQ(0, records.access);
9973 }
9974 
9975 TEST_F(audit_quiet_rename, quiet_flag_on_file_ignored_same_dir)
9976 {
9977 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
9978 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
9979 		       LANDLOCK_ACCESS_FS_REFER;
9980 	struct a_layer layer = {
9981 		.handled_access_fs = access,
9982 		.quiet_access_fs = access,
9983 		.rules = {
9984 			{
9985 				.path = file1_s1d1,
9986 				.access = 0,
9987 				.quiet = true,
9988 			},
9989 			{
9990 				.path = file2_s1d1,
9991 				.access = 0,
9992 				.quiet = true,
9993 			},
9994 		},
9995 	};
9996 	struct audit_records records = {};
9997 
9998 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
9999 
10000 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1));
10001 	ASSERT_EQ(EACCES, errno);
10002 
10003 	ASSERT_EQ(0,
10004 		  matches_log_fs(_metadata, self->audit_fd,
10005 				 "fs\\.remove_file,fs\\.make_reg", dir_s1d1));
10006 
10007 	/* No other logs */
10008 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10009 	ASSERT_EQ(0, records.access);
10010 }
10011 
10012 TEST_F(audit_quiet_rename, two_layers_different_quiet1)
10013 {
10014 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10015 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10016 		       LANDLOCK_ACCESS_FS_REFER;
10017 	struct a_layer layer1 = {
10018 		.handled_access_fs = access,
10019 		.quiet_access_fs = access,
10020 		.rules = {
10021 			{
10022 				.path = dir_s1d1,
10023 				.access = access,
10024 				.quiet = false,
10025 			},
10026 			{
10027 				.path = dir_s2d1,
10028 				.access = 0,
10029 				.quiet = true,
10030 			},
10031 		},
10032 	};
10033 	struct a_layer layer2 = {
10034 		.handled_access_fs = access,
10035 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
10036 		.rules = {
10037 			{
10038 				.path = dir_s1d1,
10039 				.access = 0,
10040 				.quiet = true,
10041 			},
10042 			{
10043 				.path = dir_s2d1,
10044 				.access = access,
10045 				.quiet = false,
10046 			},
10047 		},
10048 	};
10049 	struct audit_records records = {};
10050 
10051 	EXPECT_EQ(0, unlink(file1_s2d1));
10052 
10053 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10054 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10055 
10056 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10057 	ASSERT_EQ(EACCES, errno);
10058 
10059 	/*
10060 	 * The youngest denial will be layer 2.  Refer is quieted but we are
10061 	 * also missing remove_file on source.
10062 	 */
10063 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10064 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
10065 	/* No other logs */
10066 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10067 	ASSERT_EQ(0, records.access);
10068 }
10069 
10070 TEST_F(audit_quiet_rename, two_layers_different_quiet2)
10071 {
10072 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10073 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10074 		       LANDLOCK_ACCESS_FS_REFER;
10075 	struct a_layer layer1 = {
10076 		.handled_access_fs = access,
10077 		.quiet_access_fs = access,
10078 		.rules = {
10079 			{
10080 				.path = dir_s1d1,
10081 				.access = access,
10082 				.quiet = false,
10083 			},
10084 			{
10085 				.path = dir_s2d1,
10086 				.access = 0,
10087 				.quiet = true,
10088 			},
10089 		},
10090 	};
10091 	struct a_layer layer2 = {
10092 		.handled_access_fs = LANDLOCK_ACCESS_FS_REFER,
10093 		.quiet_access_fs = LANDLOCK_ACCESS_FS_REFER,
10094 		.rules = {
10095 			{
10096 				.path = dir_s1d1,
10097 				.access = 0,
10098 				.quiet = true,
10099 			},
10100 			{
10101 				.path = dir_s2d1,
10102 				.access = LANDLOCK_ACCESS_FS_REFER,
10103 				.quiet = false,
10104 			},
10105 		},
10106 	};
10107 	struct audit_records records = {};
10108 
10109 	EXPECT_EQ(0, unlink(file1_s2d1));
10110 
10111 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10112 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10113 
10114 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10115 	ASSERT_EQ(EACCES, errno);
10116 
10117 	/*
10118 	 * The youngest denial will be layer 2, but refer is quieted (and that
10119 	 * layer does not handle any other accesses).
10120 	 */
10121 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10122 	ASSERT_EQ(0, records.access);
10123 }
10124 
10125 TEST_F(audit_quiet_rename, two_layers_different_quiet3)
10126 {
10127 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10128 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10129 		       LANDLOCK_ACCESS_FS_REFER;
10130 	struct a_layer layer1 = {
10131 		.handled_access_fs = access,
10132 		.quiet_access_fs = access,
10133 		.rules = {
10134 			{
10135 				.path = dir_s1d1,
10136 				.access = access,
10137 				.quiet = false,
10138 			},
10139 			{
10140 				.path = dir_s2d1,
10141 				.access = 0,
10142 				.quiet = true,
10143 			},
10144 		},
10145 	};
10146 	struct a_layer layer2 = {
10147 		.handled_access_fs = access,
10148 		.quiet_access_fs = access,
10149 		.rules = {
10150 			{
10151 				.path = dir_s1d1,
10152 				.access = 0,
10153 				.quiet = true,
10154 			},
10155 			{
10156 				.path = dir_s2d1,
10157 				.access = access,
10158 				.quiet = false,
10159 			},
10160 		},
10161 	};
10162 	struct audit_records records = {};
10163 
10164 	EXPECT_EQ(0, unlink(file1_s2d1));
10165 
10166 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10167 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10168 
10169 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10170 	ASSERT_EQ(EACCES, errno);
10171 
10172 	/*
10173 	 * The youngest denial will be layer 2, in which everything is quieted.
10174 	 */
10175 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10176 	ASSERT_EQ(0, records.access);
10177 }
10178 
10179 TEST_F(audit_quiet_rename,
10180        first_layer_quiet_deny_all_second_layer_not_quiet_deny_all)
10181 {
10182 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10183 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10184 		       LANDLOCK_ACCESS_FS_REFER;
10185 	struct a_layer layer1 = {
10186 		.handled_access_fs = access,
10187 		.quiet_access_fs = access,
10188 		.rules = {
10189 			{
10190 				.path = dir_s1d1,
10191 				.access = 0,
10192 				.quiet = true,
10193 			},
10194 			{
10195 				.path = dir_s2d1,
10196 				.access = 0,
10197 				.quiet = true,
10198 			},
10199 		},
10200 	};
10201 	struct a_layer layer2 = {
10202 		.handled_access_fs = access,
10203 		.quiet_access_fs = access,
10204 		.rules = {},
10205 	};
10206 	struct audit_records records = {};
10207 
10208 	EXPECT_EQ(0, unlink(file1_s2d1));
10209 
10210 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10211 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10212 
10213 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10214 	ASSERT_EQ(EACCES, errno);
10215 
10216 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10217 				    "fs\\.remove_file,fs\\.refer", dir_s1d1));
10218 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10219 				    "fs\\.make_reg,fs\\.refer", dir_s2d1));
10220 	/* No other logs. */
10221 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10222 	ASSERT_EQ(0, records.access);
10223 }
10224 
10225 TEST_F(audit_quiet_rename,
10226        first_layer_quiet_deny_all_second_layer_dest_not_quiet)
10227 {
10228 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10229 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10230 		       LANDLOCK_ACCESS_FS_REFER;
10231 	struct a_layer layer1 = {
10232 		.handled_access_fs = access,
10233 		.quiet_access_fs = access,
10234 		.rules = {
10235 			{
10236 				.path = dir_s1d1,
10237 				.access = 0,
10238 				.quiet = true,
10239 			},
10240 			{
10241 				.path = dir_s2d1,
10242 				.access = 0,
10243 				.quiet = true,
10244 			},
10245 		},
10246 	};
10247 	struct a_layer layer2 = {
10248 		.handled_access_fs = access,
10249 		.quiet_access_fs = access,
10250 		.rules = {
10251 			{
10252 				.path = dir_s1d1,
10253 				.access = 0,
10254 				.quiet = true,
10255 			},
10256 		},
10257 	};
10258 	struct audit_records records = {};
10259 
10260 	EXPECT_EQ(0, unlink(file1_s2d1));
10261 
10262 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer1));
10263 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer2));
10264 
10265 	ASSERT_EQ(-1, renameat(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1));
10266 	ASSERT_EQ(EACCES, errno);
10267 
10268 	/* Source is quieted but destination is not. */
10269 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10270 				    "fs\\.make_reg,fs\\.refer", dir_s2d1));
10271 	/* No other logs. */
10272 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10273 	ASSERT_EQ(0, records.access);
10274 }
10275 
10276 TEST_F(audit_quiet_rename, rename_xchg)
10277 {
10278 	struct a_layer layer = {
10279 		.handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_REG |
10280 				     LANDLOCK_ACCESS_FS_REMOVE_FILE |
10281 				     LANDLOCK_ACCESS_FS_REFER,
10282 		.quiet_access_fs = LANDLOCK_ACCESS_FS_MAKE_REG,
10283 		.rules = { {
10284 				   .path = dir_s1d1,
10285 				   .access = LANDLOCK_ACCESS_FS_REMOVE_FILE |
10286 					     LANDLOCK_ACCESS_FS_REFER,
10287 				   .quiet = true,
10288 			   },
10289 			   {
10290 				   .path = dir_s2d1,
10291 				   .access = LANDLOCK_ACCESS_FS_MAKE_REG |
10292 					     LANDLOCK_ACCESS_FS_REMOVE_FILE |
10293 					     LANDLOCK_ACCESS_FS_REFER,
10294 				   .quiet = false,
10295 			   } },
10296 	};
10297 	struct audit_records records = {};
10298 
10299 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10300 
10301 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d1,
10302 				RENAME_EXCHANGE));
10303 	ASSERT_EQ(EACCES, errno);
10304 
10305 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10306 	ASSERT_EQ(0, records.access);
10307 }
10308 
10309 TEST_F(audit_quiet_rename, quiet_on_parent_mount)
10310 {
10311 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10312 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10313 		       LANDLOCK_ACCESS_FS_REFER;
10314 	struct a_layer layer = {
10315 		.handled_access_fs = access,
10316 		.quiet_access_fs = access,
10317 		.rules = {
10318 			{
10319 				.path = dir_s2d1,
10320 				.access = 0,
10321 				.quiet = true,
10322 			},
10323 		},
10324 	};
10325 	struct audit_records records = {};
10326 
10327 	EXPECT_EQ(0, unlink(file2_s1d3));
10328 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10329 
10330 	ASSERT_EQ(-1, renameat(AT_FDCWD, bind_file1_s1d3, AT_FDCWD,
10331 			       bind_file2_s1d3));
10332 	ASSERT_EQ(EACCES, errno);
10333 
10334 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10335 	ASSERT_EQ(0, records.access);
10336 }
10337 
10338 TEST_F(audit_quiet_rename, quiet_behind_mountpoint_ignored)
10339 {
10340 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10341 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10342 		       LANDLOCK_ACCESS_FS_REFER;
10343 	struct a_layer layer = {
10344 		.handled_access_fs = access,
10345 		.quiet_access_fs = access,
10346 		.rules = {
10347 			{
10348 				.path = dir_s1d1,
10349 				.access = 0,
10350 				.quiet = true,
10351 			},
10352 		},
10353 	};
10354 	struct audit_records records = {};
10355 
10356 	EXPECT_EQ(0, unlink(file2_s1d3));
10357 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10358 
10359 	ASSERT_EQ(-1, renameat(AT_FDCWD, bind_file1_s1d3, AT_FDCWD,
10360 			       bind_file2_s1d3));
10361 	ASSERT_EQ(EACCES, errno);
10362 	ASSERT_EQ(0, matches_log_fs(_metadata, self->audit_fd,
10363 				    "fs\\.remove_file,fs\\.make_reg",
10364 				    bind_dir_s1d3));
10365 
10366 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10367 	ASSERT_EQ(0, records.access);
10368 }
10369 
10370 TEST_F(audit_quiet_rename, quiet_on_parent_mount_disconnected)
10371 {
10372 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10373 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10374 		       LANDLOCK_ACCESS_FS_REFER;
10375 	struct a_layer layer = {
10376 		.handled_access_fs = access,
10377 		.quiet_access_fs = access,
10378 		.rules = {
10379 			{
10380 				.path = dir_s2d1,
10381 				.access = 0,
10382 				.quiet = true,
10383 			},
10384 		},
10385 	};
10386 	struct audit_records records = {};
10387 	int bind_s1d3_fd;
10388 
10389 	EXPECT_EQ(0, unlink(file2_s1d3));
10390 
10391 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_DIRECTORY);
10392 	ASSERT_GE(bind_s1d3_fd, 0);
10393 
10394 	/* Make s1d3 disconnected. */
10395 	create_directory(_metadata, dir_s4d1);
10396 	ASSERT_EQ(0, renameat(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s4d2));
10397 
10398 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10399 
10400 	ASSERT_EQ(-1,
10401 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name));
10402 	ASSERT_EQ(EACCES, errno);
10403 
10404 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10405 	ASSERT_EQ(0, records.access);
10406 }
10407 
10408 TEST_F(audit_quiet_rename, quiet_behind_mountpoint_disconnected)
10409 {
10410 	__u64 access = LANDLOCK_ACCESS_FS_MAKE_REG |
10411 		       LANDLOCK_ACCESS_FS_REMOVE_FILE |
10412 		       LANDLOCK_ACCESS_FS_REFER;
10413 	struct a_layer layer = {
10414 		.handled_access_fs = access,
10415 		.quiet_access_fs = access,
10416 		.rules = {
10417 			{
10418 				.path = dir_s4d1,
10419 				.access = 0,
10420 				.quiet = true,
10421 			},
10422 		},
10423 	};
10424 	struct audit_records records = {};
10425 	int bind_s1d3_fd;
10426 
10427 	EXPECT_EQ(0, unlink(file2_s1d3));
10428 
10429 	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_DIRECTORY);
10430 	ASSERT_GE(bind_s1d3_fd, 0);
10431 
10432 	/* Make s1d3 disconnected. */
10433 	create_directory(_metadata, dir_s4d1);
10434 	ASSERT_EQ(0, renameat(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s4d2));
10435 
10436 	ASSERT_EQ(0, apply_a_layer(_metadata, &layer));
10437 
10438 	ASSERT_EQ(-1,
10439 		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name));
10440 	ASSERT_EQ(EACCES, errno);
10441 
10442 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
10443 	ASSERT_EQ(0, records.access);
10444 }
10445 
10446 /* clang-format off */
10447 FIXTURE(trace_layout1) {
10448 	/* clang-format on */
10449 	int tracefs_ok;
10450 };
10451 
10452 FIXTURE_SETUP(trace_layout1)
10453 {
10454 	struct stat st;
10455 
10456 	/*
10457 	 * Check tracefs availability before creating the layout, following the
10458 	 * layout3_fs pattern: skip before any layout creation to avoid leaving
10459 	 * stale TMP_DIR on skip.
10460 	 */
10461 	if (stat(TRACEFS_LANDLOCK_DIR, &st)) {
10462 		self->tracefs_ok = 0;
10463 		SKIP(return, "tracefs not available");
10464 	}
10465 	self->tracefs_ok = 1;
10466 
10467 	/* Isolate tracefs state (PID filter, event enables). */
10468 	set_cap(_metadata, CAP_SYS_ADMIN);
10469 	ASSERT_EQ(0, unshare(CLONE_NEWNS));
10470 	ASSERT_EQ(0, mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL));
10471 	clear_cap(_metadata, CAP_SYS_ADMIN);
10472 
10473 	prepare_layout(_metadata);
10474 	create_layout1(_metadata);
10475 
10476 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10477 	ASSERT_EQ(0, tracefs_fixture_setup());
10478 	ASSERT_EQ(0, tracefs_enable_event(TRACEFS_CHECK_RULE_FS_ENABLE, true));
10479 	ASSERT_EQ(0, tracefs_clear());
10480 	ASSERT_EQ(0, tracefs_set_pid_filter(getpid()));
10481 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10482 }
10483 
10484 FIXTURE_TEARDOWN_PARENT(trace_layout1)
10485 {
10486 	if (!self->tracefs_ok)
10487 		return;
10488 
10489 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10490 	tracefs_enable_event(TRACEFS_CHECK_RULE_FS_ENABLE, false);
10491 	tracefs_clear_pid_filter();
10492 	tracefs_fixture_teardown();
10493 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10494 
10495 	remove_layout1(_metadata);
10496 	cleanup_layout(_metadata);
10497 }
10498 
10499 /*
10500  * Verifies that check_rule_inode events include correct field values: domain,
10501  * dev, ino, access_request, and grants.  All values are verified against stat()
10502  * of the rule path on a deterministic tmpfs layout.
10503  */
10504 TEST_F(trace_layout1, check_rule_fs_fields)
10505 {
10506 	struct stat dir_stat;
10507 	char expected_dev[32];
10508 	char expected_ino[32];
10509 	char *buf;
10510 	char field[64];
10511 
10512 	if (!self->tracefs_ok)
10513 		SKIP(return, "tracefs not available");
10514 
10515 	ASSERT_EQ(0, stat(dir_s1d1, &dir_stat));
10516 	snprintf(expected_dev, sizeof(expected_dev), "%u:%u",
10517 		 major(dir_stat.st_dev), minor(dir_stat.st_dev));
10518 	snprintf(expected_ino, sizeof(expected_ino), "%lu", dir_stat.st_ino);
10519 
10520 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10521 	ASSERT_EQ(0, tracefs_clear());
10522 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10523 
10524 	sandbox_child_fs_access(_metadata, dir_s1d1,
10525 				LANDLOCK_ACCESS_FS_READ_DIR,
10526 				LANDLOCK_ACCESS_FS_READ_DIR, dir_s1d1);
10527 
10528 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10529 	buf = tracefs_read_trace();
10530 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10531 	ASSERT_NE(NULL, buf);
10532 
10533 	EXPECT_EQ(1,
10534 		  tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK)))
10535 	{
10536 		TH_LOG("Expected 1 check_rule_inode event\n%s", buf);
10537 	}
10538 
10539 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10540 					   "dev", field, sizeof(field)));
10541 	EXPECT_STREQ(expected_dev, field)
10542 	{
10543 		TH_LOG("Expected dev=%s, got %s", expected_dev, field);
10544 	}
10545 
10546 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10547 					   "ino", field, sizeof(field)));
10548 	EXPECT_STREQ(expected_ino, field)
10549 	{
10550 		TH_LOG("Expected ino=%s, got %s", expected_ino, field);
10551 	}
10552 
10553 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10554 					   "access_request", field,
10555 					   sizeof(field)));
10556 	EXPECT_STREQ("read_dir", field)
10557 	{
10558 		TH_LOG("Expected access_request=read_dir, got %s", field);
10559 	}
10560 
10561 	/*
10562 	 * The domain handles only READ_DIR, so the rule carries the
10563 	 * unhandled-rights padding; intersecting with the request leaves just
10564 	 * the requested read_dir (no padding, no hex).
10565 	 */
10566 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10567 					   "grants", field, sizeof(field)));
10568 	EXPECT_STREQ("{read_dir}", field)
10569 	{
10570 		TH_LOG("Expected grants={read_dir}, got %s", field);
10571 	}
10572 
10573 	free(buf);
10574 }
10575 
10576 /*
10577  * Verifies check_rule_inode behavior with multiple rules.  With rules at s1d1
10578  * and s1d2 (a child of s1d1), accessing s1d2 produces only 1 event because the
10579  * pathwalk short-circuits after the first rule fully unmasks the single layer.
10580  */
10581 TEST_F(trace_layout1, check_rule_fs_multiple_rules)
10582 {
10583 	pid_t pid;
10584 	int status;
10585 	char *buf;
10586 	int count;
10587 
10588 	if (!self->tracefs_ok)
10589 		SKIP(return, "tracefs not available");
10590 
10591 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10592 	ASSERT_EQ(0, tracefs_clear());
10593 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10594 
10595 	pid = fork();
10596 	ASSERT_LE(0, pid);
10597 
10598 	if (pid == 0) {
10599 		struct landlock_ruleset_attr attr = {
10600 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
10601 		};
10602 		struct landlock_path_beneath_attr path_beneath = {
10603 			.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
10604 		};
10605 		int ruleset_fd, fd;
10606 
10607 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10608 		if (ruleset_fd < 0)
10609 			_exit(1);
10610 
10611 		path_beneath.parent_fd =
10612 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10613 		if (path_beneath.parent_fd < 0)
10614 			_exit(1);
10615 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10616 				      &path_beneath, 0))
10617 			_exit(1);
10618 		close(path_beneath.parent_fd);
10619 
10620 		path_beneath.parent_fd =
10621 			open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
10622 		if (path_beneath.parent_fd < 0)
10623 			_exit(1);
10624 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10625 				      &path_beneath, 0))
10626 			_exit(1);
10627 		close(path_beneath.parent_fd);
10628 
10629 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10630 		if (landlock_restrict_self(ruleset_fd, 0))
10631 			_exit(1);
10632 		close(ruleset_fd);
10633 
10634 		fd = open(dir_s1d2, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
10635 		if (fd >= 0)
10636 			close(fd);
10637 		_exit(0);
10638 	}
10639 
10640 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10641 	ASSERT_TRUE(WIFEXITED(status));
10642 	EXPECT_EQ(0, WEXITSTATUS(status));
10643 
10644 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10645 	buf = tracefs_read_trace();
10646 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10647 	ASSERT_NE(NULL, buf);
10648 
10649 	/*
10650 	 * Only one check_rule_inode event: the rule on dir_s1d2 fully unmasks
10651 	 * the single layer, so the pathwalk short-circuits before reaching the
10652 	 * dir_s1d1 rule.
10653 	 */
10654 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10655 	EXPECT_EQ(1, count)
10656 	{
10657 		TH_LOG("Expected 1 check_rule_inode event, got %d\n%s", count,
10658 		       buf);
10659 	}
10660 
10661 	free(buf);
10662 }
10663 
10664 /*
10665  * Verifies the grants array is intersected with the request: a handled,
10666  * granted, but unrequested right (execute) is filtered out, leaving only the
10667  * requested read_dir.
10668  */
10669 TEST_F(trace_layout1, check_rule_fs_request_subset)
10670 {
10671 	char *buf;
10672 	char field[64];
10673 
10674 	if (!self->tracefs_ok)
10675 		SKIP(return, "tracefs not available");
10676 
10677 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10678 	ASSERT_EQ(0, tracefs_clear());
10679 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10680 
10681 	/*
10682 	 * Handle and grant READ_DIR|EXECUTE; the open only requests read_dir.
10683 	 */
10684 	sandbox_child_fs_access(
10685 		_metadata, dir_s1d1,
10686 		LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_EXECUTE,
10687 		LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_EXECUTE,
10688 		dir_s1d1);
10689 
10690 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10691 	buf = tracefs_read_trace();
10692 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10693 	ASSERT_NE(NULL, buf);
10694 
10695 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10696 					   "access_request", field,
10697 					   sizeof(field)));
10698 	EXPECT_STREQ("read_dir", field);
10699 
10700 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10701 					   "grants", field, sizeof(field)));
10702 	EXPECT_STREQ("{read_dir}", field);
10703 
10704 	free(buf);
10705 }
10706 
10707 /*
10708  * Verifies that the optional TRUNCATE access right, which hook_file_open()
10709  * speculatively evaluates on every open, appears in the access_request= and
10710  * grants= fields.  Opening file1_s1d1 read-only needs only read_file, but the
10711  * open hook also evaluates truncate; the domain handles and the rule grants
10712  * both, so the event reports access_request=read_file|truncate and
10713  * grants={read_file|truncate}, and the open is allowed.
10714  */
10715 TEST_F(trace_layout1, check_rule_fs_optional_access)
10716 {
10717 	pid_t pid;
10718 	int status;
10719 	char *buf;
10720 	char field[64];
10721 	int count;
10722 
10723 	if (!self->tracefs_ok)
10724 		SKIP(return, "tracefs not available");
10725 
10726 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10727 	ASSERT_EQ(0, tracefs_clear());
10728 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10729 
10730 	pid = fork();
10731 	ASSERT_LE(0, pid);
10732 
10733 	if (pid == 0) {
10734 		struct landlock_ruleset_attr attr = {
10735 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
10736 					     LANDLOCK_ACCESS_FS_TRUNCATE,
10737 		};
10738 		struct landlock_path_beneath_attr path_beneath = {
10739 			.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
10740 					  LANDLOCK_ACCESS_FS_TRUNCATE,
10741 		};
10742 		int ruleset_fd, fd;
10743 
10744 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10745 		if (ruleset_fd < 0)
10746 			_exit(1);
10747 
10748 		path_beneath.parent_fd =
10749 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10750 		if (path_beneath.parent_fd < 0)
10751 			_exit(1);
10752 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10753 				      &path_beneath, 0))
10754 			_exit(1);
10755 		close(path_beneath.parent_fd);
10756 
10757 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10758 		if (landlock_restrict_self(ruleset_fd, 0))
10759 			_exit(1);
10760 		close(ruleset_fd);
10761 
10762 		/* Read-only open needs only read_file; truncate is optional. */
10763 		fd = open(file1_s1d1, O_RDONLY | O_CLOEXEC);
10764 		if (fd < 0)
10765 			_exit(1);
10766 		close(fd);
10767 		_exit(0);
10768 	}
10769 
10770 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10771 	ASSERT_TRUE(WIFEXITED(status));
10772 	/* The open is allowed: the required read_file is granted. */
10773 	EXPECT_EQ(0, WEXITSTATUS(status));
10774 
10775 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10776 	buf = tracefs_read_trace();
10777 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10778 	ASSERT_NE(NULL, buf);
10779 
10780 	/* The rule at dir_s1d1 matches when opening file1_s1d1. */
10781 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10782 	EXPECT_EQ(1, count)
10783 	{
10784 		TH_LOG("Expected 1 check_rule_inode event, got %d\n%s", count,
10785 		       buf);
10786 	}
10787 
10788 	/* The open hook adds the optional truncate to the request. */
10789 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10790 					   "access_request", field,
10791 					   sizeof(field)));
10792 	EXPECT_STREQ("read_file|truncate", field);
10793 
10794 	/* The rule grants both, so truncate appears in the grants array. */
10795 	ASSERT_EQ(0, tracefs_extract_field(buf, REGEX_CHECK_RULE_FS(TRACE_TASK),
10796 					   "grants", field, sizeof(field)));
10797 	EXPECT_STREQ("{read_file|truncate}", field);
10798 
10799 	free(buf);
10800 }
10801 
10802 /*
10803  * Verifies that check_rule_inode fires for a rule matching the inode even when
10804  * it grants none of the requested rights, so the grants set is empty.  Landlock
10805  * cannot know a rule ignores the request before reading it, so the event is
10806  * still emitted (grants={}), which lets a tracer see that the rule matched.
10807  * The domain handles READ_DIR|EXECUTE, dir_s1d2 grants only EXECUTE and its
10808  * parent dir_s1d1 grants only READ_DIR.  Reading dir_s1d2 (requesting read_dir)
10809  * first matches the dir_s1d2 rule, which grants nothing requested (grants={});
10810  * walking up to dir_s1d1 then grants read_dir (grants={read_dir}) and allows
10811  * the access.
10812  */
10813 TEST_F(trace_layout1, check_rule_fs_empty_grant)
10814 {
10815 	pid_t pid;
10816 	int status;
10817 	char *buf;
10818 	int count;
10819 
10820 	if (!self->tracefs_ok)
10821 		SKIP(return, "tracefs not available");
10822 
10823 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10824 	ASSERT_EQ(0, tracefs_clear());
10825 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10826 
10827 	pid = fork();
10828 	ASSERT_LE(0, pid);
10829 
10830 	if (pid == 0) {
10831 		struct landlock_ruleset_attr attr = {
10832 			.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR |
10833 					     LANDLOCK_ACCESS_FS_EXECUTE,
10834 		};
10835 		struct landlock_path_beneath_attr path_beneath = {};
10836 		int ruleset_fd, fd;
10837 
10838 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
10839 		if (ruleset_fd < 0)
10840 			_exit(1);
10841 
10842 		/* Parent dir_s1d1 grants only READ_DIR. */
10843 		path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_DIR;
10844 		path_beneath.parent_fd =
10845 			open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
10846 		if (path_beneath.parent_fd < 0)
10847 			_exit(1);
10848 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10849 				      &path_beneath, 0))
10850 			_exit(1);
10851 		close(path_beneath.parent_fd);
10852 
10853 		/* Child dir_s1d2 grants only EXECUTE. */
10854 		path_beneath.allowed_access = LANDLOCK_ACCESS_FS_EXECUTE;
10855 		path_beneath.parent_fd =
10856 			open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
10857 		if (path_beneath.parent_fd < 0)
10858 			_exit(1);
10859 		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
10860 				      &path_beneath, 0))
10861 			_exit(1);
10862 		close(path_beneath.parent_fd);
10863 
10864 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
10865 		if (landlock_restrict_self(ruleset_fd, 0))
10866 			_exit(1);
10867 		close(ruleset_fd);
10868 
10869 		fd = open(dir_s1d2, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
10870 		if (fd < 0)
10871 			_exit(1);
10872 		close(fd);
10873 		_exit(0);
10874 	}
10875 
10876 	ASSERT_EQ(pid, waitpid(pid, &status, 0));
10877 	ASSERT_TRUE(WIFEXITED(status));
10878 	EXPECT_EQ(0, WEXITSTATUS(status));
10879 
10880 	set_cap(_metadata, CAP_DAC_OVERRIDE);
10881 	buf = tracefs_read_trace();
10882 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
10883 	ASSERT_NE(NULL, buf);
10884 
10885 	/*
10886 	 * dir_s1d2 (grants nothing requested) then dir_s1d1 (grants read_dir).
10887 	 */
10888 	count = tracefs_count_matches(buf, REGEX_CHECK_RULE_FS(TRACE_TASK));
10889 	EXPECT_EQ(2, count)
10890 	{
10891 		TH_LOG("Expected 2 check_rule_inode events, got %d\n%s", count,
10892 		       buf);
10893 	}
10894 
10895 	/* The dir_s1d2 rule matches the inode but grants none of read_dir. */
10896 	EXPECT_EQ(
10897 		1,
10898 		tracefs_count_matches(
10899 			buf,
10900 			TRACE_PREFIX(
10901 				TRACE_TASK) "landlock_check_rule_inode: domain=[0-9a-f]\\+ "
10902 					    "access_request=read_dir "
10903 					    "dev=[0-9]\\+:[0-9]\\+ ino=[0-9]\\+ "
10904 					    "grants={}$"))
10905 	{
10906 		TH_LOG("Expected a grants={} event\n%s", buf);
10907 	}
10908 
10909 	/* Walking up to dir_s1d1 grants the requested read_dir. */
10910 	EXPECT_EQ(
10911 		1,
10912 		tracefs_count_matches(
10913 			buf,
10914 			TRACE_PREFIX(
10915 				TRACE_TASK) "landlock_check_rule_inode: domain=[0-9a-f]\\+ "
10916 					    "access_request=read_dir "
10917 					    "dev=[0-9]\\+:[0-9]\\+ ino=[0-9]\\+ "
10918 					    "grants={read_dir}$"))
10919 	{
10920 		TH_LOG("Expected a grants={read_dir} event\n%s", buf);
10921 	}
10922 
10923 	free(buf);
10924 }
10925 
10926 TEST_HARNESS_MAIN
10927