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