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