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