xref: /linux/tools/testing/selftests/landlock/fs_test.c (revision 001821b0e79716c4e17c71d8e053a23599a7a508)
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/sendfile.h>
26 #include <sys/socket.h>
27 #include <sys/stat.h>
28 #include <sys/sysmacros.h>
29 #include <sys/un.h>
30 #include <sys/vfs.h>
31 #include <unistd.h>
32 
33 /*
34  * Intentionally included last to work around header conflict.
35  * See https://sourceware.org/glibc/wiki/Synchronizing_Headers.
36  */
37 #include <linux/fs.h>
38 
39 #include "common.h"
40 
41 #ifndef renameat2
42 int renameat2(int olddirfd, const char *oldpath, int newdirfd,
43 	      const char *newpath, unsigned int flags)
44 {
45 	return syscall(__NR_renameat2, olddirfd, oldpath, newdirfd, newpath,
46 		       flags);
47 }
48 #endif
49 
50 #ifndef RENAME_EXCHANGE
51 #define RENAME_EXCHANGE (1 << 1)
52 #endif
53 
54 #define TMP_DIR "tmp"
55 #define BINARY_PATH "./true"
56 
57 /* Paths (sibling number and depth) */
58 static const char dir_s1d1[] = TMP_DIR "/s1d1";
59 static const char file1_s1d1[] = TMP_DIR "/s1d1/f1";
60 static const char file2_s1d1[] = TMP_DIR "/s1d1/f2";
61 static const char dir_s1d2[] = TMP_DIR "/s1d1/s1d2";
62 static const char file1_s1d2[] = TMP_DIR "/s1d1/s1d2/f1";
63 static const char file2_s1d2[] = TMP_DIR "/s1d1/s1d2/f2";
64 static const char dir_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3";
65 static const char file1_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f1";
66 static const char file2_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f2";
67 
68 static const char dir_s2d1[] = TMP_DIR "/s2d1";
69 static const char file1_s2d1[] = TMP_DIR "/s2d1/f1";
70 static const char dir_s2d2[] = TMP_DIR "/s2d1/s2d2";
71 static const char file1_s2d2[] = TMP_DIR "/s2d1/s2d2/f1";
72 static const char dir_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3";
73 static const char file1_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f1";
74 static const char file2_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f2";
75 
76 static const char dir_s3d1[] = TMP_DIR "/s3d1";
77 static const char file1_s3d1[] = TMP_DIR "/s3d1/f1";
78 /* dir_s3d2 is a mount point. */
79 static const char dir_s3d2[] = TMP_DIR "/s3d1/s3d2";
80 static const char dir_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3";
81 
82 /*
83  * layout1 hierarchy:
84  *
85  * tmp
86  * ├── s1d1
87  * │   ├── f1
88  * │   ├── f2
89  * │   └── s1d2
90  * │       ├── f1
91  * │       ├── f2
92  * │       └── s1d3
93  * │           ├── f1
94  * │           └── f2
95  * ├── s2d1
96  * │   ├── f1
97  * │   └── s2d2
98  * │       ├── f1
99  * │       └── s2d3
100  * │           ├── f1
101  * │           └── f2
102  * └── s3d1
103  *     ├── f1
104  *     └── s3d2
105  *         └── s3d3
106  */
107 
108 static bool fgrep(FILE *const inf, const char *const str)
109 {
110 	char line[32];
111 	const int slen = strlen(str);
112 
113 	while (!feof(inf)) {
114 		if (!fgets(line, sizeof(line), inf))
115 			break;
116 		if (strncmp(line, str, slen))
117 			continue;
118 
119 		return true;
120 	}
121 
122 	return false;
123 }
124 
125 static bool supports_filesystem(const char *const filesystem)
126 {
127 	char str[32];
128 	int len;
129 	bool res = true;
130 	FILE *const inf = fopen("/proc/filesystems", "r");
131 
132 	/*
133 	 * Consider that the filesystem is supported if we cannot get the
134 	 * supported ones.
135 	 */
136 	if (!inf)
137 		return true;
138 
139 	/* filesystem can be null for bind mounts. */
140 	if (!filesystem)
141 		goto out;
142 
143 	len = snprintf(str, sizeof(str), "nodev\t%s\n", filesystem);
144 	if (len >= sizeof(str))
145 		/* Ignores too-long filesystem names. */
146 		goto out;
147 
148 	res = fgrep(inf, str);
149 
150 out:
151 	fclose(inf);
152 	return res;
153 }
154 
155 static bool cwd_matches_fs(unsigned int fs_magic)
156 {
157 	struct statfs statfs_buf;
158 
159 	if (!fs_magic)
160 		return true;
161 
162 	if (statfs(".", &statfs_buf))
163 		return true;
164 
165 	return statfs_buf.f_type == fs_magic;
166 }
167 
168 static void mkdir_parents(struct __test_metadata *const _metadata,
169 			  const char *const path)
170 {
171 	char *walker;
172 	const char *parent;
173 	int i, err;
174 
175 	ASSERT_NE(path[0], '\0');
176 	walker = strdup(path);
177 	ASSERT_NE(NULL, walker);
178 	parent = walker;
179 	for (i = 1; walker[i]; i++) {
180 		if (walker[i] != '/')
181 			continue;
182 		walker[i] = '\0';
183 		err = mkdir(parent, 0700);
184 		ASSERT_FALSE(err && errno != EEXIST)
185 		{
186 			TH_LOG("Failed to create directory \"%s\": %s", parent,
187 			       strerror(errno));
188 		}
189 		walker[i] = '/';
190 	}
191 	free(walker);
192 }
193 
194 static void create_directory(struct __test_metadata *const _metadata,
195 			     const char *const path)
196 {
197 	mkdir_parents(_metadata, path);
198 	ASSERT_EQ(0, mkdir(path, 0700))
199 	{
200 		TH_LOG("Failed to create directory \"%s\": %s", path,
201 		       strerror(errno));
202 	}
203 }
204 
205 static void create_file(struct __test_metadata *const _metadata,
206 			const char *const path)
207 {
208 	mkdir_parents(_metadata, path);
209 	ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0))
210 	{
211 		TH_LOG("Failed to create file \"%s\": %s", path,
212 		       strerror(errno));
213 	}
214 }
215 
216 static int remove_path(const char *const path)
217 {
218 	char *walker;
219 	int i, ret, err = 0;
220 
221 	walker = strdup(path);
222 	if (!walker) {
223 		err = ENOMEM;
224 		goto out;
225 	}
226 	if (unlink(path) && rmdir(path)) {
227 		if (errno != ENOENT && errno != ENOTDIR)
228 			err = errno;
229 		goto out;
230 	}
231 	for (i = strlen(walker); i > 0; i--) {
232 		if (walker[i] != '/')
233 			continue;
234 		walker[i] = '\0';
235 		ret = rmdir(walker);
236 		if (ret) {
237 			if (errno != ENOTEMPTY && errno != EBUSY)
238 				err = errno;
239 			goto out;
240 		}
241 		if (strcmp(walker, TMP_DIR) == 0)
242 			goto out;
243 	}
244 
245 out:
246 	free(walker);
247 	return err;
248 }
249 
250 struct mnt_opt {
251 	const char *const source;
252 	const char *const type;
253 	const unsigned long flags;
254 	const char *const data;
255 };
256 
257 #define MNT_TMP_DATA "size=4m,mode=700"
258 
259 static const struct mnt_opt mnt_tmp = {
260 	.type = "tmpfs",
261 	.data = MNT_TMP_DATA,
262 };
263 
264 static int mount_opt(const struct mnt_opt *const mnt, const char *const target)
265 {
266 	return mount(mnt->source ?: mnt->type, target, mnt->type, mnt->flags,
267 		     mnt->data);
268 }
269 
270 static void prepare_layout_opt(struct __test_metadata *const _metadata,
271 			       const struct mnt_opt *const mnt)
272 {
273 	disable_caps(_metadata);
274 	umask(0077);
275 	create_directory(_metadata, TMP_DIR);
276 
277 	/*
278 	 * Do not pollute the rest of the system: creates a private mount point
279 	 * for tests relying on pivot_root(2) and move_mount(2).
280 	 */
281 	set_cap(_metadata, CAP_SYS_ADMIN);
282 	ASSERT_EQ(0, unshare(CLONE_NEWNS | CLONE_NEWCGROUP));
283 	ASSERT_EQ(0, mount_opt(mnt, TMP_DIR))
284 	{
285 		TH_LOG("Failed to mount the %s filesystem: %s", mnt->type,
286 		       strerror(errno));
287 		/*
288 		 * FIXTURE_TEARDOWN() is not called when FIXTURE_SETUP()
289 		 * failed, so we need to explicitly do a minimal cleanup to
290 		 * avoid cascading errors with other tests that don't depend on
291 		 * the same filesystem.
292 		 */
293 		remove_path(TMP_DIR);
294 	}
295 	ASSERT_EQ(0, mount(NULL, TMP_DIR, NULL, MS_PRIVATE | MS_REC, NULL));
296 	clear_cap(_metadata, CAP_SYS_ADMIN);
297 }
298 
299 static void prepare_layout(struct __test_metadata *const _metadata)
300 {
301 	prepare_layout_opt(_metadata, &mnt_tmp);
302 }
303 
304 static void cleanup_layout(struct __test_metadata *const _metadata)
305 {
306 	set_cap(_metadata, CAP_SYS_ADMIN);
307 	if (umount(TMP_DIR)) {
308 		/*
309 		 * According to the test environment, the mount point of the
310 		 * current directory may be shared or not, which changes the
311 		 * visibility of the nested TMP_DIR mount point for the test's
312 		 * parent process doing this cleanup.
313 		 */
314 		ASSERT_EQ(EINVAL, errno);
315 	}
316 	clear_cap(_metadata, CAP_SYS_ADMIN);
317 	EXPECT_EQ(0, remove_path(TMP_DIR));
318 }
319 
320 /* clang-format off */
321 FIXTURE(layout0) {};
322 /* clang-format on */
323 
324 FIXTURE_SETUP(layout0)
325 {
326 	prepare_layout(_metadata);
327 }
328 
329 FIXTURE_TEARDOWN_PARENT(layout0)
330 {
331 	cleanup_layout(_metadata);
332 }
333 
334 static void create_layout1(struct __test_metadata *const _metadata)
335 {
336 	create_file(_metadata, file1_s1d1);
337 	create_file(_metadata, file1_s1d2);
338 	create_file(_metadata, file1_s1d3);
339 	create_file(_metadata, file2_s1d1);
340 	create_file(_metadata, file2_s1d2);
341 	create_file(_metadata, file2_s1d3);
342 
343 	create_file(_metadata, file1_s2d1);
344 	create_file(_metadata, file1_s2d2);
345 	create_file(_metadata, file1_s2d3);
346 	create_file(_metadata, file2_s2d3);
347 
348 	create_file(_metadata, file1_s3d1);
349 	create_directory(_metadata, dir_s3d2);
350 	set_cap(_metadata, CAP_SYS_ADMIN);
351 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
352 	clear_cap(_metadata, CAP_SYS_ADMIN);
353 
354 	ASSERT_EQ(0, mkdir(dir_s3d3, 0700));
355 }
356 
357 static void remove_layout1(struct __test_metadata *const _metadata)
358 {
359 	EXPECT_EQ(0, remove_path(file2_s1d3));
360 	EXPECT_EQ(0, remove_path(file2_s1d2));
361 	EXPECT_EQ(0, remove_path(file2_s1d1));
362 	EXPECT_EQ(0, remove_path(file1_s1d3));
363 	EXPECT_EQ(0, remove_path(file1_s1d2));
364 	EXPECT_EQ(0, remove_path(file1_s1d1));
365 	EXPECT_EQ(0, remove_path(dir_s1d3));
366 
367 	EXPECT_EQ(0, remove_path(file2_s2d3));
368 	EXPECT_EQ(0, remove_path(file1_s2d3));
369 	EXPECT_EQ(0, remove_path(file1_s2d2));
370 	EXPECT_EQ(0, remove_path(file1_s2d1));
371 	EXPECT_EQ(0, remove_path(dir_s2d2));
372 
373 	EXPECT_EQ(0, remove_path(file1_s3d1));
374 	EXPECT_EQ(0, remove_path(dir_s3d3));
375 	set_cap(_metadata, CAP_SYS_ADMIN);
376 	umount(dir_s3d2);
377 	clear_cap(_metadata, CAP_SYS_ADMIN);
378 	EXPECT_EQ(0, remove_path(dir_s3d2));
379 }
380 
381 /* clang-format off */
382 FIXTURE(layout1) {};
383 /* clang-format on */
384 
385 FIXTURE_SETUP(layout1)
386 {
387 	prepare_layout(_metadata);
388 
389 	create_layout1(_metadata);
390 }
391 
392 FIXTURE_TEARDOWN_PARENT(layout1)
393 {
394 	remove_layout1(_metadata);
395 
396 	cleanup_layout(_metadata);
397 }
398 
399 /*
400  * This helper enables to use the ASSERT_* macros and print the line number
401  * pointing to the test caller.
402  */
403 static int test_open_rel(const int dirfd, const char *const path,
404 			 const int flags)
405 {
406 	int fd;
407 
408 	/* Works with file and directories. */
409 	fd = openat(dirfd, path, flags | O_CLOEXEC);
410 	if (fd < 0)
411 		return errno;
412 	/*
413 	 * Mixing error codes from close(2) and open(2) should not lead to any
414 	 * (access type) confusion for this test.
415 	 */
416 	if (close(fd) != 0)
417 		return errno;
418 	return 0;
419 }
420 
421 static int test_open(const char *const path, const int flags)
422 {
423 	return test_open_rel(AT_FDCWD, path, flags);
424 }
425 
426 TEST_F_FORK(layout1, no_restriction)
427 {
428 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
429 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
430 	ASSERT_EQ(0, test_open(file2_s1d1, O_RDONLY));
431 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
432 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
433 	ASSERT_EQ(0, test_open(file2_s1d2, O_RDONLY));
434 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
435 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
436 
437 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
438 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
439 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
440 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
441 	ASSERT_EQ(0, test_open(dir_s2d3, O_RDONLY));
442 	ASSERT_EQ(0, test_open(file1_s2d3, O_RDONLY));
443 
444 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
445 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
446 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
447 }
448 
449 TEST_F_FORK(layout1, inval)
450 {
451 	struct landlock_path_beneath_attr path_beneath = {
452 		.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
453 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
454 		.parent_fd = -1,
455 	};
456 	struct landlock_ruleset_attr ruleset_attr = {
457 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
458 				     LANDLOCK_ACCESS_FS_WRITE_FILE,
459 	};
460 	int ruleset_fd;
461 
462 	path_beneath.parent_fd =
463 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
464 	ASSERT_LE(0, path_beneath.parent_fd);
465 
466 	ruleset_fd = open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
467 	ASSERT_LE(0, ruleset_fd);
468 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
469 					&path_beneath, 0));
470 	/* Returns EBADF because ruleset_fd is not a landlock-ruleset FD. */
471 	ASSERT_EQ(EBADF, errno);
472 	ASSERT_EQ(0, close(ruleset_fd));
473 
474 	ruleset_fd = open(dir_s1d1, O_DIRECTORY | O_CLOEXEC);
475 	ASSERT_LE(0, ruleset_fd);
476 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
477 					&path_beneath, 0));
478 	/* Returns EBADFD because ruleset_fd is not a valid ruleset. */
479 	ASSERT_EQ(EBADFD, errno);
480 	ASSERT_EQ(0, close(ruleset_fd));
481 
482 	/* Gets a real ruleset. */
483 	ruleset_fd =
484 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
485 	ASSERT_LE(0, ruleset_fd);
486 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
487 				       &path_beneath, 0));
488 	ASSERT_EQ(0, close(path_beneath.parent_fd));
489 
490 	/* Tests without O_PATH. */
491 	path_beneath.parent_fd = open(dir_s1d2, O_DIRECTORY | O_CLOEXEC);
492 	ASSERT_LE(0, path_beneath.parent_fd);
493 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
494 				       &path_beneath, 0));
495 	ASSERT_EQ(0, close(path_beneath.parent_fd));
496 
497 	/* Tests with a ruleset FD. */
498 	path_beneath.parent_fd = ruleset_fd;
499 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
500 					&path_beneath, 0));
501 	ASSERT_EQ(EBADFD, errno);
502 
503 	/* Checks unhandled allowed_access. */
504 	path_beneath.parent_fd =
505 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
506 	ASSERT_LE(0, path_beneath.parent_fd);
507 
508 	/* Test with legitimate values. */
509 	path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_EXECUTE;
510 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
511 					&path_beneath, 0));
512 	ASSERT_EQ(EINVAL, errno);
513 	path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_EXECUTE;
514 
515 	/* Tests with denied-by-default access right. */
516 	path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_REFER;
517 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
518 					&path_beneath, 0));
519 	ASSERT_EQ(EINVAL, errno);
520 	path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_REFER;
521 
522 	/* Test with unknown (64-bits) value. */
523 	path_beneath.allowed_access |= (1ULL << 60);
524 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
525 					&path_beneath, 0));
526 	ASSERT_EQ(EINVAL, errno);
527 	path_beneath.allowed_access &= ~(1ULL << 60);
528 
529 	/* Test with no access. */
530 	path_beneath.allowed_access = 0;
531 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
532 					&path_beneath, 0));
533 	ASSERT_EQ(ENOMSG, errno);
534 	path_beneath.allowed_access &= ~(1ULL << 60);
535 
536 	ASSERT_EQ(0, close(path_beneath.parent_fd));
537 
538 	/* Enforces the ruleset. */
539 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
540 	ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
541 
542 	ASSERT_EQ(0, close(ruleset_fd));
543 }
544 
545 /* clang-format off */
546 
547 #define ACCESS_FILE ( \
548 	LANDLOCK_ACCESS_FS_EXECUTE | \
549 	LANDLOCK_ACCESS_FS_WRITE_FILE | \
550 	LANDLOCK_ACCESS_FS_READ_FILE | \
551 	LANDLOCK_ACCESS_FS_TRUNCATE | \
552 	LANDLOCK_ACCESS_FS_IOCTL_DEV)
553 
554 #define ACCESS_LAST LANDLOCK_ACCESS_FS_IOCTL_DEV
555 
556 #define ACCESS_ALL ( \
557 	ACCESS_FILE | \
558 	LANDLOCK_ACCESS_FS_READ_DIR | \
559 	LANDLOCK_ACCESS_FS_REMOVE_DIR | \
560 	LANDLOCK_ACCESS_FS_REMOVE_FILE | \
561 	LANDLOCK_ACCESS_FS_MAKE_CHAR | \
562 	LANDLOCK_ACCESS_FS_MAKE_DIR | \
563 	LANDLOCK_ACCESS_FS_MAKE_REG | \
564 	LANDLOCK_ACCESS_FS_MAKE_SOCK | \
565 	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
566 	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
567 	LANDLOCK_ACCESS_FS_MAKE_SYM | \
568 	LANDLOCK_ACCESS_FS_REFER)
569 
570 /* clang-format on */
571 
572 TEST_F_FORK(layout1, file_and_dir_access_rights)
573 {
574 	__u64 access;
575 	int err;
576 	struct landlock_path_beneath_attr path_beneath_file = {},
577 					  path_beneath_dir = {};
578 	struct landlock_ruleset_attr ruleset_attr = {
579 		.handled_access_fs = ACCESS_ALL,
580 	};
581 	const int ruleset_fd =
582 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
583 
584 	ASSERT_LE(0, ruleset_fd);
585 
586 	/* Tests access rights for files. */
587 	path_beneath_file.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
588 	ASSERT_LE(0, path_beneath_file.parent_fd);
589 
590 	/* Tests access rights for directories. */
591 	path_beneath_dir.parent_fd =
592 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
593 	ASSERT_LE(0, path_beneath_dir.parent_fd);
594 
595 	for (access = 1; access <= ACCESS_LAST; access <<= 1) {
596 		path_beneath_dir.allowed_access = access;
597 		ASSERT_EQ(0, landlock_add_rule(ruleset_fd,
598 					       LANDLOCK_RULE_PATH_BENEATH,
599 					       &path_beneath_dir, 0));
600 
601 		path_beneath_file.allowed_access = access;
602 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
603 					&path_beneath_file, 0);
604 		if (access & ACCESS_FILE) {
605 			ASSERT_EQ(0, err);
606 		} else {
607 			ASSERT_EQ(-1, err);
608 			ASSERT_EQ(EINVAL, errno);
609 		}
610 	}
611 	ASSERT_EQ(0, close(path_beneath_file.parent_fd));
612 	ASSERT_EQ(0, close(path_beneath_dir.parent_fd));
613 	ASSERT_EQ(0, close(ruleset_fd));
614 }
615 
616 TEST_F_FORK(layout0, ruleset_with_unknown_access)
617 {
618 	__u64 access_mask;
619 
620 	for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST;
621 	     access_mask >>= 1) {
622 		struct landlock_ruleset_attr ruleset_attr = {
623 			.handled_access_fs = access_mask,
624 		};
625 
626 		ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr,
627 						      sizeof(ruleset_attr), 0));
628 		ASSERT_EQ(EINVAL, errno);
629 	}
630 }
631 
632 TEST_F_FORK(layout0, rule_with_unknown_access)
633 {
634 	__u64 access;
635 	struct landlock_path_beneath_attr path_beneath = {};
636 	const struct landlock_ruleset_attr ruleset_attr = {
637 		.handled_access_fs = ACCESS_ALL,
638 	};
639 	const int ruleset_fd =
640 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
641 
642 	ASSERT_LE(0, ruleset_fd);
643 
644 	path_beneath.parent_fd =
645 		open(TMP_DIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
646 	ASSERT_LE(0, path_beneath.parent_fd);
647 
648 	for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) {
649 		path_beneath.allowed_access = access;
650 		EXPECT_EQ(-1, landlock_add_rule(ruleset_fd,
651 						LANDLOCK_RULE_PATH_BENEATH,
652 						&path_beneath, 0));
653 		EXPECT_EQ(EINVAL, errno);
654 	}
655 	ASSERT_EQ(0, close(path_beneath.parent_fd));
656 	ASSERT_EQ(0, close(ruleset_fd));
657 }
658 
659 TEST_F_FORK(layout1, rule_with_unhandled_access)
660 {
661 	struct landlock_ruleset_attr ruleset_attr = {
662 		.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
663 	};
664 	struct landlock_path_beneath_attr path_beneath = {};
665 	int ruleset_fd;
666 	__u64 access;
667 
668 	ruleset_fd =
669 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
670 	ASSERT_LE(0, ruleset_fd);
671 
672 	path_beneath.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
673 	ASSERT_LE(0, path_beneath.parent_fd);
674 
675 	for (access = 1; access > 0; access <<= 1) {
676 		int err;
677 
678 		path_beneath.allowed_access = access;
679 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
680 					&path_beneath, 0);
681 		if (access == ruleset_attr.handled_access_fs) {
682 			EXPECT_EQ(0, err);
683 		} else {
684 			EXPECT_EQ(-1, err);
685 			EXPECT_EQ(EINVAL, errno);
686 		}
687 	}
688 
689 	EXPECT_EQ(0, close(path_beneath.parent_fd));
690 	EXPECT_EQ(0, close(ruleset_fd));
691 }
692 
693 static void add_path_beneath(struct __test_metadata *const _metadata,
694 			     const int ruleset_fd, const __u64 allowed_access,
695 			     const char *const path)
696 {
697 	struct landlock_path_beneath_attr path_beneath = {
698 		.allowed_access = allowed_access,
699 	};
700 
701 	path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC);
702 	ASSERT_LE(0, path_beneath.parent_fd)
703 	{
704 		TH_LOG("Failed to open directory \"%s\": %s", path,
705 		       strerror(errno));
706 	}
707 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
708 				       &path_beneath, 0))
709 	{
710 		TH_LOG("Failed to update the ruleset with \"%s\": %s", path,
711 		       strerror(errno));
712 	}
713 	ASSERT_EQ(0, close(path_beneath.parent_fd));
714 }
715 
716 struct rule {
717 	const char *path;
718 	__u64 access;
719 };
720 
721 /* clang-format off */
722 
723 #define ACCESS_RO ( \
724 	LANDLOCK_ACCESS_FS_READ_FILE | \
725 	LANDLOCK_ACCESS_FS_READ_DIR)
726 
727 #define ACCESS_RW ( \
728 	ACCESS_RO | \
729 	LANDLOCK_ACCESS_FS_WRITE_FILE)
730 
731 /* clang-format on */
732 
733 static int create_ruleset(struct __test_metadata *const _metadata,
734 			  const __u64 handled_access_fs,
735 			  const struct rule rules[])
736 {
737 	int ruleset_fd, i;
738 	struct landlock_ruleset_attr ruleset_attr = {
739 		.handled_access_fs = handled_access_fs,
740 	};
741 
742 	ASSERT_NE(NULL, rules)
743 	{
744 		TH_LOG("No rule list");
745 	}
746 	ASSERT_NE(NULL, rules[0].path)
747 	{
748 		TH_LOG("Empty rule list");
749 	}
750 
751 	ruleset_fd =
752 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
753 	ASSERT_LE(0, ruleset_fd)
754 	{
755 		TH_LOG("Failed to create a ruleset: %s", strerror(errno));
756 	}
757 
758 	for (i = 0; rules[i].path; i++) {
759 		if (!rules[i].access)
760 			continue;
761 
762 		add_path_beneath(_metadata, ruleset_fd, rules[i].access,
763 				 rules[i].path);
764 	}
765 	return ruleset_fd;
766 }
767 
768 TEST_F_FORK(layout0, proc_nsfs)
769 {
770 	const struct rule rules[] = {
771 		{
772 			.path = "/dev/null",
773 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
774 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
775 		},
776 		{},
777 	};
778 	struct landlock_path_beneath_attr path_beneath;
779 	const int ruleset_fd = create_ruleset(
780 		_metadata, rules[0].access | LANDLOCK_ACCESS_FS_READ_DIR,
781 		rules);
782 
783 	ASSERT_LE(0, ruleset_fd);
784 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
785 
786 	enforce_ruleset(_metadata, ruleset_fd);
787 
788 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
789 	ASSERT_EQ(EACCES, test_open("/dev", O_RDONLY));
790 	ASSERT_EQ(0, test_open("/dev/null", O_RDONLY));
791 	ASSERT_EQ(EACCES, test_open("/dev/full", O_RDONLY));
792 
793 	ASSERT_EQ(EACCES, test_open("/proc", O_RDONLY));
794 	ASSERT_EQ(EACCES, test_open("/proc/self", O_RDONLY));
795 	ASSERT_EQ(EACCES, test_open("/proc/self/ns", O_RDONLY));
796 	/*
797 	 * Because nsfs is an internal filesystem, /proc/self/ns/mnt is a
798 	 * disconnected path.  Such path cannot be identified and must then be
799 	 * allowed.
800 	 */
801 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
802 
803 	/*
804 	 * Checks that it is not possible to add nsfs-like filesystem
805 	 * references to a ruleset.
806 	 */
807 	path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
808 				      LANDLOCK_ACCESS_FS_WRITE_FILE,
809 	path_beneath.parent_fd = open("/proc/self/ns/mnt", O_PATH | O_CLOEXEC);
810 	ASSERT_LE(0, path_beneath.parent_fd);
811 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
812 					&path_beneath, 0));
813 	ASSERT_EQ(EBADFD, errno);
814 	ASSERT_EQ(0, close(path_beneath.parent_fd));
815 }
816 
817 TEST_F_FORK(layout0, unpriv)
818 {
819 	const struct rule rules[] = {
820 		{
821 			.path = TMP_DIR,
822 			.access = ACCESS_RO,
823 		},
824 		{},
825 	};
826 	int ruleset_fd;
827 
828 	drop_caps(_metadata);
829 
830 	ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules);
831 	ASSERT_LE(0, ruleset_fd);
832 	ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
833 	ASSERT_EQ(EPERM, errno);
834 
835 	/* enforce_ruleset() calls prctl(no_new_privs). */
836 	enforce_ruleset(_metadata, ruleset_fd);
837 	ASSERT_EQ(0, close(ruleset_fd));
838 }
839 
840 TEST_F_FORK(layout1, effective_access)
841 {
842 	const struct rule rules[] = {
843 		{
844 			.path = dir_s1d2,
845 			.access = ACCESS_RO,
846 		},
847 		{
848 			.path = file1_s2d2,
849 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
850 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
851 		},
852 		{},
853 	};
854 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
855 	char buf;
856 	int reg_fd;
857 
858 	ASSERT_LE(0, ruleset_fd);
859 	enforce_ruleset(_metadata, ruleset_fd);
860 	ASSERT_EQ(0, close(ruleset_fd));
861 
862 	/* Tests on a directory (with or without O_PATH). */
863 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
864 	ASSERT_EQ(0, test_open("/", O_RDONLY | O_PATH));
865 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
866 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_PATH));
867 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
868 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY | O_PATH));
869 
870 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
871 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
872 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
873 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
874 
875 	/* Tests on a file (with or without O_PATH). */
876 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY));
877 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_PATH));
878 
879 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
880 
881 	/* Checks effective read and write actions. */
882 	reg_fd = open(file1_s2d2, O_RDWR | O_CLOEXEC);
883 	ASSERT_LE(0, reg_fd);
884 	ASSERT_EQ(1, write(reg_fd, ".", 1));
885 	ASSERT_LE(0, lseek(reg_fd, 0, SEEK_SET));
886 	ASSERT_EQ(1, read(reg_fd, &buf, 1));
887 	ASSERT_EQ('.', buf);
888 	ASSERT_EQ(0, close(reg_fd));
889 
890 	/* Just in case, double-checks effective actions. */
891 	reg_fd = open(file1_s2d2, O_RDONLY | O_CLOEXEC);
892 	ASSERT_LE(0, reg_fd);
893 	ASSERT_EQ(-1, write(reg_fd, &buf, 1));
894 	ASSERT_EQ(EBADF, errno);
895 	ASSERT_EQ(0, close(reg_fd));
896 }
897 
898 TEST_F_FORK(layout1, unhandled_access)
899 {
900 	const struct rule rules[] = {
901 		{
902 			.path = dir_s1d2,
903 			.access = ACCESS_RO,
904 		},
905 		{},
906 	};
907 	/* Here, we only handle read accesses, not write accesses. */
908 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules);
909 
910 	ASSERT_LE(0, ruleset_fd);
911 	enforce_ruleset(_metadata, ruleset_fd);
912 	ASSERT_EQ(0, close(ruleset_fd));
913 
914 	/*
915 	 * Because the policy does not handle LANDLOCK_ACCESS_FS_WRITE_FILE,
916 	 * opening for write-only should be allowed, but not read-write.
917 	 */
918 	ASSERT_EQ(0, test_open(file1_s1d1, O_WRONLY));
919 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
920 
921 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
922 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
923 }
924 
925 TEST_F_FORK(layout1, ruleset_overlap)
926 {
927 	const struct rule rules[] = {
928 		/* These rules should be ORed among them. */
929 		{
930 			.path = dir_s1d2,
931 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
932 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
933 		},
934 		{
935 			.path = dir_s1d2,
936 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
937 				  LANDLOCK_ACCESS_FS_READ_DIR,
938 		},
939 		{},
940 	};
941 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
942 
943 	ASSERT_LE(0, ruleset_fd);
944 	enforce_ruleset(_metadata, ruleset_fd);
945 	ASSERT_EQ(0, close(ruleset_fd));
946 
947 	/* Checks s1d1 hierarchy. */
948 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
949 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
950 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
951 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
952 
953 	/* Checks s1d2 hierarchy. */
954 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
955 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
956 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
957 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
958 
959 	/* Checks s1d3 hierarchy. */
960 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
961 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
962 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
963 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
964 }
965 
966 TEST_F_FORK(layout1, layer_rule_unions)
967 {
968 	const struct rule layer1[] = {
969 		{
970 			.path = dir_s1d2,
971 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
972 		},
973 		/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
974 		{
975 			.path = dir_s1d3,
976 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
977 		},
978 		{},
979 	};
980 	const struct rule layer2[] = {
981 		/* Doesn't change anything from layer1. */
982 		{
983 			.path = dir_s1d2,
984 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
985 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
986 		},
987 		{},
988 	};
989 	const struct rule layer3[] = {
990 		/* Only allows write (but not read) to dir_s1d3. */
991 		{
992 			.path = dir_s1d2,
993 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
994 		},
995 		{},
996 	};
997 	int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1);
998 
999 	ASSERT_LE(0, ruleset_fd);
1000 	enforce_ruleset(_metadata, ruleset_fd);
1001 	ASSERT_EQ(0, close(ruleset_fd));
1002 
1003 	/* Checks s1d1 hierarchy with layer1. */
1004 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1005 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1006 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1007 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1008 
1009 	/* Checks s1d2 hierarchy with layer1. */
1010 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1011 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1012 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1013 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1014 
1015 	/* Checks s1d3 hierarchy with layer1. */
1016 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1017 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1018 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
1019 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1020 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1021 
1022 	/* Doesn't change anything from layer1. */
1023 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2);
1024 	ASSERT_LE(0, ruleset_fd);
1025 	enforce_ruleset(_metadata, ruleset_fd);
1026 	ASSERT_EQ(0, close(ruleset_fd));
1027 
1028 	/* Checks s1d1 hierarchy with layer2. */
1029 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1030 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1031 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1032 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1033 
1034 	/* Checks s1d2 hierarchy with layer2. */
1035 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1036 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1037 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1038 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1039 
1040 	/* Checks s1d3 hierarchy with layer2. */
1041 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1042 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1043 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
1044 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1045 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1046 
1047 	/* Only allows write (but not read) to dir_s1d3. */
1048 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3);
1049 	ASSERT_LE(0, ruleset_fd);
1050 	enforce_ruleset(_metadata, ruleset_fd);
1051 	ASSERT_EQ(0, close(ruleset_fd));
1052 
1053 	/* Checks s1d1 hierarchy with layer3. */
1054 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1055 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1056 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
1057 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1058 
1059 	/* Checks s1d2 hierarchy with layer3. */
1060 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
1061 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1062 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
1063 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1064 
1065 	/* Checks s1d3 hierarchy with layer3. */
1066 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
1067 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
1068 	/* dir_s1d3 should now deny READ_FILE and WRITE_FILE (O_RDWR). */
1069 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDWR));
1070 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1071 }
1072 
1073 TEST_F_FORK(layout1, non_overlapping_accesses)
1074 {
1075 	const struct rule layer1[] = {
1076 		{
1077 			.path = dir_s1d2,
1078 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
1079 		},
1080 		{},
1081 	};
1082 	const struct rule layer2[] = {
1083 		{
1084 			.path = dir_s1d3,
1085 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1086 		},
1087 		{},
1088 	};
1089 	int ruleset_fd;
1090 
1091 	ASSERT_EQ(0, unlink(file1_s1d1));
1092 	ASSERT_EQ(0, unlink(file1_s1d2));
1093 
1094 	ruleset_fd =
1095 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1);
1096 	ASSERT_LE(0, ruleset_fd);
1097 	enforce_ruleset(_metadata, ruleset_fd);
1098 	ASSERT_EQ(0, close(ruleset_fd));
1099 
1100 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
1101 	ASSERT_EQ(EACCES, errno);
1102 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
1103 	ASSERT_EQ(0, unlink(file1_s1d2));
1104 
1105 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE,
1106 				    layer2);
1107 	ASSERT_LE(0, ruleset_fd);
1108 	enforce_ruleset(_metadata, ruleset_fd);
1109 	ASSERT_EQ(0, close(ruleset_fd));
1110 
1111 	/* Unchanged accesses for file creation. */
1112 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
1113 	ASSERT_EQ(EACCES, errno);
1114 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
1115 
1116 	/* Checks file removing. */
1117 	ASSERT_EQ(-1, unlink(file1_s1d2));
1118 	ASSERT_EQ(EACCES, errno);
1119 	ASSERT_EQ(0, unlink(file1_s1d3));
1120 }
1121 
1122 TEST_F_FORK(layout1, interleaved_masked_accesses)
1123 {
1124 	/*
1125 	 * Checks overly restrictive rules:
1126 	 * layer 1: allows R   s1d1/s1d2/s1d3/file1
1127 	 * layer 2: allows RW  s1d1/s1d2/s1d3
1128 	 *          allows  W  s1d1/s1d2
1129 	 *          denies R   s1d1/s1d2
1130 	 * layer 3: allows R   s1d1
1131 	 * layer 4: allows R   s1d1/s1d2
1132 	 *          denies  W  s1d1/s1d2
1133 	 * layer 5: allows R   s1d1/s1d2
1134 	 * layer 6: allows   X ----
1135 	 * layer 7: allows  W  s1d1/s1d2
1136 	 *          denies R   s1d1/s1d2
1137 	 */
1138 	const struct rule layer1_read[] = {
1139 		/* Allows read access to file1_s1d3 with the first layer. */
1140 		{
1141 			.path = file1_s1d3,
1142 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1143 		},
1144 		{},
1145 	};
1146 	/* First rule with write restrictions. */
1147 	const struct rule layer2_read_write[] = {
1148 		/* Start by granting read-write access via its parent directory... */
1149 		{
1150 			.path = dir_s1d3,
1151 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1152 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
1153 		},
1154 		/* ...but also denies read access via its grandparent directory. */
1155 		{
1156 			.path = dir_s1d2,
1157 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1158 		},
1159 		{},
1160 	};
1161 	const struct rule layer3_read[] = {
1162 		/* Allows read access via its great-grandparent directory. */
1163 		{
1164 			.path = dir_s1d1,
1165 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1166 		},
1167 		{},
1168 	};
1169 	const struct rule layer4_read_write[] = {
1170 		/*
1171 		 * Try to confuse the deny access by denying write (but not
1172 		 * read) access via its grandparent directory.
1173 		 */
1174 		{
1175 			.path = dir_s1d2,
1176 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1177 		},
1178 		{},
1179 	};
1180 	const struct rule layer5_read[] = {
1181 		/*
1182 		 * Try to override layer2's deny read access by explicitly
1183 		 * allowing read access via file1_s1d3's grandparent.
1184 		 */
1185 		{
1186 			.path = dir_s1d2,
1187 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1188 		},
1189 		{},
1190 	};
1191 	const struct rule layer6_execute[] = {
1192 		/*
1193 		 * Restricts an unrelated file hierarchy with a new access
1194 		 * (non-overlapping) type.
1195 		 */
1196 		{
1197 			.path = dir_s2d1,
1198 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
1199 		},
1200 		{},
1201 	};
1202 	const struct rule layer7_read_write[] = {
1203 		/*
1204 		 * Finally, denies read access to file1_s1d3 via its
1205 		 * grandparent.
1206 		 */
1207 		{
1208 			.path = dir_s1d2,
1209 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1210 		},
1211 		{},
1212 	};
1213 	int ruleset_fd;
1214 
1215 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1216 				    layer1_read);
1217 	ASSERT_LE(0, ruleset_fd);
1218 	enforce_ruleset(_metadata, ruleset_fd);
1219 	ASSERT_EQ(0, close(ruleset_fd));
1220 
1221 	/* Checks that read access is granted for file1_s1d3 with layer 1. */
1222 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1223 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1224 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1225 
1226 	ruleset_fd = create_ruleset(_metadata,
1227 				    LANDLOCK_ACCESS_FS_READ_FILE |
1228 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1229 				    layer2_read_write);
1230 	ASSERT_LE(0, ruleset_fd);
1231 	enforce_ruleset(_metadata, ruleset_fd);
1232 	ASSERT_EQ(0, close(ruleset_fd));
1233 
1234 	/* Checks that previous access rights are unchanged with layer 2. */
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 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1240 				    layer3_read);
1241 	ASSERT_LE(0, ruleset_fd);
1242 	enforce_ruleset(_metadata, ruleset_fd);
1243 	ASSERT_EQ(0, close(ruleset_fd));
1244 
1245 	/* Checks that previous access rights are unchanged with layer 3. */
1246 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1247 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1248 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1249 
1250 	/* This time, denies write access for the file hierarchy. */
1251 	ruleset_fd = create_ruleset(_metadata,
1252 				    LANDLOCK_ACCESS_FS_READ_FILE |
1253 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1254 				    layer4_read_write);
1255 	ASSERT_LE(0, ruleset_fd);
1256 	enforce_ruleset(_metadata, ruleset_fd);
1257 	ASSERT_EQ(0, close(ruleset_fd));
1258 
1259 	/*
1260 	 * Checks that the only change with layer 4 is that write access is
1261 	 * denied.
1262 	 */
1263 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1264 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1265 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1266 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1267 
1268 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1269 				    layer5_read);
1270 	ASSERT_LE(0, ruleset_fd);
1271 	enforce_ruleset(_metadata, ruleset_fd);
1272 	ASSERT_EQ(0, close(ruleset_fd));
1273 
1274 	/* Checks that previous access rights are unchanged with layer 5. */
1275 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1276 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1277 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1278 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1279 
1280 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_EXECUTE,
1281 				    layer6_execute);
1282 	ASSERT_LE(0, ruleset_fd);
1283 	enforce_ruleset(_metadata, ruleset_fd);
1284 	ASSERT_EQ(0, close(ruleset_fd));
1285 
1286 	/* Checks that previous access rights are unchanged with layer 6. */
1287 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1288 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1289 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1290 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1291 
1292 	ruleset_fd = create_ruleset(_metadata,
1293 				    LANDLOCK_ACCESS_FS_READ_FILE |
1294 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1295 				    layer7_read_write);
1296 	ASSERT_LE(0, ruleset_fd);
1297 	enforce_ruleset(_metadata, ruleset_fd);
1298 	ASSERT_EQ(0, close(ruleset_fd));
1299 
1300 	/* Checks read access is now denied with layer 7. */
1301 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
1302 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1303 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1304 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1305 }
1306 
1307 TEST_F_FORK(layout1, inherit_subset)
1308 {
1309 	const struct rule rules[] = {
1310 		{
1311 			.path = dir_s1d2,
1312 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1313 				  LANDLOCK_ACCESS_FS_READ_DIR,
1314 		},
1315 		{},
1316 	};
1317 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1318 
1319 	ASSERT_LE(0, ruleset_fd);
1320 	enforce_ruleset(_metadata, ruleset_fd);
1321 
1322 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1323 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1324 
1325 	/* Write access is forbidden. */
1326 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1327 	/* Readdir access is allowed. */
1328 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1329 
1330 	/* Write access is forbidden. */
1331 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1332 	/* Readdir access is allowed. */
1333 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1334 
1335 	/*
1336 	 * Tests shared rule extension: the following rules should not grant
1337 	 * any new access, only remove some.  Once enforced, these rules are
1338 	 * ANDed with the previous ones.
1339 	 */
1340 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1341 			 dir_s1d2);
1342 	/*
1343 	 * According to ruleset_fd, dir_s1d2 should now have the
1344 	 * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE
1345 	 * access rights (even if this directory is opened a second time).
1346 	 * However, when enforcing this updated ruleset, the ruleset tied to
1347 	 * the current process (i.e. its domain) will still only have the
1348 	 * dir_s1d2 with LANDLOCK_ACCESS_FS_READ_FILE and
1349 	 * LANDLOCK_ACCESS_FS_READ_DIR accesses, but
1350 	 * LANDLOCK_ACCESS_FS_WRITE_FILE must not be allowed because it would
1351 	 * be a privilege escalation.
1352 	 */
1353 	enforce_ruleset(_metadata, ruleset_fd);
1354 
1355 	/* Same tests and results as above. */
1356 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1357 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1358 
1359 	/* It is still forbidden to write in file1_s1d2. */
1360 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1361 	/* Readdir access is still allowed. */
1362 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1363 
1364 	/* It is still forbidden to write in file1_s1d3. */
1365 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1366 	/* Readdir access is still allowed. */
1367 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1368 
1369 	/*
1370 	 * Try to get more privileges by adding new access rights to the parent
1371 	 * directory: dir_s1d1.
1372 	 */
1373 	add_path_beneath(_metadata, ruleset_fd, ACCESS_RW, dir_s1d1);
1374 	enforce_ruleset(_metadata, ruleset_fd);
1375 
1376 	/* Same tests and results as above. */
1377 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1378 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1379 
1380 	/* It is still forbidden to write in file1_s1d2. */
1381 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1382 	/* Readdir access is still allowed. */
1383 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1384 
1385 	/* It is still forbidden to write in file1_s1d3. */
1386 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1387 	/* Readdir access is still allowed. */
1388 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1389 
1390 	/*
1391 	 * Now, dir_s1d3 get a new rule tied to it, only allowing
1392 	 * LANDLOCK_ACCESS_FS_WRITE_FILE.  The (kernel internal) difference is
1393 	 * that there was no rule tied to it before.
1394 	 */
1395 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1396 			 dir_s1d3);
1397 	enforce_ruleset(_metadata, ruleset_fd);
1398 	ASSERT_EQ(0, close(ruleset_fd));
1399 
1400 	/*
1401 	 * Same tests and results as above, except for open(dir_s1d3) which is
1402 	 * now denied because the new rule mask the rule previously inherited
1403 	 * from dir_s1d2.
1404 	 */
1405 
1406 	/* Same tests and results as above. */
1407 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1408 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1409 
1410 	/* It is still forbidden to write in file1_s1d2. */
1411 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1412 	/* Readdir access is still allowed. */
1413 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1414 
1415 	/* It is still forbidden to write in file1_s1d3. */
1416 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1417 	/*
1418 	 * Readdir of dir_s1d3 is still allowed because of the OR policy inside
1419 	 * the same layer.
1420 	 */
1421 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1422 }
1423 
1424 TEST_F_FORK(layout1, inherit_superset)
1425 {
1426 	const struct rule rules[] = {
1427 		{
1428 			.path = dir_s1d3,
1429 			.access = ACCESS_RO,
1430 		},
1431 		{},
1432 	};
1433 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1434 
1435 	ASSERT_LE(0, ruleset_fd);
1436 	enforce_ruleset(_metadata, ruleset_fd);
1437 
1438 	/* Readdir access is denied for dir_s1d2. */
1439 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1440 	/* Readdir access is allowed for dir_s1d3. */
1441 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1442 	/* File access is allowed for file1_s1d3. */
1443 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1444 
1445 	/* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */
1446 	add_path_beneath(_metadata, ruleset_fd,
1447 			 LANDLOCK_ACCESS_FS_READ_FILE |
1448 				 LANDLOCK_ACCESS_FS_READ_DIR,
1449 			 dir_s1d2);
1450 	enforce_ruleset(_metadata, ruleset_fd);
1451 	ASSERT_EQ(0, close(ruleset_fd));
1452 
1453 	/* Readdir access is still denied for dir_s1d2. */
1454 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1455 	/* Readdir access is still allowed for dir_s1d3. */
1456 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1457 	/* File access is still allowed for file1_s1d3. */
1458 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1459 }
1460 
1461 TEST_F_FORK(layout0, max_layers)
1462 {
1463 	int i, err;
1464 	const struct rule rules[] = {
1465 		{
1466 			.path = TMP_DIR,
1467 			.access = ACCESS_RO,
1468 		},
1469 		{},
1470 	};
1471 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1472 
1473 	ASSERT_LE(0, ruleset_fd);
1474 	for (i = 0; i < 16; i++)
1475 		enforce_ruleset(_metadata, ruleset_fd);
1476 
1477 	for (i = 0; i < 2; i++) {
1478 		err = landlock_restrict_self(ruleset_fd, 0);
1479 		ASSERT_EQ(-1, err);
1480 		ASSERT_EQ(E2BIG, errno);
1481 	}
1482 	ASSERT_EQ(0, close(ruleset_fd));
1483 }
1484 
1485 TEST_F_FORK(layout1, empty_or_same_ruleset)
1486 {
1487 	struct landlock_ruleset_attr ruleset_attr = {};
1488 	int ruleset_fd;
1489 
1490 	/* Tests empty handled_access_fs. */
1491 	ruleset_fd =
1492 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1493 	ASSERT_LE(-1, ruleset_fd);
1494 	ASSERT_EQ(ENOMSG, errno);
1495 
1496 	/* Enforces policy which deny read access to all files. */
1497 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE;
1498 	ruleset_fd =
1499 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1500 	ASSERT_LE(0, ruleset_fd);
1501 	enforce_ruleset(_metadata, ruleset_fd);
1502 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1503 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1504 
1505 	/* Nests a policy which deny read access to all directories. */
1506 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR;
1507 	ruleset_fd =
1508 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1509 	ASSERT_LE(0, ruleset_fd);
1510 	enforce_ruleset(_metadata, ruleset_fd);
1511 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1512 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1513 
1514 	/* Enforces a second time with the same ruleset. */
1515 	enforce_ruleset(_metadata, ruleset_fd);
1516 	ASSERT_EQ(0, close(ruleset_fd));
1517 }
1518 
1519 TEST_F_FORK(layout1, rule_on_mountpoint)
1520 {
1521 	const struct rule rules[] = {
1522 		{
1523 			.path = dir_s1d1,
1524 			.access = ACCESS_RO,
1525 		},
1526 		{
1527 			/* dir_s3d2 is a mount point. */
1528 			.path = dir_s3d2,
1529 			.access = ACCESS_RO,
1530 		},
1531 		{},
1532 	};
1533 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1534 
1535 	ASSERT_LE(0, ruleset_fd);
1536 	enforce_ruleset(_metadata, ruleset_fd);
1537 	ASSERT_EQ(0, close(ruleset_fd));
1538 
1539 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1540 
1541 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1542 
1543 	ASSERT_EQ(EACCES, test_open(dir_s3d1, O_RDONLY));
1544 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1545 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1546 }
1547 
1548 TEST_F_FORK(layout1, rule_over_mountpoint)
1549 {
1550 	const struct rule rules[] = {
1551 		{
1552 			.path = dir_s1d1,
1553 			.access = ACCESS_RO,
1554 		},
1555 		{
1556 			/* dir_s3d2 is a mount point. */
1557 			.path = dir_s3d1,
1558 			.access = ACCESS_RO,
1559 		},
1560 		{},
1561 	};
1562 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1563 
1564 	ASSERT_LE(0, ruleset_fd);
1565 	enforce_ruleset(_metadata, ruleset_fd);
1566 	ASSERT_EQ(0, close(ruleset_fd));
1567 
1568 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1569 
1570 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1571 
1572 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
1573 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1574 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1575 }
1576 
1577 /*
1578  * This test verifies that we can apply a landlock rule on the root directory
1579  * (which might require special handling).
1580  */
1581 TEST_F_FORK(layout1, rule_over_root_allow_then_deny)
1582 {
1583 	struct rule rules[] = {
1584 		{
1585 			.path = "/",
1586 			.access = ACCESS_RO,
1587 		},
1588 		{},
1589 	};
1590 	int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1591 
1592 	ASSERT_LE(0, ruleset_fd);
1593 	enforce_ruleset(_metadata, ruleset_fd);
1594 	ASSERT_EQ(0, close(ruleset_fd));
1595 
1596 	/* Checks allowed access. */
1597 	ASSERT_EQ(0, test_open("/", O_RDONLY));
1598 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1599 
1600 	rules[0].access = LANDLOCK_ACCESS_FS_READ_FILE;
1601 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1602 	ASSERT_LE(0, ruleset_fd);
1603 	enforce_ruleset(_metadata, ruleset_fd);
1604 	ASSERT_EQ(0, close(ruleset_fd));
1605 
1606 	/* Checks denied access (on a directory). */
1607 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1608 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1609 }
1610 
1611 TEST_F_FORK(layout1, rule_over_root_deny)
1612 {
1613 	const struct rule rules[] = {
1614 		{
1615 			.path = "/",
1616 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1617 		},
1618 		{},
1619 	};
1620 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1621 
1622 	ASSERT_LE(0, ruleset_fd);
1623 	enforce_ruleset(_metadata, ruleset_fd);
1624 	ASSERT_EQ(0, close(ruleset_fd));
1625 
1626 	/* Checks denied access (on a directory). */
1627 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1628 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1629 }
1630 
1631 TEST_F_FORK(layout1, rule_inside_mount_ns)
1632 {
1633 	const struct rule rules[] = {
1634 		{
1635 			.path = "s3d3",
1636 			.access = ACCESS_RO,
1637 		},
1638 		{},
1639 	};
1640 	int ruleset_fd;
1641 
1642 	set_cap(_metadata, CAP_SYS_ADMIN);
1643 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3))
1644 	{
1645 		TH_LOG("Failed to pivot root: %s", strerror(errno));
1646 	};
1647 	ASSERT_EQ(0, chdir("/"));
1648 	clear_cap(_metadata, CAP_SYS_ADMIN);
1649 
1650 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1651 	ASSERT_LE(0, ruleset_fd);
1652 	enforce_ruleset(_metadata, ruleset_fd);
1653 	ASSERT_EQ(0, close(ruleset_fd));
1654 
1655 	ASSERT_EQ(0, test_open("s3d3", O_RDONLY));
1656 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1657 }
1658 
1659 TEST_F_FORK(layout1, mount_and_pivot)
1660 {
1661 	const struct rule rules[] = {
1662 		{
1663 			.path = dir_s3d2,
1664 			.access = ACCESS_RO,
1665 		},
1666 		{},
1667 	};
1668 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1669 
1670 	ASSERT_LE(0, ruleset_fd);
1671 	enforce_ruleset(_metadata, ruleset_fd);
1672 	ASSERT_EQ(0, close(ruleset_fd));
1673 
1674 	set_cap(_metadata, CAP_SYS_ADMIN);
1675 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
1676 	ASSERT_EQ(EPERM, errno);
1677 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1678 	ASSERT_EQ(EPERM, errno);
1679 	clear_cap(_metadata, CAP_SYS_ADMIN);
1680 }
1681 
1682 TEST_F_FORK(layout1, move_mount)
1683 {
1684 	const struct rule rules[] = {
1685 		{
1686 			.path = dir_s3d2,
1687 			.access = ACCESS_RO,
1688 		},
1689 		{},
1690 	};
1691 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1692 
1693 	ASSERT_LE(0, ruleset_fd);
1694 
1695 	set_cap(_metadata, CAP_SYS_ADMIN);
1696 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1697 			     dir_s1d2, 0))
1698 	{
1699 		TH_LOG("Failed to move mount: %s", strerror(errno));
1700 	}
1701 
1702 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1703 			     dir_s3d2, 0));
1704 	clear_cap(_metadata, CAP_SYS_ADMIN);
1705 
1706 	enforce_ruleset(_metadata, ruleset_fd);
1707 	ASSERT_EQ(0, close(ruleset_fd));
1708 
1709 	set_cap(_metadata, CAP_SYS_ADMIN);
1710 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1711 			      dir_s1d2, 0));
1712 	ASSERT_EQ(EPERM, errno);
1713 	clear_cap(_metadata, CAP_SYS_ADMIN);
1714 }
1715 
1716 TEST_F_FORK(layout1, topology_changes_with_net_only)
1717 {
1718 	const struct landlock_ruleset_attr ruleset_net = {
1719 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1720 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1721 	};
1722 	int ruleset_fd;
1723 
1724 	/* Add network restrictions. */
1725 	ruleset_fd =
1726 		landlock_create_ruleset(&ruleset_net, sizeof(ruleset_net), 0);
1727 	ASSERT_LE(0, ruleset_fd);
1728 	enforce_ruleset(_metadata, ruleset_fd);
1729 	ASSERT_EQ(0, close(ruleset_fd));
1730 
1731 	/* Mount, remount, move_mount, umount, and pivot_root checks. */
1732 	set_cap(_metadata, CAP_SYS_ADMIN);
1733 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s1d2));
1734 	ASSERT_EQ(0, mount(NULL, dir_s1d2, NULL, MS_PRIVATE | MS_REC, NULL));
1735 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1736 			     dir_s2d2, 0));
1737 	ASSERT_EQ(0, umount(dir_s2d2));
1738 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1739 	ASSERT_EQ(0, chdir("/"));
1740 	clear_cap(_metadata, CAP_SYS_ADMIN);
1741 }
1742 
1743 TEST_F_FORK(layout1, topology_changes_with_net_and_fs)
1744 {
1745 	const struct landlock_ruleset_attr ruleset_net_fs = {
1746 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
1747 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
1748 		.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
1749 	};
1750 	int ruleset_fd;
1751 
1752 	/* Add network and filesystem restrictions. */
1753 	ruleset_fd = landlock_create_ruleset(&ruleset_net_fs,
1754 					     sizeof(ruleset_net_fs), 0);
1755 	ASSERT_LE(0, ruleset_fd);
1756 	enforce_ruleset(_metadata, ruleset_fd);
1757 	ASSERT_EQ(0, close(ruleset_fd));
1758 
1759 	/* Mount, remount, move_mount, umount, and pivot_root checks. */
1760 	set_cap(_metadata, CAP_SYS_ADMIN);
1761 	ASSERT_EQ(-1, mount_opt(&mnt_tmp, dir_s1d2));
1762 	ASSERT_EQ(EPERM, errno);
1763 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_PRIVATE | MS_REC, NULL));
1764 	ASSERT_EQ(EPERM, errno);
1765 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1766 			      dir_s2d2, 0));
1767 	ASSERT_EQ(EPERM, errno);
1768 	ASSERT_EQ(-1, umount(dir_s3d2));
1769 	ASSERT_EQ(EPERM, errno);
1770 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1771 	ASSERT_EQ(EPERM, errno);
1772 	clear_cap(_metadata, CAP_SYS_ADMIN);
1773 }
1774 
1775 TEST_F_FORK(layout1, release_inodes)
1776 {
1777 	const struct rule rules[] = {
1778 		{
1779 			.path = dir_s1d1,
1780 			.access = ACCESS_RO,
1781 		},
1782 		{
1783 			.path = dir_s3d2,
1784 			.access = ACCESS_RO,
1785 		},
1786 		{
1787 			.path = dir_s3d3,
1788 			.access = ACCESS_RO,
1789 		},
1790 		{},
1791 	};
1792 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1793 
1794 	ASSERT_LE(0, ruleset_fd);
1795 	/* Unmount a file hierarchy while it is being used by a ruleset. */
1796 	set_cap(_metadata, CAP_SYS_ADMIN);
1797 	ASSERT_EQ(0, umount(dir_s3d2));
1798 	clear_cap(_metadata, CAP_SYS_ADMIN);
1799 
1800 	enforce_ruleset(_metadata, ruleset_fd);
1801 	ASSERT_EQ(0, close(ruleset_fd));
1802 
1803 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1804 	ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
1805 	/* This dir_s3d3 would not be allowed and does not exist anyway. */
1806 	ASSERT_EQ(ENOENT, test_open(dir_s3d3, O_RDONLY));
1807 }
1808 
1809 enum relative_access {
1810 	REL_OPEN,
1811 	REL_CHDIR,
1812 	REL_CHROOT_ONLY,
1813 	REL_CHROOT_CHDIR,
1814 };
1815 
1816 static void test_relative_path(struct __test_metadata *const _metadata,
1817 			       const enum relative_access rel)
1818 {
1819 	/*
1820 	 * Common layer to check that chroot doesn't ignore it (i.e. a chroot
1821 	 * is not a disconnected root directory).
1822 	 */
1823 	const struct rule layer1_base[] = {
1824 		{
1825 			.path = TMP_DIR,
1826 			.access = ACCESS_RO,
1827 		},
1828 		{},
1829 	};
1830 	const struct rule layer2_subs[] = {
1831 		{
1832 			.path = dir_s1d2,
1833 			.access = ACCESS_RO,
1834 		},
1835 		{
1836 			.path = dir_s2d2,
1837 			.access = ACCESS_RO,
1838 		},
1839 		{},
1840 	};
1841 	int dirfd, ruleset_fd;
1842 
1843 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
1844 	ASSERT_LE(0, ruleset_fd);
1845 	enforce_ruleset(_metadata, ruleset_fd);
1846 	ASSERT_EQ(0, close(ruleset_fd));
1847 
1848 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_subs);
1849 
1850 	ASSERT_LE(0, ruleset_fd);
1851 	switch (rel) {
1852 	case REL_OPEN:
1853 	case REL_CHDIR:
1854 		break;
1855 	case REL_CHROOT_ONLY:
1856 		ASSERT_EQ(0, chdir(dir_s2d2));
1857 		break;
1858 	case REL_CHROOT_CHDIR:
1859 		ASSERT_EQ(0, chdir(dir_s1d2));
1860 		break;
1861 	default:
1862 		ASSERT_TRUE(false);
1863 		return;
1864 	}
1865 
1866 	set_cap(_metadata, CAP_SYS_CHROOT);
1867 	enforce_ruleset(_metadata, ruleset_fd);
1868 
1869 	switch (rel) {
1870 	case REL_OPEN:
1871 		dirfd = open(dir_s1d2, O_DIRECTORY);
1872 		ASSERT_LE(0, dirfd);
1873 		break;
1874 	case REL_CHDIR:
1875 		ASSERT_EQ(0, chdir(dir_s1d2));
1876 		dirfd = AT_FDCWD;
1877 		break;
1878 	case REL_CHROOT_ONLY:
1879 		/* Do chroot into dir_s1d2 (relative to dir_s2d2). */
1880 		ASSERT_EQ(0, chroot("../../s1d1/s1d2"))
1881 		{
1882 			TH_LOG("Failed to chroot: %s", strerror(errno));
1883 		}
1884 		dirfd = AT_FDCWD;
1885 		break;
1886 	case REL_CHROOT_CHDIR:
1887 		/* Do chroot into dir_s1d2. */
1888 		ASSERT_EQ(0, chroot("."))
1889 		{
1890 			TH_LOG("Failed to chroot: %s", strerror(errno));
1891 		}
1892 		dirfd = AT_FDCWD;
1893 		break;
1894 	}
1895 
1896 	ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES,
1897 		  test_open_rel(dirfd, "..", O_RDONLY));
1898 	ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY));
1899 
1900 	if (rel == REL_CHROOT_ONLY) {
1901 		/* The current directory is dir_s2d2. */
1902 		ASSERT_EQ(0, test_open_rel(dirfd, "./s2d3", O_RDONLY));
1903 	} else {
1904 		/* The current directory is dir_s1d2. */
1905 		ASSERT_EQ(0, test_open_rel(dirfd, "./s1d3", O_RDONLY));
1906 	}
1907 
1908 	if (rel == REL_CHROOT_ONLY || rel == REL_CHROOT_CHDIR) {
1909 		/* Checks the root dir_s1d2. */
1910 		ASSERT_EQ(0, test_open_rel(dirfd, "/..", O_RDONLY));
1911 		ASSERT_EQ(0, test_open_rel(dirfd, "/", O_RDONLY));
1912 		ASSERT_EQ(0, test_open_rel(dirfd, "/f1", O_RDONLY));
1913 		ASSERT_EQ(0, test_open_rel(dirfd, "/s1d3", O_RDONLY));
1914 	}
1915 
1916 	if (rel != REL_CHROOT_CHDIR) {
1917 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY));
1918 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY));
1919 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3",
1920 					   O_RDONLY));
1921 
1922 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY));
1923 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY));
1924 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3",
1925 					   O_RDONLY));
1926 	}
1927 
1928 	if (rel == REL_OPEN)
1929 		ASSERT_EQ(0, close(dirfd));
1930 	ASSERT_EQ(0, close(ruleset_fd));
1931 }
1932 
1933 TEST_F_FORK(layout1, relative_open)
1934 {
1935 	test_relative_path(_metadata, REL_OPEN);
1936 }
1937 
1938 TEST_F_FORK(layout1, relative_chdir)
1939 {
1940 	test_relative_path(_metadata, REL_CHDIR);
1941 }
1942 
1943 TEST_F_FORK(layout1, relative_chroot_only)
1944 {
1945 	test_relative_path(_metadata, REL_CHROOT_ONLY);
1946 }
1947 
1948 TEST_F_FORK(layout1, relative_chroot_chdir)
1949 {
1950 	test_relative_path(_metadata, REL_CHROOT_CHDIR);
1951 }
1952 
1953 static void copy_binary(struct __test_metadata *const _metadata,
1954 			const char *const dst_path)
1955 {
1956 	int dst_fd, src_fd;
1957 	struct stat statbuf;
1958 
1959 	dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC);
1960 	ASSERT_LE(0, dst_fd)
1961 	{
1962 		TH_LOG("Failed to open \"%s\": %s", dst_path, strerror(errno));
1963 	}
1964 	src_fd = open(BINARY_PATH, O_RDONLY | O_CLOEXEC);
1965 	ASSERT_LE(0, src_fd)
1966 	{
1967 		TH_LOG("Failed to open \"" BINARY_PATH "\": %s",
1968 		       strerror(errno));
1969 	}
1970 	ASSERT_EQ(0, fstat(src_fd, &statbuf));
1971 	ASSERT_EQ(statbuf.st_size,
1972 		  sendfile(dst_fd, src_fd, 0, statbuf.st_size));
1973 	ASSERT_EQ(0, close(src_fd));
1974 	ASSERT_EQ(0, close(dst_fd));
1975 }
1976 
1977 static void test_execute(struct __test_metadata *const _metadata, const int err,
1978 			 const char *const path)
1979 {
1980 	int status;
1981 	char *const argv[] = { (char *)path, NULL };
1982 	const pid_t child = fork();
1983 
1984 	ASSERT_LE(0, child);
1985 	if (child == 0) {
1986 		ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL))
1987 		{
1988 			TH_LOG("Failed to execute \"%s\": %s", path,
1989 			       strerror(errno));
1990 		};
1991 		ASSERT_EQ(err, errno);
1992 		_exit(__test_passed(_metadata) ? 2 : 1);
1993 		return;
1994 	}
1995 	ASSERT_EQ(child, waitpid(child, &status, 0));
1996 	ASSERT_EQ(1, WIFEXITED(status));
1997 	ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status))
1998 	{
1999 		TH_LOG("Unexpected return code for \"%s\": %s", path,
2000 		       strerror(errno));
2001 	};
2002 }
2003 
2004 TEST_F_FORK(layout1, execute)
2005 {
2006 	const struct rule rules[] = {
2007 		{
2008 			.path = dir_s1d2,
2009 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
2010 		},
2011 		{},
2012 	};
2013 	const int ruleset_fd =
2014 		create_ruleset(_metadata, rules[0].access, rules);
2015 
2016 	ASSERT_LE(0, ruleset_fd);
2017 	copy_binary(_metadata, file1_s1d1);
2018 	copy_binary(_metadata, file1_s1d2);
2019 	copy_binary(_metadata, file1_s1d3);
2020 
2021 	enforce_ruleset(_metadata, ruleset_fd);
2022 	ASSERT_EQ(0, close(ruleset_fd));
2023 
2024 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
2025 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2026 	test_execute(_metadata, EACCES, file1_s1d1);
2027 
2028 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
2029 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2030 	test_execute(_metadata, 0, file1_s1d2);
2031 
2032 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
2033 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2034 	test_execute(_metadata, 0, file1_s1d3);
2035 }
2036 
2037 TEST_F_FORK(layout1, link)
2038 {
2039 	const struct rule layer1[] = {
2040 		{
2041 			.path = dir_s1d2,
2042 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2043 		},
2044 		{},
2045 	};
2046 	const struct rule layer2[] = {
2047 		{
2048 			.path = dir_s1d3,
2049 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2050 		},
2051 		{},
2052 	};
2053 	int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
2054 
2055 	ASSERT_LE(0, ruleset_fd);
2056 
2057 	ASSERT_EQ(0, unlink(file1_s1d1));
2058 	ASSERT_EQ(0, unlink(file1_s1d2));
2059 	ASSERT_EQ(0, unlink(file1_s1d3));
2060 
2061 	enforce_ruleset(_metadata, ruleset_fd);
2062 	ASSERT_EQ(0, close(ruleset_fd));
2063 
2064 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2065 	ASSERT_EQ(EACCES, errno);
2066 
2067 	/* Denies linking because of reparenting. */
2068 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
2069 	ASSERT_EQ(EXDEV, errno);
2070 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
2071 	ASSERT_EQ(EXDEV, errno);
2072 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
2073 	ASSERT_EQ(EXDEV, errno);
2074 
2075 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
2076 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
2077 
2078 	/* Prepares for next unlinks. */
2079 	ASSERT_EQ(0, unlink(file2_s1d2));
2080 	ASSERT_EQ(0, unlink(file2_s1d3));
2081 
2082 	ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
2083 	ASSERT_LE(0, ruleset_fd);
2084 	enforce_ruleset(_metadata, ruleset_fd);
2085 	ASSERT_EQ(0, close(ruleset_fd));
2086 
2087 	/* Checks that linkind doesn't require the ability to delete a file. */
2088 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
2089 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
2090 }
2091 
2092 static int test_rename(const char *const oldpath, const char *const newpath)
2093 {
2094 	if (rename(oldpath, newpath))
2095 		return errno;
2096 	return 0;
2097 }
2098 
2099 static int test_exchange(const char *const oldpath, const char *const newpath)
2100 {
2101 	if (renameat2(AT_FDCWD, oldpath, AT_FDCWD, newpath, RENAME_EXCHANGE))
2102 		return errno;
2103 	return 0;
2104 }
2105 
2106 TEST_F_FORK(layout1, rename_file)
2107 {
2108 	const struct rule rules[] = {
2109 		{
2110 			.path = dir_s1d3,
2111 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2112 		},
2113 		{
2114 			.path = dir_s2d2,
2115 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2116 		},
2117 		{},
2118 	};
2119 	const int ruleset_fd =
2120 		create_ruleset(_metadata, rules[0].access, rules);
2121 
2122 	ASSERT_LE(0, ruleset_fd);
2123 
2124 	ASSERT_EQ(0, unlink(file1_s1d2));
2125 
2126 	enforce_ruleset(_metadata, ruleset_fd);
2127 	ASSERT_EQ(0, close(ruleset_fd));
2128 
2129 	/*
2130 	 * Tries to replace a file, from a directory that allows file removal,
2131 	 * but to a different directory (which also allows file removal).
2132 	 */
2133 	ASSERT_EQ(-1, rename(file1_s2d3, file1_s1d3));
2134 	ASSERT_EQ(EXDEV, errno);
2135 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d3,
2136 				RENAME_EXCHANGE));
2137 	ASSERT_EQ(EXDEV, errno);
2138 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
2139 				RENAME_EXCHANGE));
2140 	ASSERT_EQ(EXDEV, errno);
2141 
2142 	/*
2143 	 * Tries to replace a file, from a directory that denies file removal,
2144 	 * to a different directory (which allows file removal).
2145 	 */
2146 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2147 	ASSERT_EQ(EACCES, errno);
2148 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file1_s1d3,
2149 				RENAME_EXCHANGE));
2150 	ASSERT_EQ(EACCES, errno);
2151 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s1d3,
2152 				RENAME_EXCHANGE));
2153 	ASSERT_EQ(EXDEV, errno);
2154 
2155 	/* Exchanges files and directories that partially allow removal. */
2156 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
2157 				RENAME_EXCHANGE));
2158 	ASSERT_EQ(EACCES, errno);
2159 	/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
2160 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
2161 	ASSERT_EQ(EACCES, errno);
2162 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
2163 				RENAME_EXCHANGE));
2164 	ASSERT_EQ(EACCES, errno);
2165 	/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
2166 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
2167 	ASSERT_EQ(EACCES, errno);
2168 
2169 	/* Renames files with different parents. */
2170 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
2171 	ASSERT_EQ(EXDEV, errno);
2172 	ASSERT_EQ(0, unlink(file1_s1d3));
2173 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2174 	ASSERT_EQ(EACCES, errno);
2175 
2176 	/* Exchanges and renames files with same parent. */
2177 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3,
2178 			       RENAME_EXCHANGE));
2179 	ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3));
2180 
2181 	/* Exchanges files and directories with same parent, twice. */
2182 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
2183 			       RENAME_EXCHANGE));
2184 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
2185 			       RENAME_EXCHANGE));
2186 }
2187 
2188 TEST_F_FORK(layout1, rename_dir)
2189 {
2190 	const struct rule rules[] = {
2191 		{
2192 			.path = dir_s1d2,
2193 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
2194 		},
2195 		{
2196 			.path = dir_s2d1,
2197 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
2198 		},
2199 		{},
2200 	};
2201 	const int ruleset_fd =
2202 		create_ruleset(_metadata, rules[0].access, rules);
2203 
2204 	ASSERT_LE(0, ruleset_fd);
2205 
2206 	/* Empties dir_s1d3 to allow renaming. */
2207 	ASSERT_EQ(0, unlink(file1_s1d3));
2208 	ASSERT_EQ(0, unlink(file2_s1d3));
2209 
2210 	enforce_ruleset(_metadata, ruleset_fd);
2211 	ASSERT_EQ(0, close(ruleset_fd));
2212 
2213 	/* Exchanges and renames directory to a different parent. */
2214 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
2215 				RENAME_EXCHANGE));
2216 	ASSERT_EQ(EXDEV, errno);
2217 	ASSERT_EQ(-1, rename(dir_s2d3, dir_s1d3));
2218 	ASSERT_EQ(EXDEV, errno);
2219 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
2220 				RENAME_EXCHANGE));
2221 	ASSERT_EQ(EXDEV, errno);
2222 
2223 	/*
2224 	 * Exchanges directory to the same parent, which doesn't allow
2225 	 * directory removal.
2226 	 */
2227 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
2228 				RENAME_EXCHANGE));
2229 	ASSERT_EQ(EACCES, errno);
2230 	/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
2231 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
2232 	ASSERT_EQ(EACCES, errno);
2233 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
2234 				RENAME_EXCHANGE));
2235 	ASSERT_EQ(EACCES, errno);
2236 	/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
2237 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
2238 	ASSERT_EQ(EACCES, errno);
2239 
2240 	/*
2241 	 * Exchanges and renames directory to the same parent, which allows
2242 	 * directory removal.
2243 	 */
2244 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2,
2245 			       RENAME_EXCHANGE));
2246 	ASSERT_EQ(0, unlink(dir_s1d3));
2247 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
2248 	ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3));
2249 	ASSERT_EQ(0, rmdir(dir_s1d3));
2250 }
2251 
2252 TEST_F_FORK(layout1, reparent_refer)
2253 {
2254 	const struct rule layer1[] = {
2255 		{
2256 			.path = dir_s1d2,
2257 			.access = LANDLOCK_ACCESS_FS_REFER,
2258 		},
2259 		{
2260 			.path = dir_s2d2,
2261 			.access = LANDLOCK_ACCESS_FS_REFER,
2262 		},
2263 		{},
2264 	};
2265 	int ruleset_fd =
2266 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REFER, layer1);
2267 
2268 	ASSERT_LE(0, ruleset_fd);
2269 	enforce_ruleset(_metadata, ruleset_fd);
2270 	ASSERT_EQ(0, close(ruleset_fd));
2271 
2272 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d1));
2273 	ASSERT_EQ(EXDEV, errno);
2274 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d2));
2275 	ASSERT_EQ(EXDEV, errno);
2276 	ASSERT_EQ(-1, rename(dir_s1d2, dir_s2d3));
2277 	ASSERT_EQ(EXDEV, errno);
2278 
2279 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d1));
2280 	ASSERT_EQ(EXDEV, errno);
2281 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d2));
2282 	ASSERT_EQ(EXDEV, errno);
2283 	/*
2284 	 * Moving should only be allowed when the source and the destination
2285 	 * parent directory have REFER.
2286 	 */
2287 	ASSERT_EQ(-1, rename(dir_s1d3, dir_s2d3));
2288 	ASSERT_EQ(ENOTEMPTY, errno);
2289 	ASSERT_EQ(0, unlink(file1_s2d3));
2290 	ASSERT_EQ(0, unlink(file2_s2d3));
2291 	ASSERT_EQ(0, rename(dir_s1d3, dir_s2d3));
2292 }
2293 
2294 /* Checks renames beneath dir_s1d1. */
2295 static void refer_denied_by_default(struct __test_metadata *const _metadata,
2296 				    const struct rule layer1[],
2297 				    const int layer1_err,
2298 				    const struct rule layer2[])
2299 {
2300 	int ruleset_fd;
2301 
2302 	ASSERT_EQ(0, unlink(file1_s1d2));
2303 
2304 	ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
2305 	ASSERT_LE(0, ruleset_fd);
2306 	enforce_ruleset(_metadata, ruleset_fd);
2307 	ASSERT_EQ(0, close(ruleset_fd));
2308 
2309 	/*
2310 	 * If the first layer handles LANDLOCK_ACCESS_FS_REFER (according to
2311 	 * layer1_err), then it allows some different-parent renames and links.
2312 	 */
2313 	ASSERT_EQ(layer1_err, test_rename(file1_s1d1, file1_s1d2));
2314 	if (layer1_err == 0)
2315 		ASSERT_EQ(layer1_err, test_rename(file1_s1d2, file1_s1d1));
2316 	ASSERT_EQ(layer1_err, test_exchange(file2_s1d1, file2_s1d2));
2317 	ASSERT_EQ(layer1_err, test_exchange(file2_s1d2, file2_s1d1));
2318 
2319 	ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
2320 	ASSERT_LE(0, ruleset_fd);
2321 	enforce_ruleset(_metadata, ruleset_fd);
2322 	ASSERT_EQ(0, close(ruleset_fd));
2323 
2324 	/*
2325 	 * Now, either the first or the second layer does not handle
2326 	 * LANDLOCK_ACCESS_FS_REFER, which means that any different-parent
2327 	 * renames and links are denied, thus making the layer handling
2328 	 * LANDLOCK_ACCESS_FS_REFER null and void.
2329 	 */
2330 	ASSERT_EQ(EXDEV, test_rename(file1_s1d1, file1_s1d2));
2331 	ASSERT_EQ(EXDEV, test_exchange(file2_s1d1, file2_s1d2));
2332 	ASSERT_EQ(EXDEV, test_exchange(file2_s1d2, file2_s1d1));
2333 }
2334 
2335 const struct rule layer_dir_s1d1_refer[] = {
2336 	{
2337 		.path = dir_s1d1,
2338 		.access = LANDLOCK_ACCESS_FS_REFER,
2339 	},
2340 	{},
2341 };
2342 
2343 const struct rule layer_dir_s1d1_execute[] = {
2344 	{
2345 		/* Matches a parent directory. */
2346 		.path = dir_s1d1,
2347 		.access = LANDLOCK_ACCESS_FS_EXECUTE,
2348 	},
2349 	{},
2350 };
2351 
2352 const struct rule layer_dir_s2d1_execute[] = {
2353 	{
2354 		/* Does not match a parent directory. */
2355 		.path = dir_s2d1,
2356 		.access = LANDLOCK_ACCESS_FS_EXECUTE,
2357 	},
2358 	{},
2359 };
2360 
2361 /*
2362  * Tests precedence over renames: denied by default for different parent
2363  * directories, *with* a rule matching a parent directory, but not directly
2364  * denying access (with MAKE_REG nor REMOVE).
2365  */
2366 TEST_F_FORK(layout1, refer_denied_by_default1)
2367 {
2368 	refer_denied_by_default(_metadata, layer_dir_s1d1_refer, 0,
2369 				layer_dir_s1d1_execute);
2370 }
2371 
2372 /*
2373  * Same test but this time turning around the ABI version order: the first
2374  * layer does not handle LANDLOCK_ACCESS_FS_REFER.
2375  */
2376 TEST_F_FORK(layout1, refer_denied_by_default2)
2377 {
2378 	refer_denied_by_default(_metadata, layer_dir_s1d1_execute, EXDEV,
2379 				layer_dir_s1d1_refer);
2380 }
2381 
2382 /*
2383  * Tests precedence over renames: denied by default for different parent
2384  * directories, *without* a rule matching a parent directory, but not directly
2385  * denying access (with MAKE_REG nor REMOVE).
2386  */
2387 TEST_F_FORK(layout1, refer_denied_by_default3)
2388 {
2389 	refer_denied_by_default(_metadata, layer_dir_s1d1_refer, 0,
2390 				layer_dir_s2d1_execute);
2391 }
2392 
2393 /*
2394  * Same test but this time turning around the ABI version order: the first
2395  * layer does not handle LANDLOCK_ACCESS_FS_REFER.
2396  */
2397 TEST_F_FORK(layout1, refer_denied_by_default4)
2398 {
2399 	refer_denied_by_default(_metadata, layer_dir_s2d1_execute, EXDEV,
2400 				layer_dir_s1d1_refer);
2401 }
2402 
2403 TEST_F_FORK(layout1, reparent_link)
2404 {
2405 	const struct rule layer1[] = {
2406 		{
2407 			.path = dir_s1d2,
2408 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2409 		},
2410 		{
2411 			.path = dir_s1d3,
2412 			.access = LANDLOCK_ACCESS_FS_REFER,
2413 		},
2414 		{
2415 			.path = dir_s2d2,
2416 			.access = LANDLOCK_ACCESS_FS_REFER,
2417 		},
2418 		{
2419 			.path = dir_s2d3,
2420 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2421 		},
2422 		{},
2423 	};
2424 	const int ruleset_fd = create_ruleset(
2425 		_metadata,
2426 		LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER, layer1);
2427 
2428 	ASSERT_LE(0, ruleset_fd);
2429 	enforce_ruleset(_metadata, ruleset_fd);
2430 	ASSERT_EQ(0, close(ruleset_fd));
2431 
2432 	ASSERT_EQ(0, unlink(file1_s1d1));
2433 	ASSERT_EQ(0, unlink(file1_s1d2));
2434 	ASSERT_EQ(0, unlink(file1_s1d3));
2435 
2436 	/* Denies linking because of missing MAKE_REG. */
2437 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2438 	ASSERT_EQ(EACCES, errno);
2439 	/* Denies linking because of missing source and destination REFER. */
2440 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
2441 	ASSERT_EQ(EXDEV, errno);
2442 	/* Denies linking because of missing source REFER. */
2443 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d3));
2444 	ASSERT_EQ(EXDEV, errno);
2445 
2446 	/* Denies linking because of missing MAKE_REG. */
2447 	ASSERT_EQ(-1, link(file1_s2d2, file1_s1d1));
2448 	ASSERT_EQ(EACCES, errno);
2449 	/* Denies linking because of missing destination REFER. */
2450 	ASSERT_EQ(-1, link(file1_s2d2, file1_s1d2));
2451 	ASSERT_EQ(EXDEV, errno);
2452 
2453 	/* Allows linking because of REFER and MAKE_REG. */
2454 	ASSERT_EQ(0, link(file1_s2d2, file1_s1d3));
2455 	ASSERT_EQ(0, unlink(file1_s2d2));
2456 	/* Reverse linking denied because of missing MAKE_REG. */
2457 	ASSERT_EQ(-1, link(file1_s1d3, file1_s2d2));
2458 	ASSERT_EQ(EACCES, errno);
2459 	ASSERT_EQ(0, unlink(file1_s2d3));
2460 	/* Checks reverse linking. */
2461 	ASSERT_EQ(0, link(file1_s1d3, file1_s2d3));
2462 	ASSERT_EQ(0, unlink(file1_s1d3));
2463 
2464 	/*
2465 	 * This is OK for a file link, but it should not be allowed for a
2466 	 * directory rename (because of the superset of access rights.
2467 	 */
2468 	ASSERT_EQ(0, link(file1_s2d3, file1_s1d3));
2469 	ASSERT_EQ(0, unlink(file1_s1d3));
2470 
2471 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
2472 	ASSERT_EQ(EXDEV, errno);
2473 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
2474 	ASSERT_EQ(EXDEV, errno);
2475 
2476 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
2477 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
2478 }
2479 
2480 TEST_F_FORK(layout1, reparent_rename)
2481 {
2482 	/* Same rules as for reparent_link. */
2483 	const struct rule layer1[] = {
2484 		{
2485 			.path = dir_s1d2,
2486 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2487 		},
2488 		{
2489 			.path = dir_s1d3,
2490 			.access = LANDLOCK_ACCESS_FS_REFER,
2491 		},
2492 		{
2493 			.path = dir_s2d2,
2494 			.access = LANDLOCK_ACCESS_FS_REFER,
2495 		},
2496 		{
2497 			.path = dir_s2d3,
2498 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2499 		},
2500 		{},
2501 	};
2502 	const int ruleset_fd = create_ruleset(
2503 		_metadata,
2504 		LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER, layer1);
2505 
2506 	ASSERT_LE(0, ruleset_fd);
2507 	enforce_ruleset(_metadata, ruleset_fd);
2508 	ASSERT_EQ(0, close(ruleset_fd));
2509 
2510 	ASSERT_EQ(0, unlink(file1_s1d2));
2511 	ASSERT_EQ(0, unlink(file1_s1d3));
2512 
2513 	/* Denies renaming because of missing MAKE_REG. */
2514 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file1_s1d1,
2515 				RENAME_EXCHANGE));
2516 	ASSERT_EQ(EACCES, errno);
2517 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file2_s1d1,
2518 				RENAME_EXCHANGE));
2519 	ASSERT_EQ(EACCES, errno);
2520 	ASSERT_EQ(0, unlink(file1_s1d1));
2521 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
2522 	ASSERT_EQ(EACCES, errno);
2523 	/* Even denies same file exchange. */
2524 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file2_s1d1,
2525 				RENAME_EXCHANGE));
2526 	ASSERT_EQ(EACCES, errno);
2527 
2528 	/* Denies renaming because of missing source and destination REFER. */
2529 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d2));
2530 	ASSERT_EQ(EXDEV, errno);
2531 	/*
2532 	 * Denies renaming because of missing MAKE_REG, source and destination
2533 	 * REFER.
2534 	 */
2535 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file2_s1d1,
2536 				RENAME_EXCHANGE));
2537 	ASSERT_EQ(EACCES, errno);
2538 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file2_s1d1, AT_FDCWD, file1_s2d1,
2539 				RENAME_EXCHANGE));
2540 	ASSERT_EQ(EACCES, errno);
2541 
2542 	/* Denies renaming because of missing source REFER. */
2543 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
2544 	ASSERT_EQ(EXDEV, errno);
2545 	/* Denies renaming because of missing MAKE_REG. */
2546 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file2_s1d3,
2547 				RENAME_EXCHANGE));
2548 	ASSERT_EQ(EACCES, errno);
2549 
2550 	/* Denies renaming because of missing MAKE_REG. */
2551 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d1));
2552 	ASSERT_EQ(EACCES, errno);
2553 	/* Denies renaming because of missing destination REFER*/
2554 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
2555 	ASSERT_EQ(EXDEV, errno);
2556 
2557 	/* Denies exchange because of one missing MAKE_REG. */
2558 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, file2_s1d3,
2559 				RENAME_EXCHANGE));
2560 	ASSERT_EQ(EACCES, errno);
2561 	/* Allows renaming because of REFER and MAKE_REG. */
2562 	ASSERT_EQ(0, rename(file1_s2d2, file1_s1d3));
2563 
2564 	/* Reverse renaming denied because of missing MAKE_REG. */
2565 	ASSERT_EQ(-1, rename(file1_s1d3, file1_s2d2));
2566 	ASSERT_EQ(EACCES, errno);
2567 	ASSERT_EQ(0, unlink(file1_s2d3));
2568 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2569 
2570 	/* Tests reverse renaming. */
2571 	ASSERT_EQ(0, rename(file1_s2d3, file1_s1d3));
2572 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s1d3,
2573 			       RENAME_EXCHANGE));
2574 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2575 
2576 	/*
2577 	 * This is OK for a file rename, but it should not be allowed for a
2578 	 * directory rename (because of the superset of access rights).
2579 	 */
2580 	ASSERT_EQ(0, rename(file1_s2d3, file1_s1d3));
2581 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2582 
2583 	/*
2584 	 * Tests superset restrictions applied to directories.  Not only the
2585 	 * dir_s2d3's parent (dir_s2d2) should be taken into account but also
2586 	 * access rights tied to dir_s2d3. dir_s2d2 is missing one access right
2587 	 * compared to dir_s1d3/file1_s1d3 (MAKE_REG) but it is provided
2588 	 * directly by the moved dir_s2d3.
2589 	 */
2590 	ASSERT_EQ(0, rename(dir_s2d3, file1_s1d3));
2591 	ASSERT_EQ(0, rename(file1_s1d3, dir_s2d3));
2592 	/*
2593 	 * The first rename is allowed but not the exchange because dir_s1d3's
2594 	 * parent (dir_s1d2) doesn't have REFER.
2595 	 */
2596 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
2597 				RENAME_EXCHANGE));
2598 	ASSERT_EQ(EXDEV, errno);
2599 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s2d3,
2600 				RENAME_EXCHANGE));
2601 	ASSERT_EQ(EXDEV, errno);
2602 	ASSERT_EQ(-1, rename(file1_s2d3, dir_s1d3));
2603 	ASSERT_EQ(EXDEV, errno);
2604 
2605 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s1d3));
2606 	ASSERT_EQ(EXDEV, errno);
2607 	ASSERT_EQ(-1, rename(file2_s1d3, file1_s1d2));
2608 	ASSERT_EQ(EXDEV, errno);
2609 
2610 	/* Renaming in the same directory is always allowed. */
2611 	ASSERT_EQ(0, rename(file2_s1d2, file1_s1d2));
2612 	ASSERT_EQ(0, rename(file2_s1d3, file1_s1d3));
2613 
2614 	ASSERT_EQ(0, unlink(file1_s1d2));
2615 	/* Denies because of missing source MAKE_REG and destination REFER. */
2616 	ASSERT_EQ(-1, rename(dir_s2d3, file1_s1d2));
2617 	ASSERT_EQ(EXDEV, errno);
2618 
2619 	ASSERT_EQ(0, unlink(file1_s1d3));
2620 	/* Denies because of missing source MAKE_REG and REFER. */
2621 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s1d3));
2622 	ASSERT_EQ(EXDEV, errno);
2623 }
2624 
2625 static void
2626 reparent_exdev_layers_enforce1(struct __test_metadata *const _metadata)
2627 {
2628 	const struct rule layer1[] = {
2629 		{
2630 			.path = dir_s1d2,
2631 			.access = LANDLOCK_ACCESS_FS_REFER,
2632 		},
2633 		{
2634 			/* Interesting for the layer2 tests. */
2635 			.path = dir_s1d3,
2636 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2637 		},
2638 		{
2639 			.path = dir_s2d2,
2640 			.access = LANDLOCK_ACCESS_FS_REFER,
2641 		},
2642 		{
2643 			.path = dir_s2d3,
2644 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
2645 		},
2646 		{},
2647 	};
2648 	const int ruleset_fd = create_ruleset(
2649 		_metadata,
2650 		LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER, layer1);
2651 
2652 	ASSERT_LE(0, ruleset_fd);
2653 	enforce_ruleset(_metadata, ruleset_fd);
2654 	ASSERT_EQ(0, close(ruleset_fd));
2655 }
2656 
2657 static void
2658 reparent_exdev_layers_enforce2(struct __test_metadata *const _metadata)
2659 {
2660 	const struct rule layer2[] = {
2661 		{
2662 			.path = dir_s2d3,
2663 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
2664 		},
2665 		{},
2666 	};
2667 	/*
2668 	 * Same checks as before but with a second layer and a new MAKE_DIR
2669 	 * rule (and no explicit handling of REFER).
2670 	 */
2671 	const int ruleset_fd =
2672 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_DIR, layer2);
2673 
2674 	ASSERT_LE(0, ruleset_fd);
2675 	enforce_ruleset(_metadata, ruleset_fd);
2676 	ASSERT_EQ(0, close(ruleset_fd));
2677 }
2678 
2679 TEST_F_FORK(layout1, reparent_exdev_layers_rename1)
2680 {
2681 	ASSERT_EQ(0, unlink(file1_s2d2));
2682 	ASSERT_EQ(0, unlink(file1_s2d3));
2683 
2684 	reparent_exdev_layers_enforce1(_metadata);
2685 
2686 	/*
2687 	 * Moving the dir_s1d3 directory below dir_s2d2 is allowed by Landlock
2688 	 * because it doesn't inherit new access rights.
2689 	 */
2690 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d2));
2691 	ASSERT_EQ(0, rename(file1_s2d2, dir_s1d3));
2692 
2693 	/*
2694 	 * Moving the dir_s1d3 directory below dir_s2d3 is allowed, even if it
2695 	 * gets a new inherited access rights (MAKE_REG), because MAKE_REG is
2696 	 * already allowed for dir_s1d3.
2697 	 */
2698 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d3));
2699 	ASSERT_EQ(0, rename(file1_s2d3, dir_s1d3));
2700 
2701 	/*
2702 	 * However, moving the file1_s1d3 file below dir_s2d3 is allowed
2703 	 * because it cannot inherit MAKE_REG right (which is dedicated to
2704 	 * directories).
2705 	 */
2706 	ASSERT_EQ(0, rename(file1_s1d3, file1_s2d3));
2707 
2708 	reparent_exdev_layers_enforce2(_metadata);
2709 
2710 	/*
2711 	 * Moving the dir_s1d3 directory below dir_s2d2 is now denied because
2712 	 * MAKE_DIR is not tied to dir_s2d2.
2713 	 */
2714 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d2));
2715 	ASSERT_EQ(EACCES, errno);
2716 
2717 	/*
2718 	 * Moving the dir_s1d3 directory below dir_s2d3 is forbidden because it
2719 	 * would grants MAKE_REG and MAKE_DIR rights to it.
2720 	 */
2721 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d3));
2722 	ASSERT_EQ(EXDEV, errno);
2723 
2724 	/*
2725 	 * Moving the file2_s1d3 file below dir_s2d3 is denied because the
2726 	 * second layer does not handle REFER, which is always denied by
2727 	 * default.
2728 	 */
2729 	ASSERT_EQ(-1, rename(file2_s1d3, file1_s2d3));
2730 	ASSERT_EQ(EXDEV, errno);
2731 }
2732 
2733 TEST_F_FORK(layout1, reparent_exdev_layers_rename2)
2734 {
2735 	reparent_exdev_layers_enforce1(_metadata);
2736 
2737 	/* Checks EACCES predominance over EXDEV. */
2738 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d2));
2739 	ASSERT_EQ(EACCES, errno);
2740 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d2));
2741 	ASSERT_EQ(EACCES, errno);
2742 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d3));
2743 	ASSERT_EQ(EXDEV, errno);
2744 	/* Modify layout! */
2745 	ASSERT_EQ(0, rename(file1_s1d2, file1_s2d3));
2746 
2747 	/* Without REFER source. */
2748 	ASSERT_EQ(-1, rename(dir_s1d1, file1_s2d2));
2749 	ASSERT_EQ(EXDEV, errno);
2750 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d2));
2751 	ASSERT_EQ(EXDEV, errno);
2752 
2753 	reparent_exdev_layers_enforce2(_metadata);
2754 
2755 	/* Checks EACCES predominance over EXDEV. */
2756 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d2));
2757 	ASSERT_EQ(EACCES, errno);
2758 	/* Checks with actual file2_s1d2. */
2759 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d2));
2760 	ASSERT_EQ(EACCES, errno);
2761 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s2d3));
2762 	ASSERT_EQ(EXDEV, errno);
2763 	/*
2764 	 * Modifying the layout is now denied because the second layer does not
2765 	 * handle REFER, which is always denied by default.
2766 	 */
2767 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d3));
2768 	ASSERT_EQ(EXDEV, errno);
2769 
2770 	/* Without REFER source, EACCES wins over EXDEV. */
2771 	ASSERT_EQ(-1, rename(dir_s1d1, file1_s2d2));
2772 	ASSERT_EQ(EACCES, errno);
2773 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d2));
2774 	ASSERT_EQ(EACCES, errno);
2775 }
2776 
2777 TEST_F_FORK(layout1, reparent_exdev_layers_exchange1)
2778 {
2779 	const char *const dir_file1_s1d2 = file1_s1d2, *const dir_file2_s2d3 =
2780 							       file2_s2d3;
2781 
2782 	ASSERT_EQ(0, unlink(file1_s1d2));
2783 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
2784 	ASSERT_EQ(0, unlink(file2_s2d3));
2785 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
2786 
2787 	reparent_exdev_layers_enforce1(_metadata);
2788 
2789 	/* Error predominance with file exchange: returns EXDEV and EACCES. */
2790 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d3,
2791 				RENAME_EXCHANGE));
2792 	ASSERT_EQ(EACCES, errno);
2793 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d1,
2794 				RENAME_EXCHANGE));
2795 	ASSERT_EQ(EACCES, errno);
2796 
2797 	/*
2798 	 * Checks with directories which creation could be allowed, but denied
2799 	 * because of access rights that would be inherited.
2800 	 */
2801 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD,
2802 				dir_file2_s2d3, RENAME_EXCHANGE));
2803 	ASSERT_EQ(EXDEV, errno);
2804 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD,
2805 				dir_file1_s1d2, RENAME_EXCHANGE));
2806 	ASSERT_EQ(EXDEV, errno);
2807 
2808 	/* Checks with same access rights. */
2809 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s2d3,
2810 			       RENAME_EXCHANGE));
2811 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
2812 			       RENAME_EXCHANGE));
2813 
2814 	/* Checks with different (child-only) access rights. */
2815 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_file1_s1d2,
2816 			       RENAME_EXCHANGE));
2817 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD, dir_s2d3,
2818 			       RENAME_EXCHANGE));
2819 
2820 	/*
2821 	 * Checks that exchange between file and directory are consistent.
2822 	 *
2823 	 * Moving a file (file1_s2d2) to a directory which only grants more
2824 	 * directory-related access rights is allowed, and at the same time
2825 	 * moving a directory (dir_file2_s2d3) to another directory which
2826 	 * grants less access rights is allowed too.
2827 	 *
2828 	 * See layout1.reparent_exdev_layers_exchange3 for inverted arguments.
2829 	 */
2830 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
2831 			       RENAME_EXCHANGE));
2832 	/*
2833 	 * However, moving back the directory is denied because it would get
2834 	 * more access rights than the current state and because file creation
2835 	 * is forbidden (in dir_s2d2).
2836 	 */
2837 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
2838 				RENAME_EXCHANGE));
2839 	ASSERT_EQ(EACCES, errno);
2840 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
2841 				RENAME_EXCHANGE));
2842 	ASSERT_EQ(EACCES, errno);
2843 
2844 	reparent_exdev_layers_enforce2(_metadata);
2845 
2846 	/* Error predominance with file exchange: returns EXDEV and EACCES. */
2847 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, file1_s2d3,
2848 				RENAME_EXCHANGE));
2849 	ASSERT_EQ(EACCES, errno);
2850 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d1,
2851 				RENAME_EXCHANGE));
2852 	ASSERT_EQ(EACCES, errno);
2853 
2854 	/* Checks with directories which creation is now denied. */
2855 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD,
2856 				dir_file2_s2d3, RENAME_EXCHANGE));
2857 	ASSERT_EQ(EACCES, errno);
2858 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD,
2859 				dir_file1_s1d2, RENAME_EXCHANGE));
2860 	ASSERT_EQ(EACCES, errno);
2861 
2862 	/* Checks with different (child-only) access rights. */
2863 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, dir_s2d3,
2864 				RENAME_EXCHANGE));
2865 	/* Denied because of MAKE_DIR. */
2866 	ASSERT_EQ(EACCES, errno);
2867 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
2868 				RENAME_EXCHANGE));
2869 	ASSERT_EQ(EACCES, errno);
2870 
2871 	/* Checks with different (child-only) access rights. */
2872 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_file1_s1d2,
2873 				RENAME_EXCHANGE));
2874 	/* Denied because of MAKE_DIR. */
2875 	ASSERT_EQ(EACCES, errno);
2876 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file1_s1d2, AT_FDCWD, dir_s2d3,
2877 				RENAME_EXCHANGE));
2878 	ASSERT_EQ(EACCES, errno);
2879 
2880 	/* See layout1.reparent_exdev_layers_exchange2 for complement. */
2881 }
2882 
2883 TEST_F_FORK(layout1, reparent_exdev_layers_exchange2)
2884 {
2885 	const char *const dir_file2_s2d3 = file2_s2d3;
2886 
2887 	ASSERT_EQ(0, unlink(file2_s2d3));
2888 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
2889 
2890 	reparent_exdev_layers_enforce1(_metadata);
2891 	reparent_exdev_layers_enforce2(_metadata);
2892 
2893 	/* Checks that exchange between file and directory are consistent. */
2894 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
2895 				RENAME_EXCHANGE));
2896 	ASSERT_EQ(EACCES, errno);
2897 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
2898 				RENAME_EXCHANGE));
2899 	ASSERT_EQ(EACCES, errno);
2900 }
2901 
2902 TEST_F_FORK(layout1, reparent_exdev_layers_exchange3)
2903 {
2904 	const char *const dir_file2_s2d3 = file2_s2d3;
2905 
2906 	ASSERT_EQ(0, unlink(file2_s2d3));
2907 	ASSERT_EQ(0, mkdir(file2_s2d3, 0700));
2908 
2909 	reparent_exdev_layers_enforce1(_metadata);
2910 
2911 	/*
2912 	 * Checks that exchange between file and directory are consistent,
2913 	 * including with inverted arguments (see
2914 	 * layout1.reparent_exdev_layers_exchange1).
2915 	 */
2916 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
2917 			       RENAME_EXCHANGE));
2918 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_file2_s2d3,
2919 				RENAME_EXCHANGE));
2920 	ASSERT_EQ(EACCES, errno);
2921 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_file2_s2d3, AT_FDCWD, file1_s2d2,
2922 				RENAME_EXCHANGE));
2923 	ASSERT_EQ(EACCES, errno);
2924 }
2925 
2926 TEST_F_FORK(layout1, reparent_remove)
2927 {
2928 	const struct rule layer1[] = {
2929 		{
2930 			.path = dir_s1d1,
2931 			.access = LANDLOCK_ACCESS_FS_REFER |
2932 				  LANDLOCK_ACCESS_FS_REMOVE_DIR,
2933 		},
2934 		{
2935 			.path = dir_s1d2,
2936 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2937 		},
2938 		{
2939 			.path = dir_s2d1,
2940 			.access = LANDLOCK_ACCESS_FS_REFER |
2941 				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
2942 		},
2943 		{},
2944 	};
2945 	const int ruleset_fd = create_ruleset(
2946 		_metadata,
2947 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_REMOVE_DIR |
2948 			LANDLOCK_ACCESS_FS_REMOVE_FILE,
2949 		layer1);
2950 
2951 	ASSERT_LE(0, ruleset_fd);
2952 	enforce_ruleset(_metadata, ruleset_fd);
2953 	ASSERT_EQ(0, close(ruleset_fd));
2954 
2955 	/* Access denied because of wrong/swapped remove file/dir. */
2956 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s2d2));
2957 	ASSERT_EQ(EACCES, errno);
2958 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s1d1));
2959 	ASSERT_EQ(EACCES, errno);
2960 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s2d2,
2961 				RENAME_EXCHANGE));
2962 	ASSERT_EQ(EACCES, errno);
2963 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s2d3,
2964 				RENAME_EXCHANGE));
2965 	ASSERT_EQ(EACCES, errno);
2966 
2967 	/* Access allowed thanks to the matching rights. */
2968 	ASSERT_EQ(-1, rename(file1_s2d1, dir_s1d2));
2969 	ASSERT_EQ(EISDIR, errno);
2970 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s2d1));
2971 	ASSERT_EQ(ENOTDIR, errno);
2972 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d1));
2973 	ASSERT_EQ(ENOTDIR, errno);
2974 	ASSERT_EQ(0, unlink(file1_s2d1));
2975 	ASSERT_EQ(0, unlink(file1_s1d3));
2976 	ASSERT_EQ(0, unlink(file2_s1d3));
2977 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d1));
2978 
2979 	/* Effectively removes a file and a directory by exchanging them. */
2980 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
2981 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
2982 			       RENAME_EXCHANGE));
2983 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
2984 				RENAME_EXCHANGE));
2985 	ASSERT_EQ(EACCES, errno);
2986 }
2987 
2988 TEST_F_FORK(layout1, reparent_dom_superset)
2989 {
2990 	const struct rule layer1[] = {
2991 		{
2992 			.path = dir_s1d2,
2993 			.access = LANDLOCK_ACCESS_FS_REFER,
2994 		},
2995 		{
2996 			.path = file1_s1d2,
2997 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
2998 		},
2999 		{
3000 			.path = dir_s1d3,
3001 			.access = LANDLOCK_ACCESS_FS_MAKE_SOCK |
3002 				  LANDLOCK_ACCESS_FS_EXECUTE,
3003 		},
3004 		{
3005 			.path = dir_s2d2,
3006 			.access = LANDLOCK_ACCESS_FS_REFER |
3007 				  LANDLOCK_ACCESS_FS_EXECUTE |
3008 				  LANDLOCK_ACCESS_FS_MAKE_SOCK,
3009 		},
3010 		{
3011 			.path = dir_s2d3,
3012 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3013 				  LANDLOCK_ACCESS_FS_MAKE_FIFO,
3014 		},
3015 		{},
3016 	};
3017 	int ruleset_fd = create_ruleset(_metadata,
3018 					LANDLOCK_ACCESS_FS_REFER |
3019 						LANDLOCK_ACCESS_FS_EXECUTE |
3020 						LANDLOCK_ACCESS_FS_MAKE_SOCK |
3021 						LANDLOCK_ACCESS_FS_READ_FILE |
3022 						LANDLOCK_ACCESS_FS_MAKE_FIFO,
3023 					layer1);
3024 
3025 	ASSERT_LE(0, ruleset_fd);
3026 	enforce_ruleset(_metadata, ruleset_fd);
3027 	ASSERT_EQ(0, close(ruleset_fd));
3028 
3029 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d1));
3030 	ASSERT_EQ(EXDEV, errno);
3031 	/*
3032 	 * Moving file1_s1d2 beneath dir_s2d3 would grant it the READ_FILE
3033 	 * access right.
3034 	 */
3035 	ASSERT_EQ(-1, rename(file1_s1d2, file1_s2d3));
3036 	ASSERT_EQ(EXDEV, errno);
3037 	/*
3038 	 * Moving file1_s1d2 should be allowed even if dir_s2d2 grants a
3039 	 * superset of access rights compared to dir_s1d2, because file1_s1d2
3040 	 * already has these access rights anyway.
3041 	 */
3042 	ASSERT_EQ(0, rename(file1_s1d2, file1_s2d2));
3043 	ASSERT_EQ(0, rename(file1_s2d2, file1_s1d2));
3044 
3045 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d1));
3046 	ASSERT_EQ(EXDEV, errno);
3047 	/*
3048 	 * Moving dir_s1d3 beneath dir_s2d3 would grant it the MAKE_FIFO access
3049 	 * right.
3050 	 */
3051 	ASSERT_EQ(-1, rename(dir_s1d3, file1_s2d3));
3052 	ASSERT_EQ(EXDEV, errno);
3053 	/*
3054 	 * Moving dir_s1d3 should be allowed even if dir_s2d2 grants a superset
3055 	 * of access rights compared to dir_s1d2, because dir_s1d3 already has
3056 	 * these access rights anyway.
3057 	 */
3058 	ASSERT_EQ(0, rename(dir_s1d3, file1_s2d2));
3059 	ASSERT_EQ(0, rename(file1_s2d2, dir_s1d3));
3060 
3061 	/*
3062 	 * Moving file1_s2d3 beneath dir_s1d2 is allowed, but moving it back
3063 	 * will be denied because the new inherited access rights from dir_s1d2
3064 	 * will be less than the destination (original) dir_s2d3.  This is a
3065 	 * sinkhole scenario where we cannot move back files or directories.
3066 	 */
3067 	ASSERT_EQ(0, rename(file1_s2d3, file2_s1d2));
3068 	ASSERT_EQ(-1, rename(file2_s1d2, file1_s2d3));
3069 	ASSERT_EQ(EXDEV, errno);
3070 	ASSERT_EQ(0, unlink(file2_s1d2));
3071 	ASSERT_EQ(0, unlink(file2_s2d3));
3072 	/*
3073 	 * Checks similar directory one-way move: dir_s2d3 loses EXECUTE and
3074 	 * MAKE_SOCK which were inherited from dir_s1d3.
3075 	 */
3076 	ASSERT_EQ(0, rename(dir_s2d3, file2_s1d2));
3077 	ASSERT_EQ(-1, rename(file2_s1d2, dir_s2d3));
3078 	ASSERT_EQ(EXDEV, errno);
3079 }
3080 
3081 TEST_F_FORK(layout1, remove_dir)
3082 {
3083 	const struct rule rules[] = {
3084 		{
3085 			.path = dir_s1d2,
3086 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
3087 		},
3088 		{},
3089 	};
3090 	const int ruleset_fd =
3091 		create_ruleset(_metadata, rules[0].access, rules);
3092 
3093 	ASSERT_LE(0, ruleset_fd);
3094 
3095 	ASSERT_EQ(0, unlink(file1_s1d1));
3096 	ASSERT_EQ(0, unlink(file1_s1d2));
3097 	ASSERT_EQ(0, unlink(file1_s1d3));
3098 	ASSERT_EQ(0, unlink(file2_s1d3));
3099 
3100 	enforce_ruleset(_metadata, ruleset_fd);
3101 	ASSERT_EQ(0, close(ruleset_fd));
3102 
3103 	ASSERT_EQ(0, rmdir(dir_s1d3));
3104 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
3105 	ASSERT_EQ(0, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
3106 
3107 	/* dir_s1d2 itself cannot be removed. */
3108 	ASSERT_EQ(-1, rmdir(dir_s1d2));
3109 	ASSERT_EQ(EACCES, errno);
3110 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d2, AT_REMOVEDIR));
3111 	ASSERT_EQ(EACCES, errno);
3112 	ASSERT_EQ(-1, rmdir(dir_s1d1));
3113 	ASSERT_EQ(EACCES, errno);
3114 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d1, AT_REMOVEDIR));
3115 	ASSERT_EQ(EACCES, errno);
3116 }
3117 
3118 TEST_F_FORK(layout1, remove_file)
3119 {
3120 	const struct rule rules[] = {
3121 		{
3122 			.path = dir_s1d2,
3123 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
3124 		},
3125 		{},
3126 	};
3127 	const int ruleset_fd =
3128 		create_ruleset(_metadata, rules[0].access, rules);
3129 
3130 	ASSERT_LE(0, ruleset_fd);
3131 	enforce_ruleset(_metadata, ruleset_fd);
3132 	ASSERT_EQ(0, close(ruleset_fd));
3133 
3134 	ASSERT_EQ(-1, unlink(file1_s1d1));
3135 	ASSERT_EQ(EACCES, errno);
3136 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, file1_s1d1, 0));
3137 	ASSERT_EQ(EACCES, errno);
3138 	ASSERT_EQ(0, unlink(file1_s1d2));
3139 	ASSERT_EQ(0, unlinkat(AT_FDCWD, file1_s1d3, 0));
3140 }
3141 
3142 static void test_make_file(struct __test_metadata *const _metadata,
3143 			   const __u64 access, const mode_t mode,
3144 			   const dev_t dev)
3145 {
3146 	const struct rule rules[] = {
3147 		{
3148 			.path = dir_s1d2,
3149 			.access = access,
3150 		},
3151 		{},
3152 	};
3153 	const int ruleset_fd = create_ruleset(_metadata, access, rules);
3154 
3155 	ASSERT_LE(0, ruleset_fd);
3156 
3157 	ASSERT_EQ(0, unlink(file1_s1d1));
3158 	ASSERT_EQ(0, unlink(file2_s1d1));
3159 	ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev))
3160 	{
3161 		TH_LOG("Failed to make file \"%s\": %s", file2_s1d1,
3162 		       strerror(errno));
3163 	};
3164 
3165 	ASSERT_EQ(0, unlink(file1_s1d2));
3166 	ASSERT_EQ(0, unlink(file2_s1d2));
3167 
3168 	ASSERT_EQ(0, unlink(file1_s1d3));
3169 	ASSERT_EQ(0, unlink(file2_s1d3));
3170 
3171 	enforce_ruleset(_metadata, ruleset_fd);
3172 	ASSERT_EQ(0, close(ruleset_fd));
3173 
3174 	ASSERT_EQ(-1, mknod(file1_s1d1, mode | 0400, dev));
3175 	ASSERT_EQ(EACCES, errno);
3176 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
3177 	ASSERT_EQ(EACCES, errno);
3178 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
3179 	ASSERT_EQ(EACCES, errno);
3180 
3181 	ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev))
3182 	{
3183 		TH_LOG("Failed to make file \"%s\": %s", file1_s1d2,
3184 		       strerror(errno));
3185 	};
3186 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
3187 	ASSERT_EQ(0, unlink(file2_s1d2));
3188 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
3189 
3190 	ASSERT_EQ(0, mknod(file1_s1d3, mode | 0400, dev));
3191 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
3192 	ASSERT_EQ(0, unlink(file2_s1d3));
3193 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
3194 }
3195 
3196 TEST_F_FORK(layout1, make_char)
3197 {
3198 	/* Creates a /dev/null device. */
3199 	set_cap(_metadata, CAP_MKNOD);
3200 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR,
3201 		       makedev(1, 3));
3202 }
3203 
3204 TEST_F_FORK(layout1, make_block)
3205 {
3206 	/* Creates a /dev/loop0 device. */
3207 	set_cap(_metadata, CAP_MKNOD);
3208 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK,
3209 		       makedev(7, 0));
3210 }
3211 
3212 TEST_F_FORK(layout1, make_reg_1)
3213 {
3214 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFREG, 0);
3215 }
3216 
3217 TEST_F_FORK(layout1, make_reg_2)
3218 {
3219 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, 0, 0);
3220 }
3221 
3222 TEST_F_FORK(layout1, make_sock)
3223 {
3224 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_SOCK, S_IFSOCK, 0);
3225 }
3226 
3227 TEST_F_FORK(layout1, make_fifo)
3228 {
3229 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_FIFO, S_IFIFO, 0);
3230 }
3231 
3232 TEST_F_FORK(layout1, make_sym)
3233 {
3234 	const struct rule rules[] = {
3235 		{
3236 			.path = dir_s1d2,
3237 			.access = LANDLOCK_ACCESS_FS_MAKE_SYM,
3238 		},
3239 		{},
3240 	};
3241 	const int ruleset_fd =
3242 		create_ruleset(_metadata, rules[0].access, rules);
3243 
3244 	ASSERT_LE(0, ruleset_fd);
3245 
3246 	ASSERT_EQ(0, unlink(file1_s1d1));
3247 	ASSERT_EQ(0, unlink(file2_s1d1));
3248 	ASSERT_EQ(0, symlink("none", file2_s1d1));
3249 
3250 	ASSERT_EQ(0, unlink(file1_s1d2));
3251 	ASSERT_EQ(0, unlink(file2_s1d2));
3252 
3253 	ASSERT_EQ(0, unlink(file1_s1d3));
3254 	ASSERT_EQ(0, unlink(file2_s1d3));
3255 
3256 	enforce_ruleset(_metadata, ruleset_fd);
3257 	ASSERT_EQ(0, close(ruleset_fd));
3258 
3259 	ASSERT_EQ(-1, symlink("none", file1_s1d1));
3260 	ASSERT_EQ(EACCES, errno);
3261 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
3262 	ASSERT_EQ(EACCES, errno);
3263 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
3264 	ASSERT_EQ(EACCES, errno);
3265 
3266 	ASSERT_EQ(0, symlink("none", file1_s1d2));
3267 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
3268 	ASSERT_EQ(0, unlink(file2_s1d2));
3269 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
3270 
3271 	ASSERT_EQ(0, symlink("none", file1_s1d3));
3272 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
3273 	ASSERT_EQ(0, unlink(file2_s1d3));
3274 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
3275 }
3276 
3277 TEST_F_FORK(layout1, make_dir)
3278 {
3279 	const struct rule rules[] = {
3280 		{
3281 			.path = dir_s1d2,
3282 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
3283 		},
3284 		{},
3285 	};
3286 	const int ruleset_fd =
3287 		create_ruleset(_metadata, rules[0].access, rules);
3288 
3289 	ASSERT_LE(0, ruleset_fd);
3290 
3291 	ASSERT_EQ(0, unlink(file1_s1d1));
3292 	ASSERT_EQ(0, unlink(file1_s1d2));
3293 	ASSERT_EQ(0, unlink(file1_s1d3));
3294 
3295 	enforce_ruleset(_metadata, ruleset_fd);
3296 	ASSERT_EQ(0, close(ruleset_fd));
3297 
3298 	/* Uses file_* as directory names. */
3299 	ASSERT_EQ(-1, mkdir(file1_s1d1, 0700));
3300 	ASSERT_EQ(EACCES, errno);
3301 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
3302 	ASSERT_EQ(0, mkdir(file1_s1d3, 0700));
3303 }
3304 
3305 static int open_proc_fd(struct __test_metadata *const _metadata, const int fd,
3306 			const int open_flags)
3307 {
3308 	static const char path_template[] = "/proc/self/fd/%d";
3309 	char procfd_path[sizeof(path_template) + 10];
3310 	const int procfd_path_size =
3311 		snprintf(procfd_path, sizeof(procfd_path), path_template, fd);
3312 
3313 	ASSERT_LT(procfd_path_size, sizeof(procfd_path));
3314 	return open(procfd_path, open_flags);
3315 }
3316 
3317 TEST_F_FORK(layout1, proc_unlinked_file)
3318 {
3319 	const struct rule rules[] = {
3320 		{
3321 			.path = file1_s1d2,
3322 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
3323 		},
3324 		{},
3325 	};
3326 	int reg_fd, proc_fd;
3327 	const int ruleset_fd = create_ruleset(
3328 		_metadata,
3329 		LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
3330 		rules);
3331 
3332 	ASSERT_LE(0, ruleset_fd);
3333 	enforce_ruleset(_metadata, ruleset_fd);
3334 	ASSERT_EQ(0, close(ruleset_fd));
3335 
3336 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
3337 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
3338 	reg_fd = open(file1_s1d2, O_RDONLY | O_CLOEXEC);
3339 	ASSERT_LE(0, reg_fd);
3340 	ASSERT_EQ(0, unlink(file1_s1d2));
3341 
3342 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDONLY | O_CLOEXEC);
3343 	ASSERT_LE(0, proc_fd);
3344 	ASSERT_EQ(0, close(proc_fd));
3345 
3346 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC);
3347 	ASSERT_EQ(-1, proc_fd)
3348 	{
3349 		TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd,
3350 		       strerror(errno));
3351 	}
3352 	ASSERT_EQ(EACCES, errno);
3353 
3354 	ASSERT_EQ(0, close(reg_fd));
3355 }
3356 
3357 TEST_F_FORK(layout1, proc_pipe)
3358 {
3359 	int proc_fd;
3360 	int pipe_fds[2];
3361 	char buf = '\0';
3362 	const struct rule rules[] = {
3363 		{
3364 			.path = dir_s1d2,
3365 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3366 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
3367 		},
3368 		{},
3369 	};
3370 	/* Limits read and write access to files tied to the filesystem. */
3371 	const int ruleset_fd =
3372 		create_ruleset(_metadata, rules[0].access, rules);
3373 
3374 	ASSERT_LE(0, ruleset_fd);
3375 	enforce_ruleset(_metadata, ruleset_fd);
3376 	ASSERT_EQ(0, close(ruleset_fd));
3377 
3378 	/* Checks enforcement for normal files. */
3379 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
3380 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
3381 
3382 	/* Checks access to pipes through FD. */
3383 	ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC));
3384 	ASSERT_EQ(1, write(pipe_fds[1], ".", 1))
3385 	{
3386 		TH_LOG("Failed to write in pipe: %s", strerror(errno));
3387 	}
3388 	ASSERT_EQ(1, read(pipe_fds[0], &buf, 1));
3389 	ASSERT_EQ('.', buf);
3390 
3391 	/* Checks write access to pipe through /proc/self/fd . */
3392 	proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC);
3393 	ASSERT_LE(0, proc_fd);
3394 	ASSERT_EQ(1, write(proc_fd, ".", 1))
3395 	{
3396 		TH_LOG("Failed to write through /proc/self/fd/%d: %s",
3397 		       pipe_fds[1], strerror(errno));
3398 	}
3399 	ASSERT_EQ(0, close(proc_fd));
3400 
3401 	/* Checks read access to pipe through /proc/self/fd . */
3402 	proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC);
3403 	ASSERT_LE(0, proc_fd);
3404 	buf = '\0';
3405 	ASSERT_EQ(1, read(proc_fd, &buf, 1))
3406 	{
3407 		TH_LOG("Failed to read through /proc/self/fd/%d: %s",
3408 		       pipe_fds[1], strerror(errno));
3409 	}
3410 	ASSERT_EQ(0, close(proc_fd));
3411 
3412 	ASSERT_EQ(0, close(pipe_fds[0]));
3413 	ASSERT_EQ(0, close(pipe_fds[1]));
3414 }
3415 
3416 /* Invokes truncate(2) and returns its errno or 0. */
3417 static int test_truncate(const char *const path)
3418 {
3419 	if (truncate(path, 10) < 0)
3420 		return errno;
3421 	return 0;
3422 }
3423 
3424 /*
3425  * Invokes creat(2) and returns its errno or 0.
3426  * Closes the opened file descriptor on success.
3427  */
3428 static int test_creat(const char *const path)
3429 {
3430 	int fd = creat(path, 0600);
3431 
3432 	if (fd < 0)
3433 		return errno;
3434 
3435 	/*
3436 	 * Mixing error codes from close(2) and creat(2) should not lead to any
3437 	 * (access type) confusion for this test.
3438 	 */
3439 	if (close(fd) < 0)
3440 		return errno;
3441 	return 0;
3442 }
3443 
3444 /*
3445  * Exercises file truncation when it's not restricted,
3446  * as it was the case before LANDLOCK_ACCESS_FS_TRUNCATE existed.
3447  */
3448 TEST_F_FORK(layout1, truncate_unhandled)
3449 {
3450 	const char *const file_r = file1_s1d1;
3451 	const char *const file_w = file2_s1d1;
3452 	const char *const file_none = file1_s1d2;
3453 	const struct rule rules[] = {
3454 		{
3455 			.path = file_r,
3456 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
3457 		},
3458 		{
3459 			.path = file_w,
3460 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3461 		},
3462 		/* Implicitly: No rights for file_none. */
3463 		{},
3464 	};
3465 
3466 	const __u64 handled = LANDLOCK_ACCESS_FS_READ_FILE |
3467 			      LANDLOCK_ACCESS_FS_WRITE_FILE;
3468 	int ruleset_fd;
3469 
3470 	/* Enables Landlock. */
3471 	ruleset_fd = create_ruleset(_metadata, handled, rules);
3472 
3473 	ASSERT_LE(0, ruleset_fd);
3474 	enforce_ruleset(_metadata, ruleset_fd);
3475 	ASSERT_EQ(0, close(ruleset_fd));
3476 
3477 	/*
3478 	 * Checks read right: truncate and open with O_TRUNC work, unless the
3479 	 * file is attempted to be opened for writing.
3480 	 */
3481 	EXPECT_EQ(0, test_truncate(file_r));
3482 	EXPECT_EQ(0, test_open(file_r, O_RDONLY | O_TRUNC));
3483 	EXPECT_EQ(EACCES, test_open(file_r, O_WRONLY | O_TRUNC));
3484 	EXPECT_EQ(EACCES, test_creat(file_r));
3485 
3486 	/*
3487 	 * Checks write right: truncate and open with O_TRUNC work, unless the
3488 	 * file is attempted to be opened for reading.
3489 	 */
3490 	EXPECT_EQ(0, test_truncate(file_w));
3491 	EXPECT_EQ(EACCES, test_open(file_w, O_RDONLY | O_TRUNC));
3492 	EXPECT_EQ(0, test_open(file_w, O_WRONLY | O_TRUNC));
3493 	EXPECT_EQ(0, test_creat(file_w));
3494 
3495 	/*
3496 	 * Checks "no rights" case: truncate works but all open attempts fail,
3497 	 * including creat.
3498 	 */
3499 	EXPECT_EQ(0, test_truncate(file_none));
3500 	EXPECT_EQ(EACCES, test_open(file_none, O_RDONLY | O_TRUNC));
3501 	EXPECT_EQ(EACCES, test_open(file_none, O_WRONLY | O_TRUNC));
3502 	EXPECT_EQ(EACCES, test_creat(file_none));
3503 }
3504 
3505 TEST_F_FORK(layout1, truncate)
3506 {
3507 	const char *const file_rwt = file1_s1d1;
3508 	const char *const file_rw = file2_s1d1;
3509 	const char *const file_rt = file1_s1d2;
3510 	const char *const file_t = file2_s1d2;
3511 	const char *const file_none = file1_s1d3;
3512 	const char *const dir_t = dir_s2d1;
3513 	const char *const file_in_dir_t = file1_s2d1;
3514 	const char *const dir_w = dir_s3d1;
3515 	const char *const file_in_dir_w = file1_s3d1;
3516 	const struct rule rules[] = {
3517 		{
3518 			.path = file_rwt,
3519 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3520 				  LANDLOCK_ACCESS_FS_WRITE_FILE |
3521 				  LANDLOCK_ACCESS_FS_TRUNCATE,
3522 		},
3523 		{
3524 			.path = file_rw,
3525 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3526 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
3527 		},
3528 		{
3529 			.path = file_rt,
3530 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
3531 				  LANDLOCK_ACCESS_FS_TRUNCATE,
3532 		},
3533 		{
3534 			.path = file_t,
3535 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3536 		},
3537 		/* Implicitly: No access rights for file_none. */
3538 		{
3539 			.path = dir_t,
3540 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3541 		},
3542 		{
3543 			.path = dir_w,
3544 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3545 		},
3546 		{},
3547 	};
3548 	const __u64 handled = LANDLOCK_ACCESS_FS_READ_FILE |
3549 			      LANDLOCK_ACCESS_FS_WRITE_FILE |
3550 			      LANDLOCK_ACCESS_FS_TRUNCATE;
3551 	int ruleset_fd;
3552 
3553 	/* Enables Landlock. */
3554 	ruleset_fd = create_ruleset(_metadata, handled, rules);
3555 
3556 	ASSERT_LE(0, ruleset_fd);
3557 	enforce_ruleset(_metadata, ruleset_fd);
3558 	ASSERT_EQ(0, close(ruleset_fd));
3559 
3560 	/* Checks read, write and truncate rights: truncation works. */
3561 	EXPECT_EQ(0, test_truncate(file_rwt));
3562 	EXPECT_EQ(0, test_open(file_rwt, O_RDONLY | O_TRUNC));
3563 	EXPECT_EQ(0, test_open(file_rwt, O_WRONLY | O_TRUNC));
3564 
3565 	/* Checks read and write rights: no truncate variant works. */
3566 	EXPECT_EQ(EACCES, test_truncate(file_rw));
3567 	EXPECT_EQ(EACCES, test_open(file_rw, O_RDONLY | O_TRUNC));
3568 	EXPECT_EQ(EACCES, test_open(file_rw, O_WRONLY | O_TRUNC));
3569 
3570 	/*
3571 	 * Checks read and truncate rights: truncation works.
3572 	 *
3573 	 * Note: Files can get truncated using open() even with O_RDONLY.
3574 	 */
3575 	EXPECT_EQ(0, test_truncate(file_rt));
3576 	EXPECT_EQ(0, test_open(file_rt, O_RDONLY | O_TRUNC));
3577 	EXPECT_EQ(EACCES, test_open(file_rt, O_WRONLY | O_TRUNC));
3578 
3579 	/* Checks truncate right: truncate works, but can't open file. */
3580 	EXPECT_EQ(0, test_truncate(file_t));
3581 	EXPECT_EQ(EACCES, test_open(file_t, O_RDONLY | O_TRUNC));
3582 	EXPECT_EQ(EACCES, test_open(file_t, O_WRONLY | O_TRUNC));
3583 
3584 	/* Checks "no rights" case: No form of truncation works. */
3585 	EXPECT_EQ(EACCES, test_truncate(file_none));
3586 	EXPECT_EQ(EACCES, test_open(file_none, O_RDONLY | O_TRUNC));
3587 	EXPECT_EQ(EACCES, test_open(file_none, O_WRONLY | O_TRUNC));
3588 
3589 	/*
3590 	 * Checks truncate right on directory: truncate works on contained
3591 	 * files.
3592 	 */
3593 	EXPECT_EQ(0, test_truncate(file_in_dir_t));
3594 	EXPECT_EQ(EACCES, test_open(file_in_dir_t, O_RDONLY | O_TRUNC));
3595 	EXPECT_EQ(EACCES, test_open(file_in_dir_t, O_WRONLY | O_TRUNC));
3596 
3597 	/*
3598 	 * Checks creat in dir_w: This requires the truncate right when
3599 	 * overwriting an existing file, but does not require it when the file
3600 	 * is new.
3601 	 */
3602 	EXPECT_EQ(EACCES, test_creat(file_in_dir_w));
3603 
3604 	ASSERT_EQ(0, unlink(file_in_dir_w));
3605 	EXPECT_EQ(0, test_creat(file_in_dir_w));
3606 }
3607 
3608 /* Invokes ftruncate(2) and returns its errno or 0. */
3609 static int test_ftruncate(int fd)
3610 {
3611 	if (ftruncate(fd, 10) < 0)
3612 		return errno;
3613 	return 0;
3614 }
3615 
3616 TEST_F_FORK(layout1, ftruncate)
3617 {
3618 	/*
3619 	 * This test opens a new file descriptor at different stages of
3620 	 * Landlock restriction:
3621 	 *
3622 	 * without restriction:                    ftruncate works
3623 	 * something else but truncate restricted: ftruncate works
3624 	 * truncate restricted and permitted:      ftruncate works
3625 	 * truncate restricted and not permitted:  ftruncate fails
3626 	 *
3627 	 * Whether this works or not is expected to depend on the time when the
3628 	 * FD was opened, not to depend on the time when ftruncate() was
3629 	 * called.
3630 	 */
3631 	const char *const path = file1_s1d1;
3632 	const __u64 handled1 = LANDLOCK_ACCESS_FS_READ_FILE |
3633 			       LANDLOCK_ACCESS_FS_WRITE_FILE;
3634 	const struct rule layer1[] = {
3635 		{
3636 			.path = path,
3637 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3638 		},
3639 		{},
3640 	};
3641 	const __u64 handled2 = LANDLOCK_ACCESS_FS_TRUNCATE;
3642 	const struct rule layer2[] = {
3643 		{
3644 			.path = path,
3645 			.access = LANDLOCK_ACCESS_FS_TRUNCATE,
3646 		},
3647 		{},
3648 	};
3649 	const __u64 handled3 = LANDLOCK_ACCESS_FS_TRUNCATE |
3650 			       LANDLOCK_ACCESS_FS_WRITE_FILE;
3651 	const struct rule layer3[] = {
3652 		{
3653 			.path = path,
3654 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
3655 		},
3656 		{},
3657 	};
3658 	int fd_layer0, fd_layer1, fd_layer2, fd_layer3, ruleset_fd;
3659 
3660 	fd_layer0 = open(path, O_WRONLY);
3661 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3662 
3663 	ruleset_fd = create_ruleset(_metadata, handled1, layer1);
3664 	ASSERT_LE(0, ruleset_fd);
3665 	enforce_ruleset(_metadata, ruleset_fd);
3666 	ASSERT_EQ(0, close(ruleset_fd));
3667 
3668 	fd_layer1 = open(path, O_WRONLY);
3669 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3670 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3671 
3672 	ruleset_fd = create_ruleset(_metadata, handled2, layer2);
3673 	ASSERT_LE(0, ruleset_fd);
3674 	enforce_ruleset(_metadata, ruleset_fd);
3675 	ASSERT_EQ(0, close(ruleset_fd));
3676 
3677 	fd_layer2 = open(path, O_WRONLY);
3678 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3679 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3680 	EXPECT_EQ(0, test_ftruncate(fd_layer2));
3681 
3682 	ruleset_fd = create_ruleset(_metadata, handled3, layer3);
3683 	ASSERT_LE(0, ruleset_fd);
3684 	enforce_ruleset(_metadata, ruleset_fd);
3685 	ASSERT_EQ(0, close(ruleset_fd));
3686 
3687 	fd_layer3 = open(path, O_WRONLY);
3688 	EXPECT_EQ(0, test_ftruncate(fd_layer0));
3689 	EXPECT_EQ(0, test_ftruncate(fd_layer1));
3690 	EXPECT_EQ(0, test_ftruncate(fd_layer2));
3691 	EXPECT_EQ(EACCES, test_ftruncate(fd_layer3));
3692 
3693 	ASSERT_EQ(0, close(fd_layer0));
3694 	ASSERT_EQ(0, close(fd_layer1));
3695 	ASSERT_EQ(0, close(fd_layer2));
3696 	ASSERT_EQ(0, close(fd_layer3));
3697 }
3698 
3699 /* clang-format off */
3700 FIXTURE(ftruncate) {};
3701 /* clang-format on */
3702 
3703 FIXTURE_SETUP(ftruncate)
3704 {
3705 	prepare_layout(_metadata);
3706 	create_file(_metadata, file1_s1d1);
3707 }
3708 
3709 FIXTURE_TEARDOWN_PARENT(ftruncate)
3710 {
3711 	EXPECT_EQ(0, remove_path(file1_s1d1));
3712 	cleanup_layout(_metadata);
3713 }
3714 
3715 FIXTURE_VARIANT(ftruncate)
3716 {
3717 	const __u64 handled;
3718 	const __u64 allowed;
3719 	const int expected_open_result;
3720 	const int expected_ftruncate_result;
3721 };
3722 
3723 /* clang-format off */
3724 FIXTURE_VARIANT_ADD(ftruncate, w_w) {
3725 	/* clang-format on */
3726 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE,
3727 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
3728 	.expected_open_result = 0,
3729 	.expected_ftruncate_result = 0,
3730 };
3731 
3732 /* clang-format off */
3733 FIXTURE_VARIANT_ADD(ftruncate, t_t) {
3734 	/* clang-format on */
3735 	.handled = LANDLOCK_ACCESS_FS_TRUNCATE,
3736 	.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
3737 	.expected_open_result = 0,
3738 	.expected_ftruncate_result = 0,
3739 };
3740 
3741 /* clang-format off */
3742 FIXTURE_VARIANT_ADD(ftruncate, wt_w) {
3743 	/* clang-format on */
3744 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3745 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE,
3746 	.expected_open_result = 0,
3747 	.expected_ftruncate_result = EACCES,
3748 };
3749 
3750 /* clang-format off */
3751 FIXTURE_VARIANT_ADD(ftruncate, wt_wt) {
3752 	/* clang-format on */
3753 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3754 	.allowed = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3755 	.expected_open_result = 0,
3756 	.expected_ftruncate_result = 0,
3757 };
3758 
3759 /* clang-format off */
3760 FIXTURE_VARIANT_ADD(ftruncate, wt_t) {
3761 	/* clang-format on */
3762 	.handled = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
3763 	.allowed = LANDLOCK_ACCESS_FS_TRUNCATE,
3764 	.expected_open_result = EACCES,
3765 };
3766 
3767 TEST_F_FORK(ftruncate, open_and_ftruncate)
3768 {
3769 	const char *const path = file1_s1d1;
3770 	const struct rule rules[] = {
3771 		{
3772 			.path = path,
3773 			.access = variant->allowed,
3774 		},
3775 		{},
3776 	};
3777 	int fd, ruleset_fd;
3778 
3779 	/* Enables Landlock. */
3780 	ruleset_fd = create_ruleset(_metadata, variant->handled, rules);
3781 	ASSERT_LE(0, ruleset_fd);
3782 	enforce_ruleset(_metadata, ruleset_fd);
3783 	ASSERT_EQ(0, close(ruleset_fd));
3784 
3785 	fd = open(path, O_WRONLY);
3786 	EXPECT_EQ(variant->expected_open_result, (fd < 0 ? errno : 0));
3787 	if (fd >= 0) {
3788 		EXPECT_EQ(variant->expected_ftruncate_result,
3789 			  test_ftruncate(fd));
3790 		ASSERT_EQ(0, close(fd));
3791 	}
3792 }
3793 
3794 TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes)
3795 {
3796 	int child, fd, status;
3797 	int socket_fds[2];
3798 
3799 	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0,
3800 				socket_fds));
3801 
3802 	child = fork();
3803 	ASSERT_LE(0, child);
3804 	if (child == 0) {
3805 		/*
3806 		 * Enables Landlock in the child process, open a file descriptor
3807 		 * where truncation is forbidden and send it to the
3808 		 * non-landlocked parent process.
3809 		 */
3810 		const char *const path = file1_s1d1;
3811 		const struct rule rules[] = {
3812 			{
3813 				.path = path,
3814 				.access = variant->allowed,
3815 			},
3816 			{},
3817 		};
3818 		int fd, ruleset_fd;
3819 
3820 		ruleset_fd = create_ruleset(_metadata, variant->handled, rules);
3821 		ASSERT_LE(0, ruleset_fd);
3822 		enforce_ruleset(_metadata, ruleset_fd);
3823 		ASSERT_EQ(0, close(ruleset_fd));
3824 
3825 		fd = open(path, O_WRONLY);
3826 		ASSERT_EQ(variant->expected_open_result, (fd < 0 ? errno : 0));
3827 
3828 		if (fd >= 0) {
3829 			ASSERT_EQ(0, send_fd(socket_fds[0], fd));
3830 			ASSERT_EQ(0, close(fd));
3831 		}
3832 
3833 		ASSERT_EQ(0, close(socket_fds[0]));
3834 
3835 		_exit(_metadata->exit_code);
3836 		return;
3837 	}
3838 
3839 	if (variant->expected_open_result == 0) {
3840 		fd = recv_fd(socket_fds[1]);
3841 		ASSERT_LE(0, fd);
3842 
3843 		EXPECT_EQ(variant->expected_ftruncate_result,
3844 			  test_ftruncate(fd));
3845 		ASSERT_EQ(0, close(fd));
3846 	}
3847 
3848 	ASSERT_EQ(child, waitpid(child, &status, 0));
3849 	ASSERT_EQ(1, WIFEXITED(status));
3850 	ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
3851 
3852 	ASSERT_EQ(0, close(socket_fds[0]));
3853 	ASSERT_EQ(0, close(socket_fds[1]));
3854 }
3855 
3856 /* Invokes the FS_IOC_GETFLAGS IOCTL and returns its errno or 0. */
3857 static int test_fs_ioc_getflags_ioctl(int fd)
3858 {
3859 	uint32_t flags;
3860 
3861 	if (ioctl(fd, FS_IOC_GETFLAGS, &flags) < 0)
3862 		return errno;
3863 	return 0;
3864 }
3865 
3866 TEST(memfd_ftruncate_and_ioctl)
3867 {
3868 	const struct landlock_ruleset_attr attr = {
3869 		.handled_access_fs = ACCESS_ALL,
3870 	};
3871 	int ruleset_fd, fd, i;
3872 
3873 	/*
3874 	 * We exercise the same test both with and without Landlock enabled, to
3875 	 * ensure that it behaves the same in both cases.
3876 	 */
3877 	for (i = 0; i < 2; i++) {
3878 		/* Creates a new memfd. */
3879 		fd = memfd_create("name", MFD_CLOEXEC);
3880 		ASSERT_LE(0, fd);
3881 
3882 		/*
3883 		 * Checks that operations associated with the opened file
3884 		 * (ftruncate, ioctl) are permitted on file descriptors that are
3885 		 * created in ways other than open(2).
3886 		 */
3887 		EXPECT_EQ(0, test_ftruncate(fd));
3888 		EXPECT_EQ(0, test_fs_ioc_getflags_ioctl(fd));
3889 
3890 		ASSERT_EQ(0, close(fd));
3891 
3892 		/* Enables Landlock. */
3893 		ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
3894 		ASSERT_LE(0, ruleset_fd);
3895 		enforce_ruleset(_metadata, ruleset_fd);
3896 		ASSERT_EQ(0, close(ruleset_fd));
3897 	}
3898 }
3899 
3900 static int test_fionread_ioctl(int fd)
3901 {
3902 	size_t sz = 0;
3903 
3904 	if (ioctl(fd, FIONREAD, &sz) < 0 && errno == EACCES)
3905 		return errno;
3906 	return 0;
3907 }
3908 
3909 TEST_F_FORK(layout1, o_path_ftruncate_and_ioctl)
3910 {
3911 	const struct landlock_ruleset_attr attr = {
3912 		.handled_access_fs = ACCESS_ALL,
3913 	};
3914 	int ruleset_fd, fd;
3915 
3916 	/*
3917 	 * Checks that for files opened with O_PATH, both ioctl(2) and
3918 	 * ftruncate(2) yield EBADF, as it is documented in open(2) for the
3919 	 * O_PATH flag.
3920 	 */
3921 	fd = open(dir_s1d1, O_PATH | O_CLOEXEC);
3922 	ASSERT_LE(0, fd);
3923 
3924 	EXPECT_EQ(EBADF, test_ftruncate(fd));
3925 	EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd));
3926 
3927 	ASSERT_EQ(0, close(fd));
3928 
3929 	/* Enables Landlock. */
3930 	ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
3931 	ASSERT_LE(0, ruleset_fd);
3932 	enforce_ruleset(_metadata, ruleset_fd);
3933 	ASSERT_EQ(0, close(ruleset_fd));
3934 
3935 	/*
3936 	 * Checks that after enabling Landlock,
3937 	 * - the file can still be opened with O_PATH
3938 	 * - both ioctl and truncate still yield EBADF (not EACCES).
3939 	 */
3940 	fd = open(dir_s1d1, O_PATH | O_CLOEXEC);
3941 	ASSERT_LE(0, fd);
3942 
3943 	EXPECT_EQ(EBADF, test_ftruncate(fd));
3944 	EXPECT_EQ(EBADF, test_fs_ioc_getflags_ioctl(fd));
3945 
3946 	ASSERT_EQ(0, close(fd));
3947 }
3948 
3949 /*
3950  * ioctl_error - generically call the given ioctl with a pointer to a
3951  * sufficiently large zeroed-out memory region.
3952  *
3953  * Returns the IOCTLs error, or 0.
3954  */
3955 static int ioctl_error(struct __test_metadata *const _metadata, int fd,
3956 		       unsigned int cmd)
3957 {
3958 	char buf[128]; /* sufficiently large */
3959 	int res, stdinbak_fd;
3960 
3961 	/*
3962 	 * Depending on the IOCTL command, parts of the zeroed-out buffer might
3963 	 * be interpreted as file descriptor numbers.  We do not want to
3964 	 * accidentally operate on file descriptor 0 (stdin), so we temporarily
3965 	 * move stdin to a different FD and close FD 0 for the IOCTL call.
3966 	 */
3967 	stdinbak_fd = dup(0);
3968 	ASSERT_LT(0, stdinbak_fd);
3969 	ASSERT_EQ(0, close(0));
3970 
3971 	/* Invokes the IOCTL with a zeroed-out buffer. */
3972 	bzero(&buf, sizeof(buf));
3973 	res = ioctl(fd, cmd, &buf);
3974 
3975 	/* Restores the old FD 0 and closes the backup FD. */
3976 	ASSERT_EQ(0, dup2(stdinbak_fd, 0));
3977 	ASSERT_EQ(0, close(stdinbak_fd));
3978 
3979 	if (res < 0)
3980 		return errno;
3981 
3982 	return 0;
3983 }
3984 
3985 /* Define some linux/falloc.h IOCTL commands which are not available in uapi headers. */
3986 struct space_resv {
3987 	__s16 l_type;
3988 	__s16 l_whence;
3989 	__s64 l_start;
3990 	__s64 l_len; /* len == 0 means until end of file */
3991 	__s32 l_sysid;
3992 	__u32 l_pid;
3993 	__s32 l_pad[4]; /* reserved area */
3994 };
3995 
3996 #define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
3997 #define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv)
3998 #define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
3999 #define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv)
4000 #define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv)
4001 
4002 /*
4003  * Tests a series of blanket-permitted and denied IOCTLs.
4004  */
4005 TEST_F_FORK(layout1, blanket_permitted_ioctls)
4006 {
4007 	const struct landlock_ruleset_attr attr = {
4008 		.handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4009 	};
4010 	int ruleset_fd, fd;
4011 
4012 	/* Enables Landlock. */
4013 	ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
4014 	ASSERT_LE(0, ruleset_fd);
4015 	enforce_ruleset(_metadata, ruleset_fd);
4016 	ASSERT_EQ(0, close(ruleset_fd));
4017 
4018 	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
4019 	ASSERT_LE(0, fd);
4020 
4021 	/*
4022 	 * Checks permitted commands.
4023 	 * These ones may return errors, but should not be blocked by Landlock.
4024 	 */
4025 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOCLEX));
4026 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONCLEX));
4027 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIONBIO));
4028 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOASYNC));
4029 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIOQSIZE));
4030 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIFREEZE));
4031 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FITHAW));
4032 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_FIEMAP));
4033 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIGETBSZ));
4034 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONE));
4035 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FICLONERANGE));
4036 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FIDEDUPERANGE));
4037 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSUUID));
4038 	EXPECT_NE(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFSSYSFSPATH));
4039 
4040 	/*
4041 	 * Checks blocked commands.
4042 	 * A call to a blocked IOCTL command always returns EACCES.
4043 	 */
4044 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIONREAD));
4045 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_GETFLAGS));
4046 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_SETFLAGS));
4047 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSGETXATTR));
4048 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_FSSETXATTR));
4049 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FIBMAP));
4050 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP));
4051 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_RESVSP64));
4052 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP));
4053 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_UNRESVSP64));
4054 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, FS_IOC_ZERO_RANGE));
4055 
4056 	/* Default case is also blocked. */
4057 	EXPECT_EQ(EACCES, ioctl_error(_metadata, fd, 0xc00ffeee));
4058 
4059 	ASSERT_EQ(0, close(fd));
4060 }
4061 
4062 /*
4063  * Named pipes are not governed by the LANDLOCK_ACCESS_FS_IOCTL_DEV right,
4064  * because they are not character or block devices.
4065  */
4066 TEST_F_FORK(layout1, named_pipe_ioctl)
4067 {
4068 	pid_t child_pid;
4069 	int fd, ruleset_fd;
4070 	const char *const path = file1_s1d1;
4071 	const struct landlock_ruleset_attr attr = {
4072 		.handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4073 	};
4074 
4075 	ASSERT_EQ(0, unlink(path));
4076 	ASSERT_EQ(0, mkfifo(path, 0600));
4077 
4078 	/* Enables Landlock. */
4079 	ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
4080 	ASSERT_LE(0, ruleset_fd);
4081 	enforce_ruleset(_metadata, ruleset_fd);
4082 	ASSERT_EQ(0, close(ruleset_fd));
4083 
4084 	/* The child process opens the pipe for writing. */
4085 	child_pid = fork();
4086 	ASSERT_NE(-1, child_pid);
4087 	if (child_pid == 0) {
4088 		fd = open(path, O_WRONLY);
4089 		close(fd);
4090 		exit(0);
4091 	}
4092 
4093 	fd = open(path, O_RDONLY);
4094 	ASSERT_LE(0, fd);
4095 
4096 	/* FIONREAD is implemented by pipefifo_fops. */
4097 	EXPECT_EQ(0, test_fionread_ioctl(fd));
4098 
4099 	ASSERT_EQ(0, close(fd));
4100 	ASSERT_EQ(0, unlink(path));
4101 
4102 	ASSERT_EQ(child_pid, waitpid(child_pid, NULL, 0));
4103 }
4104 
4105 /* For named UNIX domain sockets, no IOCTL restrictions apply. */
4106 TEST_F_FORK(layout1, named_unix_domain_socket_ioctl)
4107 {
4108 	const char *const path = file1_s1d1;
4109 	int srv_fd, cli_fd, ruleset_fd;
4110 	socklen_t size;
4111 	struct sockaddr_un srv_un, cli_un;
4112 	const struct landlock_ruleset_attr attr = {
4113 		.handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4114 	};
4115 
4116 	/* Sets up a server */
4117 	srv_un.sun_family = AF_UNIX;
4118 	strncpy(srv_un.sun_path, path, sizeof(srv_un.sun_path));
4119 
4120 	ASSERT_EQ(0, unlink(path));
4121 	srv_fd = socket(AF_UNIX, SOCK_STREAM, 0);
4122 	ASSERT_LE(0, srv_fd);
4123 
4124 	size = offsetof(struct sockaddr_un, sun_path) + strlen(srv_un.sun_path);
4125 	ASSERT_EQ(0, bind(srv_fd, (struct sockaddr *)&srv_un, size));
4126 	ASSERT_EQ(0, listen(srv_fd, 10 /* qlen */));
4127 
4128 	/* Enables Landlock. */
4129 	ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
4130 	ASSERT_LE(0, ruleset_fd);
4131 	enforce_ruleset(_metadata, ruleset_fd);
4132 	ASSERT_EQ(0, close(ruleset_fd));
4133 
4134 	/* Sets up a client connection to it */
4135 	cli_un.sun_family = AF_UNIX;
4136 	cli_fd = socket(AF_UNIX, SOCK_STREAM, 0);
4137 	ASSERT_LE(0, cli_fd);
4138 
4139 	size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path);
4140 	ASSERT_EQ(0, bind(cli_fd, (struct sockaddr *)&cli_un, size));
4141 
4142 	bzero(&cli_un, sizeof(cli_un));
4143 	cli_un.sun_family = AF_UNIX;
4144 	strncpy(cli_un.sun_path, path, sizeof(cli_un.sun_path));
4145 	size = offsetof(struct sockaddr_un, sun_path) + strlen(cli_un.sun_path);
4146 
4147 	ASSERT_EQ(0, connect(cli_fd, (struct sockaddr *)&cli_un, size));
4148 
4149 	/* FIONREAD and other IOCTLs should not be forbidden. */
4150 	EXPECT_EQ(0, test_fionread_ioctl(cli_fd));
4151 
4152 	ASSERT_EQ(0, close(cli_fd));
4153 }
4154 
4155 /* clang-format off */
4156 FIXTURE(ioctl) {};
4157 
4158 FIXTURE_SETUP(ioctl) {};
4159 
4160 FIXTURE_TEARDOWN(ioctl) {};
4161 /* clang-format on */
4162 
4163 FIXTURE_VARIANT(ioctl)
4164 {
4165 	const __u64 handled;
4166 	const __u64 allowed;
4167 	const mode_t open_mode;
4168 	/*
4169 	 * FIONREAD is used as a characteristic device-specific IOCTL command.
4170 	 * It is implemented in fs/ioctl.c for regular files,
4171 	 * but we do not blanket-permit it for devices.
4172 	 */
4173 	const int expected_fionread_result;
4174 };
4175 
4176 /* clang-format off */
4177 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_none) {
4178 	/* clang-format on */
4179 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4180 	.allowed = 0,
4181 	.open_mode = O_RDWR,
4182 	.expected_fionread_result = EACCES,
4183 };
4184 
4185 /* clang-format off */
4186 FIXTURE_VARIANT_ADD(ioctl, handled_i_allowed_i) {
4187 	/* clang-format on */
4188 	.handled = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4189 	.allowed = LANDLOCK_ACCESS_FS_IOCTL_DEV,
4190 	.open_mode = O_RDWR,
4191 	.expected_fionread_result = 0,
4192 };
4193 
4194 /* clang-format off */
4195 FIXTURE_VARIANT_ADD(ioctl, unhandled) {
4196 	/* clang-format on */
4197 	.handled = LANDLOCK_ACCESS_FS_EXECUTE,
4198 	.allowed = LANDLOCK_ACCESS_FS_EXECUTE,
4199 	.open_mode = O_RDWR,
4200 	.expected_fionread_result = 0,
4201 };
4202 
4203 TEST_F_FORK(ioctl, handle_dir_access_file)
4204 {
4205 	const int flag = 0;
4206 	const struct rule rules[] = {
4207 		{
4208 			.path = "/dev",
4209 			.access = variant->allowed,
4210 		},
4211 		{},
4212 	};
4213 	int file_fd, ruleset_fd;
4214 
4215 	/* Enables Landlock. */
4216 	ruleset_fd = create_ruleset(_metadata, variant->handled, rules);
4217 	ASSERT_LE(0, ruleset_fd);
4218 	enforce_ruleset(_metadata, ruleset_fd);
4219 	ASSERT_EQ(0, close(ruleset_fd));
4220 
4221 	file_fd = open("/dev/zero", variant->open_mode);
4222 	ASSERT_LE(0, file_fd);
4223 
4224 	/* Checks that IOCTL commands return the expected errors. */
4225 	EXPECT_EQ(variant->expected_fionread_result,
4226 		  test_fionread_ioctl(file_fd));
4227 
4228 	/* Checks that unrestrictable commands are unrestricted. */
4229 	EXPECT_EQ(0, ioctl(file_fd, FIOCLEX));
4230 	EXPECT_EQ(0, ioctl(file_fd, FIONCLEX));
4231 	EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag));
4232 	EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag));
4233 	EXPECT_EQ(0, ioctl(file_fd, FIGETBSZ, &flag));
4234 
4235 	ASSERT_EQ(0, close(file_fd));
4236 }
4237 
4238 TEST_F_FORK(ioctl, handle_dir_access_dir)
4239 {
4240 	const int flag = 0;
4241 	const struct rule rules[] = {
4242 		{
4243 			.path = "/dev",
4244 			.access = variant->allowed,
4245 		},
4246 		{},
4247 	};
4248 	int dir_fd, ruleset_fd;
4249 
4250 	/* Enables Landlock. */
4251 	ruleset_fd = create_ruleset(_metadata, variant->handled, rules);
4252 	ASSERT_LE(0, ruleset_fd);
4253 	enforce_ruleset(_metadata, ruleset_fd);
4254 	ASSERT_EQ(0, close(ruleset_fd));
4255 
4256 	/*
4257 	 * Ignore variant->open_mode for this test, as we intend to open a
4258 	 * directory.  If the directory can not be opened, the variant is
4259 	 * infeasible to test with an opened directory.
4260 	 */
4261 	dir_fd = open("/dev", O_RDONLY);
4262 	if (dir_fd < 0)
4263 		return;
4264 
4265 	/*
4266 	 * Checks that IOCTL commands return the expected errors.
4267 	 * We do not use the expected values from the fixture here.
4268 	 *
4269 	 * When using IOCTL on a directory, no Landlock restrictions apply.
4270 	 */
4271 	EXPECT_EQ(0, test_fionread_ioctl(dir_fd));
4272 
4273 	/* Checks that unrestrictable commands are unrestricted. */
4274 	EXPECT_EQ(0, ioctl(dir_fd, FIOCLEX));
4275 	EXPECT_EQ(0, ioctl(dir_fd, FIONCLEX));
4276 	EXPECT_EQ(0, ioctl(dir_fd, FIONBIO, &flag));
4277 	EXPECT_EQ(0, ioctl(dir_fd, FIOASYNC, &flag));
4278 	EXPECT_EQ(0, ioctl(dir_fd, FIGETBSZ, &flag));
4279 
4280 	ASSERT_EQ(0, close(dir_fd));
4281 }
4282 
4283 TEST_F_FORK(ioctl, handle_file_access_file)
4284 {
4285 	const int flag = 0;
4286 	const struct rule rules[] = {
4287 		{
4288 			.path = "/dev/zero",
4289 			.access = variant->allowed,
4290 		},
4291 		{},
4292 	};
4293 	int file_fd, ruleset_fd;
4294 
4295 	/* Enables Landlock. */
4296 	ruleset_fd = create_ruleset(_metadata, variant->handled, rules);
4297 	ASSERT_LE(0, ruleset_fd);
4298 	enforce_ruleset(_metadata, ruleset_fd);
4299 	ASSERT_EQ(0, close(ruleset_fd));
4300 
4301 	file_fd = open("/dev/zero", variant->open_mode);
4302 	ASSERT_LE(0, file_fd)
4303 	{
4304 		TH_LOG("Failed to open /dev/zero: %s", strerror(errno));
4305 	}
4306 
4307 	/* Checks that IOCTL commands return the expected errors. */
4308 	EXPECT_EQ(variant->expected_fionread_result,
4309 		  test_fionread_ioctl(file_fd));
4310 
4311 	/* Checks that unrestrictable commands are unrestricted. */
4312 	EXPECT_EQ(0, ioctl(file_fd, FIOCLEX));
4313 	EXPECT_EQ(0, ioctl(file_fd, FIONCLEX));
4314 	EXPECT_EQ(0, ioctl(file_fd, FIONBIO, &flag));
4315 	EXPECT_EQ(0, ioctl(file_fd, FIOASYNC, &flag));
4316 	EXPECT_EQ(0, ioctl(file_fd, FIGETBSZ, &flag));
4317 
4318 	ASSERT_EQ(0, close(file_fd));
4319 }
4320 
4321 /* clang-format off */
4322 FIXTURE(layout1_bind) {};
4323 /* clang-format on */
4324 
4325 FIXTURE_SETUP(layout1_bind)
4326 {
4327 	prepare_layout(_metadata);
4328 
4329 	create_layout1(_metadata);
4330 
4331 	set_cap(_metadata, CAP_SYS_ADMIN);
4332 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
4333 	clear_cap(_metadata, CAP_SYS_ADMIN);
4334 }
4335 
4336 FIXTURE_TEARDOWN_PARENT(layout1_bind)
4337 {
4338 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
4339 
4340 	remove_layout1(_metadata);
4341 
4342 	cleanup_layout(_metadata);
4343 }
4344 
4345 static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
4346 static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
4347 
4348 /*
4349  * layout1_bind hierarchy:
4350  *
4351  * tmp
4352  * ├── s1d1
4353  * │   ├── f1
4354  * │   ├── f2
4355  * │   └── s1d2
4356  * │       ├── f1
4357  * │       ├── f2
4358  * │       └── s1d3
4359  * │           ├── f1
4360  * │           └── f2
4361  * ├── s2d1
4362  * │   ├── f1
4363  * │   └── s2d2
4364  * │       ├── f1
4365  * │       ├── f2
4366  * │       └── s1d3
4367  * │           ├── f1
4368  * │           └── f2
4369  * └── s3d1
4370  *     └── s3d2
4371  *         └── s3d3
4372  */
4373 
4374 TEST_F_FORK(layout1_bind, no_restriction)
4375 {
4376 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
4377 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
4378 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
4379 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
4380 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
4381 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
4382 
4383 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
4384 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
4385 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
4386 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
4387 	ASSERT_EQ(ENOENT, test_open(dir_s2d3, O_RDONLY));
4388 	ASSERT_EQ(ENOENT, test_open(file1_s2d3, O_RDONLY));
4389 
4390 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY));
4391 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
4392 
4393 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
4394 }
4395 
4396 TEST_F_FORK(layout1_bind, same_content_same_file)
4397 {
4398 	/*
4399 	 * Sets access right on parent directories of both source and
4400 	 * destination mount points.
4401 	 */
4402 	const struct rule layer1_parent[] = {
4403 		{
4404 			.path = dir_s1d1,
4405 			.access = ACCESS_RO,
4406 		},
4407 		{
4408 			.path = dir_s2d1,
4409 			.access = ACCESS_RW,
4410 		},
4411 		{},
4412 	};
4413 	/*
4414 	 * Sets access rights on the same bind-mounted directories.  The result
4415 	 * should be ACCESS_RW for both directories, but not both hierarchies
4416 	 * because of the first layer.
4417 	 */
4418 	const struct rule layer2_mount_point[] = {
4419 		{
4420 			.path = dir_s1d2,
4421 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4422 		},
4423 		{
4424 			.path = dir_s2d2,
4425 			.access = ACCESS_RW,
4426 		},
4427 		{},
4428 	};
4429 	/* Only allow read-access to the s1d3 hierarchies. */
4430 	const struct rule layer3_source[] = {
4431 		{
4432 			.path = dir_s1d3,
4433 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4434 		},
4435 		{},
4436 	};
4437 	/* Removes all access rights. */
4438 	const struct rule layer4_destination[] = {
4439 		{
4440 			.path = bind_file1_s1d3,
4441 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
4442 		},
4443 		{},
4444 	};
4445 	int ruleset_fd;
4446 
4447 	/* Sets rules for the parent directories. */
4448 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_parent);
4449 	ASSERT_LE(0, ruleset_fd);
4450 	enforce_ruleset(_metadata, ruleset_fd);
4451 	ASSERT_EQ(0, close(ruleset_fd));
4452 
4453 	/* Checks source hierarchy. */
4454 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
4455 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
4456 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
4457 
4458 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
4459 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
4460 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
4461 
4462 	/* Checks destination hierarchy. */
4463 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDWR));
4464 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
4465 
4466 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
4467 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
4468 
4469 	/* Sets rules for the mount points. */
4470 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_mount_point);
4471 	ASSERT_LE(0, ruleset_fd);
4472 	enforce_ruleset(_metadata, ruleset_fd);
4473 	ASSERT_EQ(0, close(ruleset_fd));
4474 
4475 	/* Checks source hierarchy. */
4476 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
4477 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
4478 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
4479 
4480 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
4481 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
4482 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
4483 
4484 	/* Checks destination hierarchy. */
4485 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_RDONLY));
4486 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_WRONLY));
4487 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
4488 
4489 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
4490 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
4491 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
4492 
4493 	/* Sets a (shared) rule only on the source. */
4494 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_source);
4495 	ASSERT_LE(0, ruleset_fd);
4496 	enforce_ruleset(_metadata, ruleset_fd);
4497 	ASSERT_EQ(0, close(ruleset_fd));
4498 
4499 	/* Checks source hierarchy. */
4500 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
4501 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
4502 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
4503 
4504 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
4505 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
4506 	ASSERT_EQ(EACCES, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
4507 
4508 	/* Checks destination hierarchy. */
4509 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_RDONLY));
4510 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_WRONLY));
4511 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
4512 
4513 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
4514 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
4515 	ASSERT_EQ(EACCES, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
4516 
4517 	/* Sets a (shared) rule only on the destination. */
4518 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_destination);
4519 	ASSERT_LE(0, ruleset_fd);
4520 	enforce_ruleset(_metadata, ruleset_fd);
4521 	ASSERT_EQ(0, close(ruleset_fd));
4522 
4523 	/* Checks source hierarchy. */
4524 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
4525 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
4526 
4527 	/* Checks destination hierarchy. */
4528 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_RDONLY));
4529 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
4530 }
4531 
4532 TEST_F_FORK(layout1_bind, reparent_cross_mount)
4533 {
4534 	const struct rule layer1[] = {
4535 		{
4536 			/* dir_s2d1 is beneath the dir_s2d2 mount point. */
4537 			.path = dir_s2d1,
4538 			.access = LANDLOCK_ACCESS_FS_REFER,
4539 		},
4540 		{
4541 			.path = bind_dir_s1d3,
4542 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
4543 		},
4544 		{},
4545 	};
4546 	int ruleset_fd = create_ruleset(
4547 		_metadata,
4548 		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_EXECUTE, layer1);
4549 
4550 	ASSERT_LE(0, ruleset_fd);
4551 	enforce_ruleset(_metadata, ruleset_fd);
4552 	ASSERT_EQ(0, close(ruleset_fd));
4553 
4554 	/* Checks basic denied move. */
4555 	ASSERT_EQ(-1, rename(file1_s1d1, file1_s1d2));
4556 	ASSERT_EQ(EXDEV, errno);
4557 
4558 	/* Checks real cross-mount move (Landlock is not involved). */
4559 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s2d2));
4560 	ASSERT_EQ(EXDEV, errno);
4561 
4562 	/* Checks move that will give more accesses. */
4563 	ASSERT_EQ(-1, rename(file1_s2d2, bind_file1_s1d3));
4564 	ASSERT_EQ(EXDEV, errno);
4565 
4566 	/* Checks legitimate downgrade move. */
4567 	ASSERT_EQ(0, rename(bind_file1_s1d3, file1_s2d2));
4568 }
4569 
4570 #define LOWER_BASE TMP_DIR "/lower"
4571 #define LOWER_DATA LOWER_BASE "/data"
4572 static const char lower_fl1[] = LOWER_DATA "/fl1";
4573 static const char lower_dl1[] = LOWER_DATA "/dl1";
4574 static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2";
4575 static const char lower_fo1[] = LOWER_DATA "/fo1";
4576 static const char lower_do1[] = LOWER_DATA "/do1";
4577 static const char lower_do1_fo2[] = LOWER_DATA "/do1/fo2";
4578 static const char lower_do1_fl3[] = LOWER_DATA "/do1/fl3";
4579 
4580 static const char (*lower_base_files[])[] = {
4581 	&lower_fl1,
4582 	&lower_fo1,
4583 	NULL,
4584 };
4585 static const char (*lower_base_directories[])[] = {
4586 	&lower_dl1,
4587 	&lower_do1,
4588 	NULL,
4589 };
4590 static const char (*lower_sub_files[])[] = {
4591 	&lower_dl1_fl2,
4592 	&lower_do1_fo2,
4593 	&lower_do1_fl3,
4594 	NULL,
4595 };
4596 
4597 #define UPPER_BASE TMP_DIR "/upper"
4598 #define UPPER_DATA UPPER_BASE "/data"
4599 #define UPPER_WORK UPPER_BASE "/work"
4600 static const char upper_fu1[] = UPPER_DATA "/fu1";
4601 static const char upper_du1[] = UPPER_DATA "/du1";
4602 static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2";
4603 static const char upper_fo1[] = UPPER_DATA "/fo1";
4604 static const char upper_do1[] = UPPER_DATA "/do1";
4605 static const char upper_do1_fo2[] = UPPER_DATA "/do1/fo2";
4606 static const char upper_do1_fu3[] = UPPER_DATA "/do1/fu3";
4607 
4608 static const char (*upper_base_files[])[] = {
4609 	&upper_fu1,
4610 	&upper_fo1,
4611 	NULL,
4612 };
4613 static const char (*upper_base_directories[])[] = {
4614 	&upper_du1,
4615 	&upper_do1,
4616 	NULL,
4617 };
4618 static const char (*upper_sub_files[])[] = {
4619 	&upper_du1_fu2,
4620 	&upper_do1_fo2,
4621 	&upper_do1_fu3,
4622 	NULL,
4623 };
4624 
4625 #define MERGE_BASE TMP_DIR "/merge"
4626 #define MERGE_DATA MERGE_BASE "/data"
4627 static const char merge_fl1[] = MERGE_DATA "/fl1";
4628 static const char merge_dl1[] = MERGE_DATA "/dl1";
4629 static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2";
4630 static const char merge_fu1[] = MERGE_DATA "/fu1";
4631 static const char merge_du1[] = MERGE_DATA "/du1";
4632 static const char merge_du1_fu2[] = MERGE_DATA "/du1/fu2";
4633 static const char merge_fo1[] = MERGE_DATA "/fo1";
4634 static const char merge_do1[] = MERGE_DATA "/do1";
4635 static const char merge_do1_fo2[] = MERGE_DATA "/do1/fo2";
4636 static const char merge_do1_fl3[] = MERGE_DATA "/do1/fl3";
4637 static const char merge_do1_fu3[] = MERGE_DATA "/do1/fu3";
4638 
4639 static const char (*merge_base_files[])[] = {
4640 	&merge_fl1,
4641 	&merge_fu1,
4642 	&merge_fo1,
4643 	NULL,
4644 };
4645 static const char (*merge_base_directories[])[] = {
4646 	&merge_dl1,
4647 	&merge_du1,
4648 	&merge_do1,
4649 	NULL,
4650 };
4651 static const char (*merge_sub_files[])[] = {
4652 	&merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2,
4653 	&merge_do1_fl3, &merge_do1_fu3, NULL,
4654 };
4655 
4656 /*
4657  * layout2_overlay hierarchy:
4658  *
4659  * tmp
4660  * ├── lower
4661  * │   └── data
4662  * │       ├── dl1
4663  * │       │   └── fl2
4664  * │       ├── do1
4665  * │       │   ├── fl3
4666  * │       │   └── fo2
4667  * │       ├── fl1
4668  * │       └── fo1
4669  * ├── merge
4670  * │   └── data
4671  * │       ├── dl1
4672  * │       │   └── fl2
4673  * │       ├── do1
4674  * │       │   ├── fl3
4675  * │       │   ├── fo2
4676  * │       │   └── fu3
4677  * │       ├── du1
4678  * │       │   └── fu2
4679  * │       ├── fl1
4680  * │       ├── fo1
4681  * │       └── fu1
4682  * └── upper
4683  *     ├── data
4684  *     │   ├── do1
4685  *     │   │   ├── fo2
4686  *     │   │   └── fu3
4687  *     │   ├── du1
4688  *     │   │   └── fu2
4689  *     │   ├── fo1
4690  *     │   └── fu1
4691  *     └── work
4692  *         └── work
4693  */
4694 
4695 FIXTURE(layout2_overlay)
4696 {
4697 	bool skip_test;
4698 };
4699 
4700 FIXTURE_SETUP(layout2_overlay)
4701 {
4702 	if (!supports_filesystem("overlay")) {
4703 		self->skip_test = true;
4704 		SKIP(return, "overlayfs is not supported (setup)");
4705 	}
4706 
4707 	prepare_layout(_metadata);
4708 
4709 	create_directory(_metadata, LOWER_BASE);
4710 	set_cap(_metadata, CAP_SYS_ADMIN);
4711 	/* Creates tmpfs mount points to get deterministic overlayfs. */
4712 	ASSERT_EQ(0, mount_opt(&mnt_tmp, LOWER_BASE));
4713 	clear_cap(_metadata, CAP_SYS_ADMIN);
4714 	create_file(_metadata, lower_fl1);
4715 	create_file(_metadata, lower_dl1_fl2);
4716 	create_file(_metadata, lower_fo1);
4717 	create_file(_metadata, lower_do1_fo2);
4718 	create_file(_metadata, lower_do1_fl3);
4719 
4720 	create_directory(_metadata, UPPER_BASE);
4721 	set_cap(_metadata, CAP_SYS_ADMIN);
4722 	ASSERT_EQ(0, mount_opt(&mnt_tmp, UPPER_BASE));
4723 	clear_cap(_metadata, CAP_SYS_ADMIN);
4724 	create_file(_metadata, upper_fu1);
4725 	create_file(_metadata, upper_du1_fu2);
4726 	create_file(_metadata, upper_fo1);
4727 	create_file(_metadata, upper_do1_fo2);
4728 	create_file(_metadata, upper_do1_fu3);
4729 	ASSERT_EQ(0, mkdir(UPPER_WORK, 0700));
4730 
4731 	create_directory(_metadata, MERGE_DATA);
4732 	set_cap(_metadata, CAP_SYS_ADMIN);
4733 	set_cap(_metadata, CAP_DAC_OVERRIDE);
4734 	ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0,
4735 			   "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA
4736 			   ",workdir=" UPPER_WORK));
4737 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
4738 	clear_cap(_metadata, CAP_SYS_ADMIN);
4739 }
4740 
4741 FIXTURE_TEARDOWN_PARENT(layout2_overlay)
4742 {
4743 	if (self->skip_test)
4744 		SKIP(return, "overlayfs is not supported (teardown)");
4745 
4746 	EXPECT_EQ(0, remove_path(lower_do1_fl3));
4747 	EXPECT_EQ(0, remove_path(lower_dl1_fl2));
4748 	EXPECT_EQ(0, remove_path(lower_fl1));
4749 	EXPECT_EQ(0, remove_path(lower_do1_fo2));
4750 	EXPECT_EQ(0, remove_path(lower_fo1));
4751 
4752 	/* umount(LOWER_BASE)) is handled by namespace lifetime. */
4753 	EXPECT_EQ(0, remove_path(LOWER_BASE));
4754 
4755 	EXPECT_EQ(0, remove_path(upper_do1_fu3));
4756 	EXPECT_EQ(0, remove_path(upper_du1_fu2));
4757 	EXPECT_EQ(0, remove_path(upper_fu1));
4758 	EXPECT_EQ(0, remove_path(upper_do1_fo2));
4759 	EXPECT_EQ(0, remove_path(upper_fo1));
4760 	EXPECT_EQ(0, remove_path(UPPER_WORK "/work"));
4761 
4762 	/* umount(UPPER_BASE)) is handled by namespace lifetime. */
4763 	EXPECT_EQ(0, remove_path(UPPER_BASE));
4764 
4765 	/* umount(MERGE_DATA)) is handled by namespace lifetime. */
4766 	EXPECT_EQ(0, remove_path(MERGE_DATA));
4767 
4768 	cleanup_layout(_metadata);
4769 }
4770 
4771 TEST_F_FORK(layout2_overlay, no_restriction)
4772 {
4773 	if (self->skip_test)
4774 		SKIP(return, "overlayfs is not supported (test)");
4775 
4776 	ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
4777 	ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
4778 	ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
4779 	ASSERT_EQ(0, test_open(lower_fo1, O_RDONLY));
4780 	ASSERT_EQ(0, test_open(lower_do1, O_RDONLY));
4781 	ASSERT_EQ(0, test_open(lower_do1_fo2, O_RDONLY));
4782 	ASSERT_EQ(0, test_open(lower_do1_fl3, O_RDONLY));
4783 
4784 	ASSERT_EQ(0, test_open(upper_fu1, O_RDONLY));
4785 	ASSERT_EQ(0, test_open(upper_du1, O_RDONLY));
4786 	ASSERT_EQ(0, test_open(upper_du1_fu2, O_RDONLY));
4787 	ASSERT_EQ(0, test_open(upper_fo1, O_RDONLY));
4788 	ASSERT_EQ(0, test_open(upper_do1, O_RDONLY));
4789 	ASSERT_EQ(0, test_open(upper_do1_fo2, O_RDONLY));
4790 	ASSERT_EQ(0, test_open(upper_do1_fu3, O_RDONLY));
4791 
4792 	ASSERT_EQ(0, test_open(merge_fl1, O_RDONLY));
4793 	ASSERT_EQ(0, test_open(merge_dl1, O_RDONLY));
4794 	ASSERT_EQ(0, test_open(merge_dl1_fl2, O_RDONLY));
4795 	ASSERT_EQ(0, test_open(merge_fu1, O_RDONLY));
4796 	ASSERT_EQ(0, test_open(merge_du1, O_RDONLY));
4797 	ASSERT_EQ(0, test_open(merge_du1_fu2, O_RDONLY));
4798 	ASSERT_EQ(0, test_open(merge_fo1, O_RDONLY));
4799 	ASSERT_EQ(0, test_open(merge_do1, O_RDONLY));
4800 	ASSERT_EQ(0, test_open(merge_do1_fo2, O_RDONLY));
4801 	ASSERT_EQ(0, test_open(merge_do1_fl3, O_RDONLY));
4802 	ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY));
4803 }
4804 
4805 #define for_each_path(path_list, path_entry, i)               \
4806 	for (i = 0, path_entry = *path_list[i]; path_list[i]; \
4807 	     path_entry = *path_list[++i])
4808 
4809 TEST_F_FORK(layout2_overlay, same_content_different_file)
4810 {
4811 	/* Sets access right on parent directories of both layers. */
4812 	const struct rule layer1_base[] = {
4813 		{
4814 			.path = LOWER_BASE,
4815 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4816 		},
4817 		{
4818 			.path = UPPER_BASE,
4819 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4820 		},
4821 		{
4822 			.path = MERGE_BASE,
4823 			.access = ACCESS_RW,
4824 		},
4825 		{},
4826 	};
4827 	const struct rule layer2_data[] = {
4828 		{
4829 			.path = LOWER_DATA,
4830 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4831 		},
4832 		{
4833 			.path = UPPER_DATA,
4834 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4835 		},
4836 		{
4837 			.path = MERGE_DATA,
4838 			.access = ACCESS_RW,
4839 		},
4840 		{},
4841 	};
4842 	/* Sets access right on directories inside both layers. */
4843 	const struct rule layer3_subdirs[] = {
4844 		{
4845 			.path = lower_dl1,
4846 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4847 		},
4848 		{
4849 			.path = lower_do1,
4850 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4851 		},
4852 		{
4853 			.path = upper_du1,
4854 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4855 		},
4856 		{
4857 			.path = upper_do1,
4858 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4859 		},
4860 		{
4861 			.path = merge_dl1,
4862 			.access = ACCESS_RW,
4863 		},
4864 		{
4865 			.path = merge_du1,
4866 			.access = ACCESS_RW,
4867 		},
4868 		{
4869 			.path = merge_do1,
4870 			.access = ACCESS_RW,
4871 		},
4872 		{},
4873 	};
4874 	/* Tighten access rights to the files. */
4875 	const struct rule layer4_files[] = {
4876 		{
4877 			.path = lower_dl1_fl2,
4878 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4879 		},
4880 		{
4881 			.path = lower_do1_fo2,
4882 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4883 		},
4884 		{
4885 			.path = lower_do1_fl3,
4886 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4887 		},
4888 		{
4889 			.path = upper_du1_fu2,
4890 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4891 		},
4892 		{
4893 			.path = upper_do1_fo2,
4894 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4895 		},
4896 		{
4897 			.path = upper_do1_fu3,
4898 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
4899 		},
4900 		{
4901 			.path = merge_dl1_fl2,
4902 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4903 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4904 		},
4905 		{
4906 			.path = merge_du1_fu2,
4907 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4908 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4909 		},
4910 		{
4911 			.path = merge_do1_fo2,
4912 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4913 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4914 		},
4915 		{
4916 			.path = merge_do1_fl3,
4917 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4918 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4919 		},
4920 		{
4921 			.path = merge_do1_fu3,
4922 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4923 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4924 		},
4925 		{},
4926 	};
4927 	const struct rule layer5_merge_only[] = {
4928 		{
4929 			.path = MERGE_DATA,
4930 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
4931 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
4932 		},
4933 		{},
4934 	};
4935 	int ruleset_fd;
4936 	size_t i;
4937 	const char *path_entry;
4938 
4939 	if (self->skip_test)
4940 		SKIP(return, "overlayfs is not supported (test)");
4941 
4942 	/* Sets rules on base directories (i.e. outside overlay scope). */
4943 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
4944 	ASSERT_LE(0, ruleset_fd);
4945 	enforce_ruleset(_metadata, ruleset_fd);
4946 	ASSERT_EQ(0, close(ruleset_fd));
4947 
4948 	/* Checks lower layer. */
4949 	for_each_path(lower_base_files, path_entry, i) {
4950 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
4951 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
4952 	}
4953 	for_each_path(lower_base_directories, path_entry, i) {
4954 		ASSERT_EQ(EACCES,
4955 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
4956 	}
4957 	for_each_path(lower_sub_files, path_entry, i) {
4958 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
4959 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
4960 	}
4961 	/* Checks upper layer. */
4962 	for_each_path(upper_base_files, path_entry, i) {
4963 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
4964 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
4965 	}
4966 	for_each_path(upper_base_directories, path_entry, i) {
4967 		ASSERT_EQ(EACCES,
4968 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
4969 	}
4970 	for_each_path(upper_sub_files, path_entry, i) {
4971 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
4972 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
4973 	}
4974 	/*
4975 	 * Checks that access rights are independent from the lower and upper
4976 	 * layers: write access to upper files viewed through the merge point
4977 	 * is still allowed, and write access to lower file viewed (and copied)
4978 	 * through the merge point is still allowed.
4979 	 */
4980 	for_each_path(merge_base_files, path_entry, i) {
4981 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
4982 	}
4983 	for_each_path(merge_base_directories, path_entry, i) {
4984 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
4985 	}
4986 	for_each_path(merge_sub_files, path_entry, i) {
4987 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
4988 	}
4989 
4990 	/* Sets rules on data directories (i.e. inside overlay scope). */
4991 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_data);
4992 	ASSERT_LE(0, ruleset_fd);
4993 	enforce_ruleset(_metadata, ruleset_fd);
4994 	ASSERT_EQ(0, close(ruleset_fd));
4995 
4996 	/* Checks merge. */
4997 	for_each_path(merge_base_files, path_entry, i) {
4998 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
4999 	}
5000 	for_each_path(merge_base_directories, path_entry, i) {
5001 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
5002 	}
5003 	for_each_path(merge_sub_files, path_entry, i) {
5004 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
5005 	}
5006 
5007 	/* Same checks with tighter rules. */
5008 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_subdirs);
5009 	ASSERT_LE(0, ruleset_fd);
5010 	enforce_ruleset(_metadata, ruleset_fd);
5011 	ASSERT_EQ(0, close(ruleset_fd));
5012 
5013 	/* Checks changes for lower layer. */
5014 	for_each_path(lower_base_files, path_entry, i) {
5015 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
5016 	}
5017 	/* Checks changes for upper layer. */
5018 	for_each_path(upper_base_files, path_entry, i) {
5019 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
5020 	}
5021 	/* Checks all merge accesses. */
5022 	for_each_path(merge_base_files, path_entry, i) {
5023 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
5024 	}
5025 	for_each_path(merge_base_directories, path_entry, i) {
5026 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
5027 	}
5028 	for_each_path(merge_sub_files, path_entry, i) {
5029 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
5030 	}
5031 
5032 	/* Sets rules directly on overlayed files. */
5033 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_files);
5034 	ASSERT_LE(0, ruleset_fd);
5035 	enforce_ruleset(_metadata, ruleset_fd);
5036 	ASSERT_EQ(0, close(ruleset_fd));
5037 
5038 	/* Checks unchanged accesses on lower layer. */
5039 	for_each_path(lower_sub_files, path_entry, i) {
5040 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
5041 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
5042 	}
5043 	/* Checks unchanged accesses on upper layer. */
5044 	for_each_path(upper_sub_files, path_entry, i) {
5045 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
5046 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
5047 	}
5048 	/* Checks all merge accesses. */
5049 	for_each_path(merge_base_files, path_entry, i) {
5050 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
5051 	}
5052 	for_each_path(merge_base_directories, path_entry, i) {
5053 		ASSERT_EQ(EACCES,
5054 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
5055 	}
5056 	for_each_path(merge_sub_files, path_entry, i) {
5057 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
5058 	}
5059 
5060 	/* Only allowes access to the merge hierarchy. */
5061 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer5_merge_only);
5062 	ASSERT_LE(0, ruleset_fd);
5063 	enforce_ruleset(_metadata, ruleset_fd);
5064 	ASSERT_EQ(0, close(ruleset_fd));
5065 
5066 	/* Checks new accesses on lower layer. */
5067 	for_each_path(lower_sub_files, path_entry, i) {
5068 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
5069 	}
5070 	/* Checks new accesses on upper layer. */
5071 	for_each_path(upper_sub_files, path_entry, i) {
5072 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
5073 	}
5074 	/* Checks all merge accesses. */
5075 	for_each_path(merge_base_files, path_entry, i) {
5076 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
5077 	}
5078 	for_each_path(merge_base_directories, path_entry, i) {
5079 		ASSERT_EQ(EACCES,
5080 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
5081 	}
5082 	for_each_path(merge_sub_files, path_entry, i) {
5083 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
5084 	}
5085 }
5086 
5087 FIXTURE(layout3_fs)
5088 {
5089 	bool has_created_dir;
5090 	bool has_created_file;
5091 	bool skip_test;
5092 };
5093 
5094 FIXTURE_VARIANT(layout3_fs)
5095 {
5096 	const struct mnt_opt mnt;
5097 	const char *const file_path;
5098 	unsigned int cwd_fs_magic;
5099 };
5100 
5101 /* clang-format off */
5102 FIXTURE_VARIANT_ADD(layout3_fs, tmpfs) {
5103 	/* clang-format on */
5104 	.mnt = {
5105 		.type = "tmpfs",
5106 		.data = MNT_TMP_DATA,
5107 	},
5108 	.file_path = file1_s1d1,
5109 };
5110 
5111 FIXTURE_VARIANT_ADD(layout3_fs, ramfs) {
5112 	.mnt = {
5113 		.type = "ramfs",
5114 		.data = "mode=700",
5115 	},
5116 	.file_path = TMP_DIR "/dir/file",
5117 };
5118 
5119 FIXTURE_VARIANT_ADD(layout3_fs, cgroup2) {
5120 	.mnt = {
5121 		.type = "cgroup2",
5122 	},
5123 	.file_path = TMP_DIR "/test/cgroup.procs",
5124 };
5125 
5126 FIXTURE_VARIANT_ADD(layout3_fs, proc) {
5127 	.mnt = {
5128 		.type = "proc",
5129 	},
5130 	.file_path = TMP_DIR "/self/status",
5131 };
5132 
5133 FIXTURE_VARIANT_ADD(layout3_fs, sysfs) {
5134 	.mnt = {
5135 		.type = "sysfs",
5136 	},
5137 	.file_path = TMP_DIR "/kernel/notes",
5138 };
5139 
5140 FIXTURE_VARIANT_ADD(layout3_fs, hostfs) {
5141 	.mnt = {
5142 		.source = TMP_DIR,
5143 		.flags = MS_BIND,
5144 	},
5145 	.file_path = TMP_DIR "/dir/file",
5146 	.cwd_fs_magic = HOSTFS_SUPER_MAGIC,
5147 };
5148 
5149 static char *dirname_alloc(const char *path)
5150 {
5151 	char *dup;
5152 
5153 	if (!path)
5154 		return NULL;
5155 
5156 	dup = strdup(path);
5157 	if (!dup)
5158 		return NULL;
5159 
5160 	return dirname(dup);
5161 }
5162 
5163 FIXTURE_SETUP(layout3_fs)
5164 {
5165 	struct stat statbuf;
5166 	char *dir_path = dirname_alloc(variant->file_path);
5167 
5168 	if (!supports_filesystem(variant->mnt.type) ||
5169 	    !cwd_matches_fs(variant->cwd_fs_magic)) {
5170 		self->skip_test = true;
5171 		SKIP(return, "this filesystem is not supported (setup)");
5172 	}
5173 
5174 	prepare_layout_opt(_metadata, &variant->mnt);
5175 
5176 	/* Creates directory when required. */
5177 	if (stat(dir_path, &statbuf)) {
5178 		set_cap(_metadata, CAP_DAC_OVERRIDE);
5179 		EXPECT_EQ(0, mkdir(dir_path, 0700))
5180 		{
5181 			TH_LOG("Failed to create directory \"%s\": %s",
5182 			       dir_path, strerror(errno));
5183 		}
5184 		self->has_created_dir = true;
5185 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
5186 	}
5187 
5188 	/* Creates file when required. */
5189 	if (stat(variant->file_path, &statbuf)) {
5190 		int fd;
5191 
5192 		set_cap(_metadata, CAP_DAC_OVERRIDE);
5193 		fd = creat(variant->file_path, 0600);
5194 		EXPECT_LE(0, fd)
5195 		{
5196 			TH_LOG("Failed to create file \"%s\": %s",
5197 			       variant->file_path, strerror(errno));
5198 		}
5199 		EXPECT_EQ(0, close(fd));
5200 		self->has_created_file = true;
5201 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
5202 	}
5203 
5204 	free(dir_path);
5205 }
5206 
5207 FIXTURE_TEARDOWN_PARENT(layout3_fs)
5208 {
5209 	if (self->skip_test)
5210 		SKIP(return, "this filesystem is not supported (teardown)");
5211 
5212 	if (self->has_created_file) {
5213 		set_cap(_metadata, CAP_DAC_OVERRIDE);
5214 		/*
5215 		 * Don't check for error because the file might already
5216 		 * have been removed (cf. release_inode test).
5217 		 */
5218 		unlink(variant->file_path);
5219 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
5220 	}
5221 
5222 	if (self->has_created_dir) {
5223 		char *dir_path = dirname_alloc(variant->file_path);
5224 
5225 		set_cap(_metadata, CAP_DAC_OVERRIDE);
5226 		/*
5227 		 * Don't check for error because the directory might already
5228 		 * have been removed (cf. release_inode test).
5229 		 */
5230 		rmdir(dir_path);
5231 		clear_cap(_metadata, CAP_DAC_OVERRIDE);
5232 		free(dir_path);
5233 	}
5234 
5235 	cleanup_layout(_metadata);
5236 }
5237 
5238 static void layer3_fs_tag_inode(struct __test_metadata *const _metadata,
5239 				FIXTURE_DATA(layout3_fs) * self,
5240 				const FIXTURE_VARIANT(layout3_fs) * variant,
5241 				const char *const rule_path)
5242 {
5243 	const struct rule layer1_allow_read_file[] = {
5244 		{
5245 			.path = rule_path,
5246 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
5247 		},
5248 		{},
5249 	};
5250 	const struct landlock_ruleset_attr layer2_deny_everything_attr = {
5251 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
5252 	};
5253 	const char *const dev_null_path = "/dev/null";
5254 	int ruleset_fd;
5255 
5256 	if (self->skip_test)
5257 		SKIP(return, "this filesystem is not supported (test)");
5258 
5259 	/* Checks without Landlock. */
5260 	EXPECT_EQ(0, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
5261 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
5262 
5263 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
5264 				    layer1_allow_read_file);
5265 	EXPECT_LE(0, ruleset_fd);
5266 	enforce_ruleset(_metadata, ruleset_fd);
5267 	EXPECT_EQ(0, close(ruleset_fd));
5268 
5269 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
5270 	EXPECT_EQ(0, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
5271 
5272 	/* Forbids directory reading. */
5273 	ruleset_fd =
5274 		landlock_create_ruleset(&layer2_deny_everything_attr,
5275 					sizeof(layer2_deny_everything_attr), 0);
5276 	EXPECT_LE(0, ruleset_fd);
5277 	enforce_ruleset(_metadata, ruleset_fd);
5278 	EXPECT_EQ(0, close(ruleset_fd));
5279 
5280 	/* Checks with Landlock and forbidden access. */
5281 	EXPECT_EQ(EACCES, test_open(dev_null_path, O_RDONLY | O_CLOEXEC));
5282 	EXPECT_EQ(EACCES, test_open(variant->file_path, O_RDONLY | O_CLOEXEC));
5283 }
5284 
5285 /* Matrix of tests to check file hierarchy evaluation. */
5286 
5287 TEST_F_FORK(layout3_fs, tag_inode_dir_parent)
5288 {
5289 	/* The current directory must not be the root for this test. */
5290 	layer3_fs_tag_inode(_metadata, self, variant, ".");
5291 }
5292 
5293 TEST_F_FORK(layout3_fs, tag_inode_dir_mnt)
5294 {
5295 	layer3_fs_tag_inode(_metadata, self, variant, TMP_DIR);
5296 }
5297 
5298 TEST_F_FORK(layout3_fs, tag_inode_dir_child)
5299 {
5300 	char *dir_path = dirname_alloc(variant->file_path);
5301 
5302 	layer3_fs_tag_inode(_metadata, self, variant, dir_path);
5303 	free(dir_path);
5304 }
5305 
5306 TEST_F_FORK(layout3_fs, tag_inode_file)
5307 {
5308 	layer3_fs_tag_inode(_metadata, self, variant, variant->file_path);
5309 }
5310 
5311 /* Light version of layout1.release_inodes */
5312 TEST_F_FORK(layout3_fs, release_inodes)
5313 {
5314 	const struct rule layer1[] = {
5315 		{
5316 			.path = TMP_DIR,
5317 			.access = LANDLOCK_ACCESS_FS_READ_DIR,
5318 		},
5319 		{},
5320 	};
5321 	int ruleset_fd;
5322 
5323 	if (self->skip_test)
5324 		SKIP(return, "this filesystem is not supported (test)");
5325 
5326 	/* Clean up for the teardown to not fail. */
5327 	if (self->has_created_file)
5328 		EXPECT_EQ(0, remove_path(variant->file_path));
5329 
5330 	if (self->has_created_dir) {
5331 		char *dir_path = dirname_alloc(variant->file_path);
5332 
5333 		/* Don't check for error because of cgroup specificities. */
5334 		remove_path(dir_path);
5335 		free(dir_path);
5336 	}
5337 
5338 	ruleset_fd =
5339 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
5340 	ASSERT_LE(0, ruleset_fd);
5341 
5342 	/* Unmount the filesystem while it is being used by a ruleset. */
5343 	set_cap(_metadata, CAP_SYS_ADMIN);
5344 	ASSERT_EQ(0, umount(TMP_DIR));
5345 	clear_cap(_metadata, CAP_SYS_ADMIN);
5346 
5347 	/* Replaces with a new mount point to simplify FIXTURE_TEARDOWN. */
5348 	set_cap(_metadata, CAP_SYS_ADMIN);
5349 	ASSERT_EQ(0, mount_opt(&mnt_tmp, TMP_DIR));
5350 	clear_cap(_metadata, CAP_SYS_ADMIN);
5351 
5352 	enforce_ruleset(_metadata, ruleset_fd);
5353 	ASSERT_EQ(0, close(ruleset_fd));
5354 
5355 	/* Checks that access to the new mount point is denied. */
5356 	ASSERT_EQ(EACCES, test_open(TMP_DIR, O_RDONLY));
5357 }
5358 
5359 TEST_HARNESS_MAIN
5360