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