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