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