1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Landlock tests - Filesystem
4  *
5  * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
6  * Copyright © 2020 ANSSI
7  * Copyright © 2020-2021 Microsoft Corporation
8  */
9 
10 #define _GNU_SOURCE
11 #include <fcntl.h>
12 #include <linux/landlock.h>
13 #include <sched.h>
14 #include <string.h>
15 #include <sys/capability.h>
16 #include <sys/mount.h>
17 #include <sys/prctl.h>
18 #include <sys/sendfile.h>
19 #include <sys/stat.h>
20 #include <sys/sysmacros.h>
21 #include <unistd.h>
22 
23 #include "common.h"
24 
25 #ifndef renameat2
26 int renameat2(int olddirfd, const char *oldpath, int newdirfd,
27 	      const char *newpath, unsigned int flags)
28 {
29 	return syscall(__NR_renameat2, olddirfd, oldpath, newdirfd, newpath,
30 		       flags);
31 }
32 #endif
33 
34 #ifndef RENAME_EXCHANGE
35 #define RENAME_EXCHANGE (1 << 1)
36 #endif
37 
38 #define TMP_DIR "tmp"
39 #define BINARY_PATH "./true"
40 
41 /* Paths (sibling number and depth) */
42 static const char dir_s1d1[] = TMP_DIR "/s1d1";
43 static const char file1_s1d1[] = TMP_DIR "/s1d1/f1";
44 static const char file2_s1d1[] = TMP_DIR "/s1d1/f2";
45 static const char dir_s1d2[] = TMP_DIR "/s1d1/s1d2";
46 static const char file1_s1d2[] = TMP_DIR "/s1d1/s1d2/f1";
47 static const char file2_s1d2[] = TMP_DIR "/s1d1/s1d2/f2";
48 static const char dir_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3";
49 static const char file1_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f1";
50 static const char file2_s1d3[] = TMP_DIR "/s1d1/s1d2/s1d3/f2";
51 
52 static const char dir_s2d1[] = TMP_DIR "/s2d1";
53 static const char file1_s2d1[] = TMP_DIR "/s2d1/f1";
54 static const char dir_s2d2[] = TMP_DIR "/s2d1/s2d2";
55 static const char file1_s2d2[] = TMP_DIR "/s2d1/s2d2/f1";
56 static const char dir_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3";
57 static const char file1_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f1";
58 static const char file2_s2d3[] = TMP_DIR "/s2d1/s2d2/s2d3/f2";
59 
60 static const char dir_s3d1[] = TMP_DIR "/s3d1";
61 /* dir_s3d2 is a mount point. */
62 static const char dir_s3d2[] = TMP_DIR "/s3d1/s3d2";
63 static const char dir_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3";
64 
65 /*
66  * layout1 hierarchy:
67  *
68  * tmp
69  * ├── s1d1
70  * │   ├── f1
71  * │   ├── f2
72  * │   └── s1d2
73  * │       ├── f1
74  * │       ├── f2
75  * │       └── s1d3
76  * │           ├── f1
77  * │           └── f2
78  * ├── s2d1
79  * │   ├── f1
80  * │   └── s2d2
81  * │       ├── f1
82  * │       └── s2d3
83  * │           ├── f1
84  * │           └── f2
85  * └── s3d1
86  *     └── s3d2
87  *         └── s3d3
88  */
89 
90 static void mkdir_parents(struct __test_metadata *const _metadata,
91 			  const char *const path)
92 {
93 	char *walker;
94 	const char *parent;
95 	int i, err;
96 
97 	ASSERT_NE(path[0], '\0');
98 	walker = strdup(path);
99 	ASSERT_NE(NULL, walker);
100 	parent = walker;
101 	for (i = 1; walker[i]; i++) {
102 		if (walker[i] != '/')
103 			continue;
104 		walker[i] = '\0';
105 		err = mkdir(parent, 0700);
106 		ASSERT_FALSE(err && errno != EEXIST)
107 		{
108 			TH_LOG("Failed to create directory \"%s\": %s", parent,
109 			       strerror(errno));
110 		}
111 		walker[i] = '/';
112 	}
113 	free(walker);
114 }
115 
116 static void create_directory(struct __test_metadata *const _metadata,
117 			     const char *const path)
118 {
119 	mkdir_parents(_metadata, path);
120 	ASSERT_EQ(0, mkdir(path, 0700))
121 	{
122 		TH_LOG("Failed to create directory \"%s\": %s", path,
123 		       strerror(errno));
124 	}
125 }
126 
127 static void create_file(struct __test_metadata *const _metadata,
128 			const char *const path)
129 {
130 	mkdir_parents(_metadata, path);
131 	ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0))
132 	{
133 		TH_LOG("Failed to create file \"%s\": %s", path,
134 		       strerror(errno));
135 	}
136 }
137 
138 static int remove_path(const char *const path)
139 {
140 	char *walker;
141 	int i, ret, err = 0;
142 
143 	walker = strdup(path);
144 	if (!walker) {
145 		err = ENOMEM;
146 		goto out;
147 	}
148 	if (unlink(path) && rmdir(path)) {
149 		if (errno != ENOENT)
150 			err = errno;
151 		goto out;
152 	}
153 	for (i = strlen(walker); i > 0; i--) {
154 		if (walker[i] != '/')
155 			continue;
156 		walker[i] = '\0';
157 		ret = rmdir(walker);
158 		if (ret) {
159 			if (errno != ENOTEMPTY && errno != EBUSY)
160 				err = errno;
161 			goto out;
162 		}
163 		if (strcmp(walker, TMP_DIR) == 0)
164 			goto out;
165 	}
166 
167 out:
168 	free(walker);
169 	return err;
170 }
171 
172 static void prepare_layout(struct __test_metadata *const _metadata)
173 {
174 	disable_caps(_metadata);
175 	umask(0077);
176 	create_directory(_metadata, TMP_DIR);
177 
178 	/*
179 	 * Do not pollute the rest of the system: creates a private mount point
180 	 * for tests relying on pivot_root(2) and move_mount(2).
181 	 */
182 	set_cap(_metadata, CAP_SYS_ADMIN);
183 	ASSERT_EQ(0, unshare(CLONE_NEWNS));
184 	ASSERT_EQ(0, mount("tmp", TMP_DIR, "tmpfs", 0, "size=4m,mode=700"));
185 	ASSERT_EQ(0, mount(NULL, TMP_DIR, NULL, MS_PRIVATE | MS_REC, NULL));
186 	clear_cap(_metadata, CAP_SYS_ADMIN);
187 }
188 
189 static void cleanup_layout(struct __test_metadata *const _metadata)
190 {
191 	set_cap(_metadata, CAP_SYS_ADMIN);
192 	EXPECT_EQ(0, umount(TMP_DIR));
193 	clear_cap(_metadata, CAP_SYS_ADMIN);
194 	EXPECT_EQ(0, remove_path(TMP_DIR));
195 }
196 
197 static void create_layout1(struct __test_metadata *const _metadata)
198 {
199 	create_file(_metadata, file1_s1d1);
200 	create_file(_metadata, file1_s1d2);
201 	create_file(_metadata, file1_s1d3);
202 	create_file(_metadata, file2_s1d1);
203 	create_file(_metadata, file2_s1d2);
204 	create_file(_metadata, file2_s1d3);
205 
206 	create_file(_metadata, file1_s2d1);
207 	create_file(_metadata, file1_s2d2);
208 	create_file(_metadata, file1_s2d3);
209 	create_file(_metadata, file2_s2d3);
210 
211 	create_directory(_metadata, dir_s3d2);
212 	set_cap(_metadata, CAP_SYS_ADMIN);
213 	ASSERT_EQ(0, mount("tmp", dir_s3d2, "tmpfs", 0, "size=4m,mode=700"));
214 	clear_cap(_metadata, CAP_SYS_ADMIN);
215 
216 	ASSERT_EQ(0, mkdir(dir_s3d3, 0700));
217 }
218 
219 static void remove_layout1(struct __test_metadata *const _metadata)
220 {
221 	EXPECT_EQ(0, remove_path(file2_s1d3));
222 	EXPECT_EQ(0, remove_path(file2_s1d2));
223 	EXPECT_EQ(0, remove_path(file2_s1d1));
224 	EXPECT_EQ(0, remove_path(file1_s1d3));
225 	EXPECT_EQ(0, remove_path(file1_s1d2));
226 	EXPECT_EQ(0, remove_path(file1_s1d1));
227 
228 	EXPECT_EQ(0, remove_path(file2_s2d3));
229 	EXPECT_EQ(0, remove_path(file1_s2d3));
230 	EXPECT_EQ(0, remove_path(file1_s2d2));
231 	EXPECT_EQ(0, remove_path(file1_s2d1));
232 
233 	EXPECT_EQ(0, remove_path(dir_s3d3));
234 	set_cap(_metadata, CAP_SYS_ADMIN);
235 	umount(dir_s3d2);
236 	clear_cap(_metadata, CAP_SYS_ADMIN);
237 	EXPECT_EQ(0, remove_path(dir_s3d2));
238 }
239 
240 /* clang-format off */
241 FIXTURE(layout1) {};
242 /* clang-format on */
243 
244 FIXTURE_SETUP(layout1)
245 {
246 	prepare_layout(_metadata);
247 
248 	create_layout1(_metadata);
249 }
250 
251 FIXTURE_TEARDOWN(layout1)
252 {
253 	remove_layout1(_metadata);
254 
255 	cleanup_layout(_metadata);
256 }
257 
258 /*
259  * This helper enables to use the ASSERT_* macros and print the line number
260  * pointing to the test caller.
261  */
262 static int test_open_rel(const int dirfd, const char *const path,
263 			 const int flags)
264 {
265 	int fd;
266 
267 	/* Works with file and directories. */
268 	fd = openat(dirfd, path, flags | O_CLOEXEC);
269 	if (fd < 0)
270 		return errno;
271 	/*
272 	 * Mixing error codes from close(2) and open(2) should not lead to any
273 	 * (access type) confusion for this test.
274 	 */
275 	if (close(fd) != 0)
276 		return errno;
277 	return 0;
278 }
279 
280 static int test_open(const char *const path, const int flags)
281 {
282 	return test_open_rel(AT_FDCWD, path, flags);
283 }
284 
285 TEST_F_FORK(layout1, no_restriction)
286 {
287 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
288 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
289 	ASSERT_EQ(0, test_open(file2_s1d1, O_RDONLY));
290 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
291 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
292 	ASSERT_EQ(0, test_open(file2_s1d2, O_RDONLY));
293 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
294 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
295 
296 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
297 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
298 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
299 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
300 	ASSERT_EQ(0, test_open(dir_s2d3, O_RDONLY));
301 	ASSERT_EQ(0, test_open(file1_s2d3, O_RDONLY));
302 
303 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
304 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
305 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
306 }
307 
308 TEST_F_FORK(layout1, inval)
309 {
310 	struct landlock_path_beneath_attr path_beneath = {
311 		.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
312 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
313 		.parent_fd = -1,
314 	};
315 	struct landlock_ruleset_attr ruleset_attr = {
316 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE |
317 				     LANDLOCK_ACCESS_FS_WRITE_FILE,
318 	};
319 	int ruleset_fd;
320 
321 	path_beneath.parent_fd =
322 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
323 	ASSERT_LE(0, path_beneath.parent_fd);
324 
325 	ruleset_fd = open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC);
326 	ASSERT_LE(0, ruleset_fd);
327 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
328 					&path_beneath, 0));
329 	/* Returns EBADF because ruleset_fd is not a landlock-ruleset FD. */
330 	ASSERT_EQ(EBADF, errno);
331 	ASSERT_EQ(0, close(ruleset_fd));
332 
333 	ruleset_fd = open(dir_s1d1, O_DIRECTORY | O_CLOEXEC);
334 	ASSERT_LE(0, ruleset_fd);
335 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
336 					&path_beneath, 0));
337 	/* Returns EBADFD because ruleset_fd is not a valid ruleset. */
338 	ASSERT_EQ(EBADFD, errno);
339 	ASSERT_EQ(0, close(ruleset_fd));
340 
341 	/* Gets a real ruleset. */
342 	ruleset_fd =
343 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
344 	ASSERT_LE(0, ruleset_fd);
345 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
346 				       &path_beneath, 0));
347 	ASSERT_EQ(0, close(path_beneath.parent_fd));
348 
349 	/* Tests without O_PATH. */
350 	path_beneath.parent_fd = open(dir_s1d2, O_DIRECTORY | O_CLOEXEC);
351 	ASSERT_LE(0, path_beneath.parent_fd);
352 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
353 				       &path_beneath, 0));
354 	ASSERT_EQ(0, close(path_beneath.parent_fd));
355 
356 	/* Tests with a ruleset FD. */
357 	path_beneath.parent_fd = ruleset_fd;
358 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
359 					&path_beneath, 0));
360 	ASSERT_EQ(EBADFD, errno);
361 
362 	/* Checks unhandled allowed_access. */
363 	path_beneath.parent_fd =
364 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
365 	ASSERT_LE(0, path_beneath.parent_fd);
366 
367 	/* Test with legitimate values. */
368 	path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_EXECUTE;
369 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
370 					&path_beneath, 0));
371 	ASSERT_EQ(EINVAL, errno);
372 	path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_EXECUTE;
373 
374 	/* Test with unknown (64-bits) value. */
375 	path_beneath.allowed_access |= (1ULL << 60);
376 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
377 					&path_beneath, 0));
378 	ASSERT_EQ(EINVAL, errno);
379 	path_beneath.allowed_access &= ~(1ULL << 60);
380 
381 	/* Test with no access. */
382 	path_beneath.allowed_access = 0;
383 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
384 					&path_beneath, 0));
385 	ASSERT_EQ(ENOMSG, errno);
386 	path_beneath.allowed_access &= ~(1ULL << 60);
387 
388 	ASSERT_EQ(0, close(path_beneath.parent_fd));
389 
390 	/* Enforces the ruleset. */
391 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
392 	ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
393 
394 	ASSERT_EQ(0, close(ruleset_fd));
395 }
396 
397 /* clang-format off */
398 
399 #define ACCESS_FILE ( \
400 	LANDLOCK_ACCESS_FS_EXECUTE | \
401 	LANDLOCK_ACCESS_FS_WRITE_FILE | \
402 	LANDLOCK_ACCESS_FS_READ_FILE)
403 
404 #define ACCESS_LAST LANDLOCK_ACCESS_FS_MAKE_SYM
405 
406 #define ACCESS_ALL ( \
407 	ACCESS_FILE | \
408 	LANDLOCK_ACCESS_FS_READ_DIR | \
409 	LANDLOCK_ACCESS_FS_REMOVE_DIR | \
410 	LANDLOCK_ACCESS_FS_REMOVE_FILE | \
411 	LANDLOCK_ACCESS_FS_MAKE_CHAR | \
412 	LANDLOCK_ACCESS_FS_MAKE_DIR | \
413 	LANDLOCK_ACCESS_FS_MAKE_REG | \
414 	LANDLOCK_ACCESS_FS_MAKE_SOCK | \
415 	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
416 	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
417 	ACCESS_LAST)
418 
419 /* clang-format on */
420 
421 TEST_F_FORK(layout1, file_and_dir_access_rights)
422 {
423 	__u64 access;
424 	int err;
425 	struct landlock_path_beneath_attr path_beneath_file = {},
426 					  path_beneath_dir = {};
427 	struct landlock_ruleset_attr ruleset_attr = {
428 		.handled_access_fs = ACCESS_ALL,
429 	};
430 	const int ruleset_fd =
431 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
432 
433 	ASSERT_LE(0, ruleset_fd);
434 
435 	/* Tests access rights for files. */
436 	path_beneath_file.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
437 	ASSERT_LE(0, path_beneath_file.parent_fd);
438 
439 	/* Tests access rights for directories. */
440 	path_beneath_dir.parent_fd =
441 		open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
442 	ASSERT_LE(0, path_beneath_dir.parent_fd);
443 
444 	for (access = 1; access <= ACCESS_LAST; access <<= 1) {
445 		path_beneath_dir.allowed_access = access;
446 		ASSERT_EQ(0, landlock_add_rule(ruleset_fd,
447 					       LANDLOCK_RULE_PATH_BENEATH,
448 					       &path_beneath_dir, 0));
449 
450 		path_beneath_file.allowed_access = access;
451 		err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
452 					&path_beneath_file, 0);
453 		if (access & ACCESS_FILE) {
454 			ASSERT_EQ(0, err);
455 		} else {
456 			ASSERT_EQ(-1, err);
457 			ASSERT_EQ(EINVAL, errno);
458 		}
459 	}
460 	ASSERT_EQ(0, close(path_beneath_file.parent_fd));
461 	ASSERT_EQ(0, close(path_beneath_dir.parent_fd));
462 	ASSERT_EQ(0, close(ruleset_fd));
463 }
464 
465 TEST_F_FORK(layout1, unknown_access_rights)
466 {
467 	__u64 access_mask;
468 
469 	for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST;
470 	     access_mask >>= 1) {
471 		struct landlock_ruleset_attr ruleset_attr = {
472 			.handled_access_fs = access_mask,
473 		};
474 
475 		ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr,
476 						      sizeof(ruleset_attr), 0));
477 		ASSERT_EQ(EINVAL, errno);
478 	}
479 }
480 
481 static void add_path_beneath(struct __test_metadata *const _metadata,
482 			     const int ruleset_fd, const __u64 allowed_access,
483 			     const char *const path)
484 {
485 	struct landlock_path_beneath_attr path_beneath = {
486 		.allowed_access = allowed_access,
487 	};
488 
489 	path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC);
490 	ASSERT_LE(0, path_beneath.parent_fd)
491 	{
492 		TH_LOG("Failed to open directory \"%s\": %s", path,
493 		       strerror(errno));
494 	}
495 	ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
496 				       &path_beneath, 0))
497 	{
498 		TH_LOG("Failed to update the ruleset with \"%s\": %s", path,
499 		       strerror(errno));
500 	}
501 	ASSERT_EQ(0, close(path_beneath.parent_fd));
502 }
503 
504 struct rule {
505 	const char *path;
506 	__u64 access;
507 };
508 
509 /* clang-format off */
510 
511 #define ACCESS_RO ( \
512 	LANDLOCK_ACCESS_FS_READ_FILE | \
513 	LANDLOCK_ACCESS_FS_READ_DIR)
514 
515 #define ACCESS_RW ( \
516 	ACCESS_RO | \
517 	LANDLOCK_ACCESS_FS_WRITE_FILE)
518 
519 /* clang-format on */
520 
521 static int create_ruleset(struct __test_metadata *const _metadata,
522 			  const __u64 handled_access_fs,
523 			  const struct rule rules[])
524 {
525 	int ruleset_fd, i;
526 	struct landlock_ruleset_attr ruleset_attr = {
527 		.handled_access_fs = handled_access_fs,
528 	};
529 
530 	ASSERT_NE(NULL, rules)
531 	{
532 		TH_LOG("No rule list");
533 	}
534 	ASSERT_NE(NULL, rules[0].path)
535 	{
536 		TH_LOG("Empty rule list");
537 	}
538 
539 	ruleset_fd =
540 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
541 	ASSERT_LE(0, ruleset_fd)
542 	{
543 		TH_LOG("Failed to create a ruleset: %s", strerror(errno));
544 	}
545 
546 	for (i = 0; rules[i].path; i++) {
547 		add_path_beneath(_metadata, ruleset_fd, rules[i].access,
548 				 rules[i].path);
549 	}
550 	return ruleset_fd;
551 }
552 
553 static void enforce_ruleset(struct __test_metadata *const _metadata,
554 			    const int ruleset_fd)
555 {
556 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
557 	ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0))
558 	{
559 		TH_LOG("Failed to enforce ruleset: %s", strerror(errno));
560 	}
561 }
562 
563 TEST_F_FORK(layout1, proc_nsfs)
564 {
565 	const struct rule rules[] = {
566 		{
567 			.path = "/dev/null",
568 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
569 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
570 		},
571 		{},
572 	};
573 	struct landlock_path_beneath_attr path_beneath;
574 	const int ruleset_fd = create_ruleset(
575 		_metadata, rules[0].access | LANDLOCK_ACCESS_FS_READ_DIR,
576 		rules);
577 
578 	ASSERT_LE(0, ruleset_fd);
579 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
580 
581 	enforce_ruleset(_metadata, ruleset_fd);
582 
583 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
584 	ASSERT_EQ(EACCES, test_open("/dev", O_RDONLY));
585 	ASSERT_EQ(0, test_open("/dev/null", O_RDONLY));
586 	ASSERT_EQ(EACCES, test_open("/dev/full", O_RDONLY));
587 
588 	ASSERT_EQ(EACCES, test_open("/proc", O_RDONLY));
589 	ASSERT_EQ(EACCES, test_open("/proc/self", O_RDONLY));
590 	ASSERT_EQ(EACCES, test_open("/proc/self/ns", O_RDONLY));
591 	/*
592 	 * Because nsfs is an internal filesystem, /proc/self/ns/mnt is a
593 	 * disconnected path.  Such path cannot be identified and must then be
594 	 * allowed.
595 	 */
596 	ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY));
597 
598 	/*
599 	 * Checks that it is not possible to add nsfs-like filesystem
600 	 * references to a ruleset.
601 	 */
602 	path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
603 				      LANDLOCK_ACCESS_FS_WRITE_FILE,
604 	path_beneath.parent_fd = open("/proc/self/ns/mnt", O_PATH | O_CLOEXEC);
605 	ASSERT_LE(0, path_beneath.parent_fd);
606 	ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
607 					&path_beneath, 0));
608 	ASSERT_EQ(EBADFD, errno);
609 	ASSERT_EQ(0, close(path_beneath.parent_fd));
610 }
611 
612 TEST_F_FORK(layout1, unpriv)
613 {
614 	const struct rule rules[] = {
615 		{
616 			.path = dir_s1d2,
617 			.access = ACCESS_RO,
618 		},
619 		{},
620 	};
621 	int ruleset_fd;
622 
623 	drop_caps(_metadata);
624 
625 	ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules);
626 	ASSERT_LE(0, ruleset_fd);
627 	ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
628 	ASSERT_EQ(EPERM, errno);
629 
630 	/* enforce_ruleset() calls prctl(no_new_privs). */
631 	enforce_ruleset(_metadata, ruleset_fd);
632 	ASSERT_EQ(0, close(ruleset_fd));
633 }
634 
635 TEST_F_FORK(layout1, effective_access)
636 {
637 	const struct rule rules[] = {
638 		{
639 			.path = dir_s1d2,
640 			.access = ACCESS_RO,
641 		},
642 		{
643 			.path = file1_s2d2,
644 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
645 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
646 		},
647 		{},
648 	};
649 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
650 	char buf;
651 	int reg_fd;
652 
653 	ASSERT_LE(0, ruleset_fd);
654 	enforce_ruleset(_metadata, ruleset_fd);
655 	ASSERT_EQ(0, close(ruleset_fd));
656 
657 	/* Tests on a directory (with or without O_PATH). */
658 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
659 	ASSERT_EQ(0, test_open("/", O_RDONLY | O_PATH));
660 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
661 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_PATH));
662 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
663 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY | O_PATH));
664 
665 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
666 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
667 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
668 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
669 
670 	/* Tests on a file (with or without O_PATH). */
671 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY));
672 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_PATH));
673 
674 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
675 
676 	/* Checks effective read and write actions. */
677 	reg_fd = open(file1_s2d2, O_RDWR | O_CLOEXEC);
678 	ASSERT_LE(0, reg_fd);
679 	ASSERT_EQ(1, write(reg_fd, ".", 1));
680 	ASSERT_LE(0, lseek(reg_fd, 0, SEEK_SET));
681 	ASSERT_EQ(1, read(reg_fd, &buf, 1));
682 	ASSERT_EQ('.', buf);
683 	ASSERT_EQ(0, close(reg_fd));
684 
685 	/* Just in case, double-checks effective actions. */
686 	reg_fd = open(file1_s2d2, O_RDONLY | O_CLOEXEC);
687 	ASSERT_LE(0, reg_fd);
688 	ASSERT_EQ(-1, write(reg_fd, &buf, 1));
689 	ASSERT_EQ(EBADF, errno);
690 	ASSERT_EQ(0, close(reg_fd));
691 }
692 
693 TEST_F_FORK(layout1, unhandled_access)
694 {
695 	const struct rule rules[] = {
696 		{
697 			.path = dir_s1d2,
698 			.access = ACCESS_RO,
699 		},
700 		{},
701 	};
702 	/* Here, we only handle read accesses, not write accesses. */
703 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules);
704 
705 	ASSERT_LE(0, ruleset_fd);
706 	enforce_ruleset(_metadata, ruleset_fd);
707 	ASSERT_EQ(0, close(ruleset_fd));
708 
709 	/*
710 	 * Because the policy does not handle LANDLOCK_ACCESS_FS_WRITE_FILE,
711 	 * opening for write-only should be allowed, but not read-write.
712 	 */
713 	ASSERT_EQ(0, test_open(file1_s1d1, O_WRONLY));
714 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
715 
716 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
717 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
718 }
719 
720 TEST_F_FORK(layout1, ruleset_overlap)
721 {
722 	const struct rule rules[] = {
723 		/* These rules should be ORed among them. */
724 		{
725 			.path = dir_s1d2,
726 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
727 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
728 		},
729 		{
730 			.path = dir_s1d2,
731 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
732 				  LANDLOCK_ACCESS_FS_READ_DIR,
733 		},
734 		{},
735 	};
736 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
737 
738 	ASSERT_LE(0, ruleset_fd);
739 	enforce_ruleset(_metadata, ruleset_fd);
740 	ASSERT_EQ(0, close(ruleset_fd));
741 
742 	/* Checks s1d1 hierarchy. */
743 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
744 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
745 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
746 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
747 
748 	/* Checks s1d2 hierarchy. */
749 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
750 	ASSERT_EQ(0, test_open(file1_s1d2, O_WRONLY));
751 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
752 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
753 
754 	/* Checks s1d3 hierarchy. */
755 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
756 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
757 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
758 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
759 }
760 
761 TEST_F_FORK(layout1, non_overlapping_accesses)
762 {
763 	const struct rule layer1[] = {
764 		{
765 			.path = dir_s1d2,
766 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
767 		},
768 		{},
769 	};
770 	const struct rule layer2[] = {
771 		{
772 			.path = dir_s1d3,
773 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
774 		},
775 		{},
776 	};
777 	int ruleset_fd;
778 
779 	ASSERT_EQ(0, unlink(file1_s1d1));
780 	ASSERT_EQ(0, unlink(file1_s1d2));
781 
782 	ruleset_fd =
783 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1);
784 	ASSERT_LE(0, ruleset_fd);
785 	enforce_ruleset(_metadata, ruleset_fd);
786 	ASSERT_EQ(0, close(ruleset_fd));
787 
788 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
789 	ASSERT_EQ(EACCES, errno);
790 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
791 	ASSERT_EQ(0, unlink(file1_s1d2));
792 
793 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE,
794 				    layer2);
795 	ASSERT_LE(0, ruleset_fd);
796 	enforce_ruleset(_metadata, ruleset_fd);
797 	ASSERT_EQ(0, close(ruleset_fd));
798 
799 	/* Unchanged accesses for file creation. */
800 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
801 	ASSERT_EQ(EACCES, errno);
802 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
803 
804 	/* Checks file removing. */
805 	ASSERT_EQ(-1, unlink(file1_s1d2));
806 	ASSERT_EQ(EACCES, errno);
807 	ASSERT_EQ(0, unlink(file1_s1d3));
808 }
809 
810 TEST_F_FORK(layout1, interleaved_masked_accesses)
811 {
812 	/*
813 	 * Checks overly restrictive rules:
814 	 * layer 1: allows R   s1d1/s1d2/s1d3/file1
815 	 * layer 2: allows RW  s1d1/s1d2/s1d3
816 	 *          allows  W  s1d1/s1d2
817 	 *          denies R   s1d1/s1d2
818 	 * layer 3: allows R   s1d1
819 	 * layer 4: allows R   s1d1/s1d2
820 	 *          denies  W  s1d1/s1d2
821 	 * layer 5: allows R   s1d1/s1d2
822 	 * layer 6: allows   X ----
823 	 * layer 7: allows  W  s1d1/s1d2
824 	 *          denies R   s1d1/s1d2
825 	 */
826 	const struct rule layer1_read[] = {
827 		/* Allows read access to file1_s1d3 with the first layer. */
828 		{
829 			.path = file1_s1d3,
830 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
831 		},
832 		{},
833 	};
834 	/* First rule with write restrictions. */
835 	const struct rule layer2_read_write[] = {
836 		/* Start by granting read-write access via its parent directory... */
837 		{
838 			.path = dir_s1d3,
839 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
840 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
841 		},
842 		/* ...but also denies read access via its grandparent directory. */
843 		{
844 			.path = dir_s1d2,
845 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
846 		},
847 		{},
848 	};
849 	const struct rule layer3_read[] = {
850 		/* Allows read access via its great-grandparent directory. */
851 		{
852 			.path = dir_s1d1,
853 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
854 		},
855 		{},
856 	};
857 	const struct rule layer4_read_write[] = {
858 		/*
859 		 * Try to confuse the deny access by denying write (but not
860 		 * read) access via its grandparent directory.
861 		 */
862 		{
863 			.path = dir_s1d2,
864 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
865 		},
866 		{},
867 	};
868 	const struct rule layer5_read[] = {
869 		/*
870 		 * Try to override layer2's deny read access by explicitly
871 		 * allowing read access via file1_s1d3's grandparent.
872 		 */
873 		{
874 			.path = dir_s1d2,
875 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
876 		},
877 		{},
878 	};
879 	const struct rule layer6_execute[] = {
880 		/*
881 		 * Restricts an unrelated file hierarchy with a new access
882 		 * (non-overlapping) type.
883 		 */
884 		{
885 			.path = dir_s2d1,
886 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
887 		},
888 		{},
889 	};
890 	const struct rule layer7_read_write[] = {
891 		/*
892 		 * Finally, denies read access to file1_s1d3 via its
893 		 * grandparent.
894 		 */
895 		{
896 			.path = dir_s1d2,
897 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
898 		},
899 		{},
900 	};
901 	int ruleset_fd;
902 
903 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
904 				    layer1_read);
905 	ASSERT_LE(0, ruleset_fd);
906 	enforce_ruleset(_metadata, ruleset_fd);
907 	ASSERT_EQ(0, close(ruleset_fd));
908 
909 	/* Checks that read access is granted for file1_s1d3 with layer 1. */
910 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
911 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
912 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
913 
914 	ruleset_fd = create_ruleset(_metadata,
915 				    LANDLOCK_ACCESS_FS_READ_FILE |
916 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
917 				    layer2_read_write);
918 	ASSERT_LE(0, ruleset_fd);
919 	enforce_ruleset(_metadata, ruleset_fd);
920 	ASSERT_EQ(0, close(ruleset_fd));
921 
922 	/* Checks that previous access rights are unchanged with layer 2. */
923 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
924 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
925 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
926 
927 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
928 				    layer3_read);
929 	ASSERT_LE(0, ruleset_fd);
930 	enforce_ruleset(_metadata, ruleset_fd);
931 	ASSERT_EQ(0, close(ruleset_fd));
932 
933 	/* Checks that previous access rights are unchanged with layer 3. */
934 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
935 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
936 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
937 
938 	/* This time, denies write access for the file hierarchy. */
939 	ruleset_fd = create_ruleset(_metadata,
940 				    LANDLOCK_ACCESS_FS_READ_FILE |
941 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
942 				    layer4_read_write);
943 	ASSERT_LE(0, ruleset_fd);
944 	enforce_ruleset(_metadata, ruleset_fd);
945 	ASSERT_EQ(0, close(ruleset_fd));
946 
947 	/*
948 	 * Checks that the only change with layer 4 is that write access is
949 	 * denied.
950 	 */
951 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
952 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
953 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
954 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
955 
956 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
957 				    layer5_read);
958 	ASSERT_LE(0, ruleset_fd);
959 	enforce_ruleset(_metadata, ruleset_fd);
960 	ASSERT_EQ(0, close(ruleset_fd));
961 
962 	/* Checks that previous access rights are unchanged with layer 5. */
963 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
964 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
965 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
966 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
967 
968 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_EXECUTE,
969 				    layer6_execute);
970 	ASSERT_LE(0, ruleset_fd);
971 	enforce_ruleset(_metadata, ruleset_fd);
972 	ASSERT_EQ(0, close(ruleset_fd));
973 
974 	/* Checks that previous access rights are unchanged with layer 6. */
975 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
976 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
977 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
978 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
979 
980 	ruleset_fd = create_ruleset(_metadata,
981 				    LANDLOCK_ACCESS_FS_READ_FILE |
982 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
983 				    layer7_read_write);
984 	ASSERT_LE(0, ruleset_fd);
985 	enforce_ruleset(_metadata, ruleset_fd);
986 	ASSERT_EQ(0, close(ruleset_fd));
987 
988 	/* Checks read access is now denied with layer 7. */
989 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
990 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
991 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
992 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
993 }
994 
995 TEST_F_FORK(layout1, inherit_subset)
996 {
997 	const struct rule rules[] = {
998 		{
999 			.path = dir_s1d2,
1000 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1001 				  LANDLOCK_ACCESS_FS_READ_DIR,
1002 		},
1003 		{},
1004 	};
1005 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1006 
1007 	ASSERT_LE(0, ruleset_fd);
1008 	enforce_ruleset(_metadata, ruleset_fd);
1009 
1010 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1011 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1012 
1013 	/* Write access is forbidden. */
1014 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1015 	/* Readdir access is allowed. */
1016 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1017 
1018 	/* Write access is forbidden. */
1019 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1020 	/* Readdir access is allowed. */
1021 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1022 
1023 	/*
1024 	 * Tests shared rule extension: the following rules should not grant
1025 	 * any new access, only remove some.  Once enforced, these rules are
1026 	 * ANDed with the previous ones.
1027 	 */
1028 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1029 			 dir_s1d2);
1030 	/*
1031 	 * According to ruleset_fd, dir_s1d2 should now have the
1032 	 * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE
1033 	 * access rights (even if this directory is opened a second time).
1034 	 * However, when enforcing this updated ruleset, the ruleset tied to
1035 	 * the current process (i.e. its domain) will still only have the
1036 	 * dir_s1d2 with LANDLOCK_ACCESS_FS_READ_FILE and
1037 	 * LANDLOCK_ACCESS_FS_READ_DIR accesses, but
1038 	 * LANDLOCK_ACCESS_FS_WRITE_FILE must not be allowed because it would
1039 	 * be a privilege escalation.
1040 	 */
1041 	enforce_ruleset(_metadata, ruleset_fd);
1042 
1043 	/* Same tests and results as above. */
1044 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1045 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1046 
1047 	/* It is still forbidden to write in file1_s1d2. */
1048 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1049 	/* Readdir access is still allowed. */
1050 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1051 
1052 	/* It is still forbidden to write in file1_s1d3. */
1053 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1054 	/* Readdir access is still allowed. */
1055 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1056 
1057 	/*
1058 	 * Try to get more privileges by adding new access rights to the parent
1059 	 * directory: dir_s1d1.
1060 	 */
1061 	add_path_beneath(_metadata, ruleset_fd, ACCESS_RW, dir_s1d1);
1062 	enforce_ruleset(_metadata, ruleset_fd);
1063 
1064 	/* Same tests and results as above. */
1065 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1066 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1067 
1068 	/* It is still forbidden to write in file1_s1d2. */
1069 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1070 	/* Readdir access is still allowed. */
1071 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1072 
1073 	/* It is still forbidden to write in file1_s1d3. */
1074 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1075 	/* Readdir access is still allowed. */
1076 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1077 
1078 	/*
1079 	 * Now, dir_s1d3 get a new rule tied to it, only allowing
1080 	 * LANDLOCK_ACCESS_FS_WRITE_FILE.  The (kernel internal) difference is
1081 	 * that there was no rule tied to it before.
1082 	 */
1083 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1084 			 dir_s1d3);
1085 	enforce_ruleset(_metadata, ruleset_fd);
1086 	ASSERT_EQ(0, close(ruleset_fd));
1087 
1088 	/*
1089 	 * Same tests and results as above, except for open(dir_s1d3) which is
1090 	 * now denied because the new rule mask the rule previously inherited
1091 	 * from dir_s1d2.
1092 	 */
1093 
1094 	/* Same tests and results as above. */
1095 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1096 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1097 
1098 	/* It is still forbidden to write in file1_s1d2. */
1099 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1100 	/* Readdir access is still allowed. */
1101 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1102 
1103 	/* It is still forbidden to write in file1_s1d3. */
1104 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1105 	/*
1106 	 * Readdir of dir_s1d3 is still allowed because of the OR policy inside
1107 	 * the same layer.
1108 	 */
1109 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1110 }
1111 
1112 TEST_F_FORK(layout1, inherit_superset)
1113 {
1114 	const struct rule rules[] = {
1115 		{
1116 			.path = dir_s1d3,
1117 			.access = ACCESS_RO,
1118 		},
1119 		{},
1120 	};
1121 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1122 
1123 	ASSERT_LE(0, ruleset_fd);
1124 	enforce_ruleset(_metadata, ruleset_fd);
1125 
1126 	/* Readdir access is denied for dir_s1d2. */
1127 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1128 	/* Readdir access is allowed for dir_s1d3. */
1129 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1130 	/* File access is allowed for file1_s1d3. */
1131 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1132 
1133 	/* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */
1134 	add_path_beneath(_metadata, ruleset_fd,
1135 			 LANDLOCK_ACCESS_FS_READ_FILE |
1136 				 LANDLOCK_ACCESS_FS_READ_DIR,
1137 			 dir_s1d2);
1138 	enforce_ruleset(_metadata, ruleset_fd);
1139 	ASSERT_EQ(0, close(ruleset_fd));
1140 
1141 	/* Readdir access is still denied for dir_s1d2. */
1142 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1143 	/* Readdir access is still allowed for dir_s1d3. */
1144 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1145 	/* File access is still allowed for file1_s1d3. */
1146 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1147 }
1148 
1149 TEST_F_FORK(layout1, max_layers)
1150 {
1151 	int i, err;
1152 	const struct rule rules[] = {
1153 		{
1154 			.path = dir_s1d2,
1155 			.access = ACCESS_RO,
1156 		},
1157 		{},
1158 	};
1159 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1160 
1161 	ASSERT_LE(0, ruleset_fd);
1162 	for (i = 0; i < 64; i++)
1163 		enforce_ruleset(_metadata, ruleset_fd);
1164 
1165 	for (i = 0; i < 2; i++) {
1166 		err = landlock_restrict_self(ruleset_fd, 0);
1167 		ASSERT_EQ(-1, err);
1168 		ASSERT_EQ(E2BIG, errno);
1169 	}
1170 	ASSERT_EQ(0, close(ruleset_fd));
1171 }
1172 
1173 TEST_F_FORK(layout1, empty_or_same_ruleset)
1174 {
1175 	struct landlock_ruleset_attr ruleset_attr = {};
1176 	int ruleset_fd;
1177 
1178 	/* Tests empty handled_access_fs. */
1179 	ruleset_fd =
1180 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1181 	ASSERT_LE(-1, ruleset_fd);
1182 	ASSERT_EQ(ENOMSG, errno);
1183 
1184 	/* Enforces policy which deny read access to all files. */
1185 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE;
1186 	ruleset_fd =
1187 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1188 	ASSERT_LE(0, ruleset_fd);
1189 	enforce_ruleset(_metadata, ruleset_fd);
1190 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1191 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1192 
1193 	/* Nests a policy which deny read access to all directories. */
1194 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR;
1195 	ruleset_fd =
1196 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1197 	ASSERT_LE(0, ruleset_fd);
1198 	enforce_ruleset(_metadata, ruleset_fd);
1199 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1200 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1201 
1202 	/* Enforces a second time with the same ruleset. */
1203 	enforce_ruleset(_metadata, ruleset_fd);
1204 	ASSERT_EQ(0, close(ruleset_fd));
1205 }
1206 
1207 TEST_F_FORK(layout1, rule_on_mountpoint)
1208 {
1209 	const struct rule rules[] = {
1210 		{
1211 			.path = dir_s1d1,
1212 			.access = ACCESS_RO,
1213 		},
1214 		{
1215 			/* dir_s3d2 is a mount point. */
1216 			.path = dir_s3d2,
1217 			.access = ACCESS_RO,
1218 		},
1219 		{},
1220 	};
1221 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1222 
1223 	ASSERT_LE(0, ruleset_fd);
1224 	enforce_ruleset(_metadata, ruleset_fd);
1225 	ASSERT_EQ(0, close(ruleset_fd));
1226 
1227 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1228 
1229 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1230 
1231 	ASSERT_EQ(EACCES, test_open(dir_s3d1, O_RDONLY));
1232 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1233 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1234 }
1235 
1236 TEST_F_FORK(layout1, rule_over_mountpoint)
1237 {
1238 	const struct rule rules[] = {
1239 		{
1240 			.path = dir_s1d1,
1241 			.access = ACCESS_RO,
1242 		},
1243 		{
1244 			/* dir_s3d2 is a mount point. */
1245 			.path = dir_s3d1,
1246 			.access = ACCESS_RO,
1247 		},
1248 		{},
1249 	};
1250 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1251 
1252 	ASSERT_LE(0, ruleset_fd);
1253 	enforce_ruleset(_metadata, ruleset_fd);
1254 	ASSERT_EQ(0, close(ruleset_fd));
1255 
1256 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1257 
1258 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1259 
1260 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
1261 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1262 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1263 }
1264 
1265 /*
1266  * This test verifies that we can apply a landlock rule on the root directory
1267  * (which might require special handling).
1268  */
1269 TEST_F_FORK(layout1, rule_over_root_allow_then_deny)
1270 {
1271 	struct rule rules[] = {
1272 		{
1273 			.path = "/",
1274 			.access = ACCESS_RO,
1275 		},
1276 		{},
1277 	};
1278 	int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1279 
1280 	ASSERT_LE(0, ruleset_fd);
1281 	enforce_ruleset(_metadata, ruleset_fd);
1282 	ASSERT_EQ(0, close(ruleset_fd));
1283 
1284 	/* Checks allowed access. */
1285 	ASSERT_EQ(0, test_open("/", O_RDONLY));
1286 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1287 
1288 	rules[0].access = LANDLOCK_ACCESS_FS_READ_FILE;
1289 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1290 	ASSERT_LE(0, ruleset_fd);
1291 	enforce_ruleset(_metadata, ruleset_fd);
1292 	ASSERT_EQ(0, close(ruleset_fd));
1293 
1294 	/* Checks denied access (on a directory). */
1295 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1296 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1297 }
1298 
1299 TEST_F_FORK(layout1, rule_over_root_deny)
1300 {
1301 	const struct rule rules[] = {
1302 		{
1303 			.path = "/",
1304 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1305 		},
1306 		{},
1307 	};
1308 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1309 
1310 	ASSERT_LE(0, ruleset_fd);
1311 	enforce_ruleset(_metadata, ruleset_fd);
1312 	ASSERT_EQ(0, close(ruleset_fd));
1313 
1314 	/* Checks denied access (on a directory). */
1315 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1316 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1317 }
1318 
1319 TEST_F_FORK(layout1, rule_inside_mount_ns)
1320 {
1321 	const struct rule rules[] = {
1322 		{
1323 			.path = "s3d3",
1324 			.access = ACCESS_RO,
1325 		},
1326 		{},
1327 	};
1328 	int ruleset_fd;
1329 
1330 	set_cap(_metadata, CAP_SYS_ADMIN);
1331 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3))
1332 	{
1333 		TH_LOG("Failed to pivot root: %s", strerror(errno));
1334 	};
1335 	ASSERT_EQ(0, chdir("/"));
1336 	clear_cap(_metadata, CAP_SYS_ADMIN);
1337 
1338 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1339 	ASSERT_LE(0, ruleset_fd);
1340 	enforce_ruleset(_metadata, ruleset_fd);
1341 	ASSERT_EQ(0, close(ruleset_fd));
1342 
1343 	ASSERT_EQ(0, test_open("s3d3", O_RDONLY));
1344 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1345 }
1346 
1347 TEST_F_FORK(layout1, mount_and_pivot)
1348 {
1349 	const struct rule rules[] = {
1350 		{
1351 			.path = dir_s3d2,
1352 			.access = ACCESS_RO,
1353 		},
1354 		{},
1355 	};
1356 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1357 
1358 	ASSERT_LE(0, ruleset_fd);
1359 	enforce_ruleset(_metadata, ruleset_fd);
1360 	ASSERT_EQ(0, close(ruleset_fd));
1361 
1362 	set_cap(_metadata, CAP_SYS_ADMIN);
1363 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
1364 	ASSERT_EQ(EPERM, errno);
1365 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1366 	ASSERT_EQ(EPERM, errno);
1367 	clear_cap(_metadata, CAP_SYS_ADMIN);
1368 }
1369 
1370 TEST_F_FORK(layout1, move_mount)
1371 {
1372 	const struct rule rules[] = {
1373 		{
1374 			.path = dir_s3d2,
1375 			.access = ACCESS_RO,
1376 		},
1377 		{},
1378 	};
1379 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1380 
1381 	ASSERT_LE(0, ruleset_fd);
1382 
1383 	set_cap(_metadata, CAP_SYS_ADMIN);
1384 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1385 			     dir_s1d2, 0))
1386 	{
1387 		TH_LOG("Failed to move mount: %s", strerror(errno));
1388 	}
1389 
1390 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1391 			     dir_s3d2, 0));
1392 	clear_cap(_metadata, CAP_SYS_ADMIN);
1393 
1394 	enforce_ruleset(_metadata, ruleset_fd);
1395 	ASSERT_EQ(0, close(ruleset_fd));
1396 
1397 	set_cap(_metadata, CAP_SYS_ADMIN);
1398 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1399 			      dir_s1d2, 0));
1400 	ASSERT_EQ(EPERM, errno);
1401 	clear_cap(_metadata, CAP_SYS_ADMIN);
1402 }
1403 
1404 TEST_F_FORK(layout1, release_inodes)
1405 {
1406 	const struct rule rules[] = {
1407 		{
1408 			.path = dir_s1d1,
1409 			.access = ACCESS_RO,
1410 		},
1411 		{
1412 			.path = dir_s3d2,
1413 			.access = ACCESS_RO,
1414 		},
1415 		{
1416 			.path = dir_s3d3,
1417 			.access = ACCESS_RO,
1418 		},
1419 		{},
1420 	};
1421 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1422 
1423 	ASSERT_LE(0, ruleset_fd);
1424 	/* Unmount a file hierarchy while it is being used by a ruleset. */
1425 	set_cap(_metadata, CAP_SYS_ADMIN);
1426 	ASSERT_EQ(0, umount(dir_s3d2));
1427 	clear_cap(_metadata, CAP_SYS_ADMIN);
1428 
1429 	enforce_ruleset(_metadata, ruleset_fd);
1430 	ASSERT_EQ(0, close(ruleset_fd));
1431 
1432 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1433 	ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
1434 	/* This dir_s3d3 would not be allowed and does not exist anyway. */
1435 	ASSERT_EQ(ENOENT, test_open(dir_s3d3, O_RDONLY));
1436 }
1437 
1438 enum relative_access {
1439 	REL_OPEN,
1440 	REL_CHDIR,
1441 	REL_CHROOT_ONLY,
1442 	REL_CHROOT_CHDIR,
1443 };
1444 
1445 static void test_relative_path(struct __test_metadata *const _metadata,
1446 			       const enum relative_access rel)
1447 {
1448 	/*
1449 	 * Common layer to check that chroot doesn't ignore it (i.e. a chroot
1450 	 * is not a disconnected root directory).
1451 	 */
1452 	const struct rule layer1_base[] = {
1453 		{
1454 			.path = TMP_DIR,
1455 			.access = ACCESS_RO,
1456 		},
1457 		{},
1458 	};
1459 	const struct rule layer2_subs[] = {
1460 		{
1461 			.path = dir_s1d2,
1462 			.access = ACCESS_RO,
1463 		},
1464 		{
1465 			.path = dir_s2d2,
1466 			.access = ACCESS_RO,
1467 		},
1468 		{},
1469 	};
1470 	int dirfd, ruleset_fd;
1471 
1472 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
1473 	ASSERT_LE(0, ruleset_fd);
1474 	enforce_ruleset(_metadata, ruleset_fd);
1475 	ASSERT_EQ(0, close(ruleset_fd));
1476 
1477 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_subs);
1478 
1479 	ASSERT_LE(0, ruleset_fd);
1480 	switch (rel) {
1481 	case REL_OPEN:
1482 	case REL_CHDIR:
1483 		break;
1484 	case REL_CHROOT_ONLY:
1485 		ASSERT_EQ(0, chdir(dir_s2d2));
1486 		break;
1487 	case REL_CHROOT_CHDIR:
1488 		ASSERT_EQ(0, chdir(dir_s1d2));
1489 		break;
1490 	default:
1491 		ASSERT_TRUE(false);
1492 		return;
1493 	}
1494 
1495 	set_cap(_metadata, CAP_SYS_CHROOT);
1496 	enforce_ruleset(_metadata, ruleset_fd);
1497 
1498 	switch (rel) {
1499 	case REL_OPEN:
1500 		dirfd = open(dir_s1d2, O_DIRECTORY);
1501 		ASSERT_LE(0, dirfd);
1502 		break;
1503 	case REL_CHDIR:
1504 		ASSERT_EQ(0, chdir(dir_s1d2));
1505 		dirfd = AT_FDCWD;
1506 		break;
1507 	case REL_CHROOT_ONLY:
1508 		/* Do chroot into dir_s1d2 (relative to dir_s2d2). */
1509 		ASSERT_EQ(0, chroot("../../s1d1/s1d2"))
1510 		{
1511 			TH_LOG("Failed to chroot: %s", strerror(errno));
1512 		}
1513 		dirfd = AT_FDCWD;
1514 		break;
1515 	case REL_CHROOT_CHDIR:
1516 		/* Do chroot into dir_s1d2. */
1517 		ASSERT_EQ(0, chroot("."))
1518 		{
1519 			TH_LOG("Failed to chroot: %s", strerror(errno));
1520 		}
1521 		dirfd = AT_FDCWD;
1522 		break;
1523 	}
1524 
1525 	ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES,
1526 		  test_open_rel(dirfd, "..", O_RDONLY));
1527 	ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY));
1528 
1529 	if (rel == REL_CHROOT_ONLY) {
1530 		/* The current directory is dir_s2d2. */
1531 		ASSERT_EQ(0, test_open_rel(dirfd, "./s2d3", O_RDONLY));
1532 	} else {
1533 		/* The current directory is dir_s1d2. */
1534 		ASSERT_EQ(0, test_open_rel(dirfd, "./s1d3", O_RDONLY));
1535 	}
1536 
1537 	if (rel == REL_CHROOT_ONLY || rel == REL_CHROOT_CHDIR) {
1538 		/* Checks the root dir_s1d2. */
1539 		ASSERT_EQ(0, test_open_rel(dirfd, "/..", O_RDONLY));
1540 		ASSERT_EQ(0, test_open_rel(dirfd, "/", O_RDONLY));
1541 		ASSERT_EQ(0, test_open_rel(dirfd, "/f1", O_RDONLY));
1542 		ASSERT_EQ(0, test_open_rel(dirfd, "/s1d3", O_RDONLY));
1543 	}
1544 
1545 	if (rel != REL_CHROOT_CHDIR) {
1546 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY));
1547 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY));
1548 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3",
1549 					   O_RDONLY));
1550 
1551 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY));
1552 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY));
1553 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3",
1554 					   O_RDONLY));
1555 	}
1556 
1557 	if (rel == REL_OPEN)
1558 		ASSERT_EQ(0, close(dirfd));
1559 	ASSERT_EQ(0, close(ruleset_fd));
1560 }
1561 
1562 TEST_F_FORK(layout1, relative_open)
1563 {
1564 	test_relative_path(_metadata, REL_OPEN);
1565 }
1566 
1567 TEST_F_FORK(layout1, relative_chdir)
1568 {
1569 	test_relative_path(_metadata, REL_CHDIR);
1570 }
1571 
1572 TEST_F_FORK(layout1, relative_chroot_only)
1573 {
1574 	test_relative_path(_metadata, REL_CHROOT_ONLY);
1575 }
1576 
1577 TEST_F_FORK(layout1, relative_chroot_chdir)
1578 {
1579 	test_relative_path(_metadata, REL_CHROOT_CHDIR);
1580 }
1581 
1582 static void copy_binary(struct __test_metadata *const _metadata,
1583 			const char *const dst_path)
1584 {
1585 	int dst_fd, src_fd;
1586 	struct stat statbuf;
1587 
1588 	dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC);
1589 	ASSERT_LE(0, dst_fd)
1590 	{
1591 		TH_LOG("Failed to open \"%s\": %s", dst_path, strerror(errno));
1592 	}
1593 	src_fd = open(BINARY_PATH, O_RDONLY | O_CLOEXEC);
1594 	ASSERT_LE(0, src_fd)
1595 	{
1596 		TH_LOG("Failed to open \"" BINARY_PATH "\": %s",
1597 		       strerror(errno));
1598 	}
1599 	ASSERT_EQ(0, fstat(src_fd, &statbuf));
1600 	ASSERT_EQ(statbuf.st_size,
1601 		  sendfile(dst_fd, src_fd, 0, statbuf.st_size));
1602 	ASSERT_EQ(0, close(src_fd));
1603 	ASSERT_EQ(0, close(dst_fd));
1604 }
1605 
1606 static void test_execute(struct __test_metadata *const _metadata, const int err,
1607 			 const char *const path)
1608 {
1609 	int status;
1610 	char *const argv[] = { (char *)path, NULL };
1611 	const pid_t child = fork();
1612 
1613 	ASSERT_LE(0, child);
1614 	if (child == 0) {
1615 		ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL))
1616 		{
1617 			TH_LOG("Failed to execute \"%s\": %s", path,
1618 			       strerror(errno));
1619 		};
1620 		ASSERT_EQ(err, errno);
1621 		_exit(_metadata->passed ? 2 : 1);
1622 		return;
1623 	}
1624 	ASSERT_EQ(child, waitpid(child, &status, 0));
1625 	ASSERT_EQ(1, WIFEXITED(status));
1626 	ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status))
1627 	{
1628 		TH_LOG("Unexpected return code for \"%s\": %s", path,
1629 		       strerror(errno));
1630 	};
1631 }
1632 
1633 TEST_F_FORK(layout1, execute)
1634 {
1635 	const struct rule rules[] = {
1636 		{
1637 			.path = dir_s1d2,
1638 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
1639 		},
1640 		{},
1641 	};
1642 	const int ruleset_fd =
1643 		create_ruleset(_metadata, rules[0].access, rules);
1644 
1645 	ASSERT_LE(0, ruleset_fd);
1646 	copy_binary(_metadata, file1_s1d1);
1647 	copy_binary(_metadata, file1_s1d2);
1648 	copy_binary(_metadata, file1_s1d3);
1649 
1650 	enforce_ruleset(_metadata, ruleset_fd);
1651 	ASSERT_EQ(0, close(ruleset_fd));
1652 
1653 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1654 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1655 	test_execute(_metadata, EACCES, file1_s1d1);
1656 
1657 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
1658 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1659 	test_execute(_metadata, 0, file1_s1d2);
1660 
1661 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
1662 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1663 	test_execute(_metadata, 0, file1_s1d3);
1664 }
1665 
1666 TEST_F_FORK(layout1, link)
1667 {
1668 	const struct rule layer1[] = {
1669 		{
1670 			.path = dir_s1d2,
1671 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
1672 		},
1673 		{},
1674 	};
1675 	const struct rule layer2[] = {
1676 		{
1677 			.path = dir_s1d3,
1678 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1679 		},
1680 		{},
1681 	};
1682 	int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
1683 
1684 	ASSERT_LE(0, ruleset_fd);
1685 
1686 	ASSERT_EQ(0, unlink(file1_s1d1));
1687 	ASSERT_EQ(0, unlink(file1_s1d2));
1688 	ASSERT_EQ(0, unlink(file1_s1d3));
1689 
1690 	enforce_ruleset(_metadata, ruleset_fd);
1691 	ASSERT_EQ(0, close(ruleset_fd));
1692 
1693 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
1694 	ASSERT_EQ(EACCES, errno);
1695 
1696 	/* Denies linking because of reparenting. */
1697 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
1698 	ASSERT_EQ(EXDEV, errno);
1699 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
1700 	ASSERT_EQ(EXDEV, errno);
1701 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
1702 	ASSERT_EQ(EXDEV, errno);
1703 
1704 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
1705 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
1706 
1707 	/* Prepares for next unlinks. */
1708 	ASSERT_EQ(0, unlink(file2_s1d2));
1709 	ASSERT_EQ(0, unlink(file2_s1d3));
1710 
1711 	ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
1712 	ASSERT_LE(0, ruleset_fd);
1713 	enforce_ruleset(_metadata, ruleset_fd);
1714 	ASSERT_EQ(0, close(ruleset_fd));
1715 
1716 	/* Checks that linkind doesn't require the ability to delete a file. */
1717 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
1718 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
1719 }
1720 
1721 TEST_F_FORK(layout1, rename_file)
1722 {
1723 	const struct rule rules[] = {
1724 		{
1725 			.path = dir_s1d3,
1726 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1727 		},
1728 		{
1729 			.path = dir_s2d2,
1730 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1731 		},
1732 		{},
1733 	};
1734 	const int ruleset_fd =
1735 		create_ruleset(_metadata, rules[0].access, rules);
1736 
1737 	ASSERT_LE(0, ruleset_fd);
1738 
1739 	ASSERT_EQ(0, unlink(file1_s1d2));
1740 
1741 	enforce_ruleset(_metadata, ruleset_fd);
1742 	ASSERT_EQ(0, close(ruleset_fd));
1743 
1744 	/*
1745 	 * Tries to replace a file, from a directory that allows file removal,
1746 	 * but to a different directory (which also allows file removal).
1747 	 */
1748 	ASSERT_EQ(-1, rename(file1_s2d3, file1_s1d3));
1749 	ASSERT_EQ(EXDEV, errno);
1750 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d3,
1751 				RENAME_EXCHANGE));
1752 	ASSERT_EQ(EXDEV, errno);
1753 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
1754 				RENAME_EXCHANGE));
1755 	ASSERT_EQ(EXDEV, errno);
1756 
1757 	/*
1758 	 * Tries to replace a file, from a directory that denies file removal,
1759 	 * to a different directory (which allows file removal).
1760 	 */
1761 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
1762 	ASSERT_EQ(EXDEV, errno);
1763 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file1_s1d3,
1764 				RENAME_EXCHANGE));
1765 	ASSERT_EQ(EXDEV, errno);
1766 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s1d3,
1767 				RENAME_EXCHANGE));
1768 	ASSERT_EQ(EXDEV, errno);
1769 
1770 	/* Exchanges files and directories that partially allow removal. */
1771 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
1772 				RENAME_EXCHANGE));
1773 	ASSERT_EQ(EACCES, errno);
1774 	/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
1775 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
1776 	ASSERT_EQ(EACCES, errno);
1777 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
1778 				RENAME_EXCHANGE));
1779 	ASSERT_EQ(EACCES, errno);
1780 	/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
1781 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1782 	ASSERT_EQ(EACCES, errno);
1783 
1784 	/* Renames files with different parents. */
1785 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
1786 	ASSERT_EQ(EXDEV, errno);
1787 	ASSERT_EQ(0, unlink(file1_s1d3));
1788 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
1789 	ASSERT_EQ(EXDEV, errno);
1790 
1791 	/* Exchanges and renames files with same parent. */
1792 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3,
1793 			       RENAME_EXCHANGE));
1794 	ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3));
1795 
1796 	/* Exchanges files and directories with same parent, twice. */
1797 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
1798 			       RENAME_EXCHANGE));
1799 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
1800 			       RENAME_EXCHANGE));
1801 }
1802 
1803 TEST_F_FORK(layout1, rename_dir)
1804 {
1805 	const struct rule rules[] = {
1806 		{
1807 			.path = dir_s1d2,
1808 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1809 		},
1810 		{
1811 			.path = dir_s2d1,
1812 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1813 		},
1814 		{},
1815 	};
1816 	const int ruleset_fd =
1817 		create_ruleset(_metadata, rules[0].access, rules);
1818 
1819 	ASSERT_LE(0, ruleset_fd);
1820 
1821 	/* Empties dir_s1d3 to allow renaming. */
1822 	ASSERT_EQ(0, unlink(file1_s1d3));
1823 	ASSERT_EQ(0, unlink(file2_s1d3));
1824 
1825 	enforce_ruleset(_metadata, ruleset_fd);
1826 	ASSERT_EQ(0, close(ruleset_fd));
1827 
1828 	/* Exchanges and renames directory to a different parent. */
1829 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
1830 				RENAME_EXCHANGE));
1831 	ASSERT_EQ(EXDEV, errno);
1832 	ASSERT_EQ(-1, rename(dir_s2d3, dir_s1d3));
1833 	ASSERT_EQ(EXDEV, errno);
1834 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
1835 				RENAME_EXCHANGE));
1836 	ASSERT_EQ(EXDEV, errno);
1837 
1838 	/*
1839 	 * Exchanges directory to the same parent, which doesn't allow
1840 	 * directory removal.
1841 	 */
1842 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
1843 				RENAME_EXCHANGE));
1844 	ASSERT_EQ(EACCES, errno);
1845 	/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
1846 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
1847 	ASSERT_EQ(EACCES, errno);
1848 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
1849 				RENAME_EXCHANGE));
1850 	ASSERT_EQ(EACCES, errno);
1851 	/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
1852 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1853 	ASSERT_EQ(EACCES, errno);
1854 
1855 	/*
1856 	 * Exchanges and renames directory to the same parent, which allows
1857 	 * directory removal.
1858 	 */
1859 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2,
1860 			       RENAME_EXCHANGE));
1861 	ASSERT_EQ(0, unlink(dir_s1d3));
1862 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
1863 	ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3));
1864 	ASSERT_EQ(0, rmdir(dir_s1d3));
1865 }
1866 
1867 TEST_F_FORK(layout1, remove_dir)
1868 {
1869 	const struct rule rules[] = {
1870 		{
1871 			.path = dir_s1d2,
1872 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1873 		},
1874 		{},
1875 	};
1876 	const int ruleset_fd =
1877 		create_ruleset(_metadata, rules[0].access, rules);
1878 
1879 	ASSERT_LE(0, ruleset_fd);
1880 
1881 	ASSERT_EQ(0, unlink(file1_s1d1));
1882 	ASSERT_EQ(0, unlink(file1_s1d2));
1883 	ASSERT_EQ(0, unlink(file1_s1d3));
1884 	ASSERT_EQ(0, unlink(file2_s1d3));
1885 
1886 	enforce_ruleset(_metadata, ruleset_fd);
1887 	ASSERT_EQ(0, close(ruleset_fd));
1888 
1889 	ASSERT_EQ(0, rmdir(dir_s1d3));
1890 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
1891 	ASSERT_EQ(0, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
1892 
1893 	/* dir_s1d2 itself cannot be removed. */
1894 	ASSERT_EQ(-1, rmdir(dir_s1d2));
1895 	ASSERT_EQ(EACCES, errno);
1896 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d2, AT_REMOVEDIR));
1897 	ASSERT_EQ(EACCES, errno);
1898 	ASSERT_EQ(-1, rmdir(dir_s1d1));
1899 	ASSERT_EQ(EACCES, errno);
1900 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d1, AT_REMOVEDIR));
1901 	ASSERT_EQ(EACCES, errno);
1902 }
1903 
1904 TEST_F_FORK(layout1, remove_file)
1905 {
1906 	const struct rule rules[] = {
1907 		{
1908 			.path = dir_s1d2,
1909 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1910 		},
1911 		{},
1912 	};
1913 	const int ruleset_fd =
1914 		create_ruleset(_metadata, rules[0].access, rules);
1915 
1916 	ASSERT_LE(0, ruleset_fd);
1917 	enforce_ruleset(_metadata, ruleset_fd);
1918 	ASSERT_EQ(0, close(ruleset_fd));
1919 
1920 	ASSERT_EQ(-1, unlink(file1_s1d1));
1921 	ASSERT_EQ(EACCES, errno);
1922 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, file1_s1d1, 0));
1923 	ASSERT_EQ(EACCES, errno);
1924 	ASSERT_EQ(0, unlink(file1_s1d2));
1925 	ASSERT_EQ(0, unlinkat(AT_FDCWD, file1_s1d3, 0));
1926 }
1927 
1928 static void test_make_file(struct __test_metadata *const _metadata,
1929 			   const __u64 access, const mode_t mode,
1930 			   const dev_t dev)
1931 {
1932 	const struct rule rules[] = {
1933 		{
1934 			.path = dir_s1d2,
1935 			.access = access,
1936 		},
1937 		{},
1938 	};
1939 	const int ruleset_fd = create_ruleset(_metadata, access, rules);
1940 
1941 	ASSERT_LE(0, ruleset_fd);
1942 
1943 	ASSERT_EQ(0, unlink(file1_s1d1));
1944 	ASSERT_EQ(0, unlink(file2_s1d1));
1945 	ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev))
1946 	{
1947 		TH_LOG("Failed to make file \"%s\": %s", file2_s1d1,
1948 		       strerror(errno));
1949 	};
1950 
1951 	ASSERT_EQ(0, unlink(file1_s1d2));
1952 	ASSERT_EQ(0, unlink(file2_s1d2));
1953 
1954 	ASSERT_EQ(0, unlink(file1_s1d3));
1955 	ASSERT_EQ(0, unlink(file2_s1d3));
1956 
1957 	enforce_ruleset(_metadata, ruleset_fd);
1958 	ASSERT_EQ(0, close(ruleset_fd));
1959 
1960 	ASSERT_EQ(-1, mknod(file1_s1d1, mode | 0400, dev));
1961 	ASSERT_EQ(EACCES, errno);
1962 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
1963 	ASSERT_EQ(EACCES, errno);
1964 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
1965 	ASSERT_EQ(EACCES, errno);
1966 
1967 	ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev))
1968 	{
1969 		TH_LOG("Failed to make file \"%s\": %s", file1_s1d2,
1970 		       strerror(errno));
1971 	};
1972 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
1973 	ASSERT_EQ(0, unlink(file2_s1d2));
1974 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
1975 
1976 	ASSERT_EQ(0, mknod(file1_s1d3, mode | 0400, dev));
1977 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
1978 	ASSERT_EQ(0, unlink(file2_s1d3));
1979 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
1980 }
1981 
1982 TEST_F_FORK(layout1, make_char)
1983 {
1984 	/* Creates a /dev/null device. */
1985 	set_cap(_metadata, CAP_MKNOD);
1986 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR,
1987 		       makedev(1, 3));
1988 }
1989 
1990 TEST_F_FORK(layout1, make_block)
1991 {
1992 	/* Creates a /dev/loop0 device. */
1993 	set_cap(_metadata, CAP_MKNOD);
1994 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK,
1995 		       makedev(7, 0));
1996 }
1997 
1998 TEST_F_FORK(layout1, make_reg_1)
1999 {
2000 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFREG, 0);
2001 }
2002 
2003 TEST_F_FORK(layout1, make_reg_2)
2004 {
2005 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, 0, 0);
2006 }
2007 
2008 TEST_F_FORK(layout1, make_sock)
2009 {
2010 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_SOCK, S_IFSOCK, 0);
2011 }
2012 
2013 TEST_F_FORK(layout1, make_fifo)
2014 {
2015 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_FIFO, S_IFIFO, 0);
2016 }
2017 
2018 TEST_F_FORK(layout1, make_sym)
2019 {
2020 	const struct rule rules[] = {
2021 		{
2022 			.path = dir_s1d2,
2023 			.access = LANDLOCK_ACCESS_FS_MAKE_SYM,
2024 		},
2025 		{},
2026 	};
2027 	const int ruleset_fd =
2028 		create_ruleset(_metadata, rules[0].access, rules);
2029 
2030 	ASSERT_LE(0, ruleset_fd);
2031 
2032 	ASSERT_EQ(0, unlink(file1_s1d1));
2033 	ASSERT_EQ(0, unlink(file2_s1d1));
2034 	ASSERT_EQ(0, symlink("none", file2_s1d1));
2035 
2036 	ASSERT_EQ(0, unlink(file1_s1d2));
2037 	ASSERT_EQ(0, unlink(file2_s1d2));
2038 
2039 	ASSERT_EQ(0, unlink(file1_s1d3));
2040 	ASSERT_EQ(0, unlink(file2_s1d3));
2041 
2042 	enforce_ruleset(_metadata, ruleset_fd);
2043 	ASSERT_EQ(0, close(ruleset_fd));
2044 
2045 	ASSERT_EQ(-1, symlink("none", file1_s1d1));
2046 	ASSERT_EQ(EACCES, errno);
2047 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2048 	ASSERT_EQ(EACCES, errno);
2049 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
2050 	ASSERT_EQ(EACCES, errno);
2051 
2052 	ASSERT_EQ(0, symlink("none", file1_s1d2));
2053 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
2054 	ASSERT_EQ(0, unlink(file2_s1d2));
2055 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
2056 
2057 	ASSERT_EQ(0, symlink("none", file1_s1d3));
2058 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
2059 	ASSERT_EQ(0, unlink(file2_s1d3));
2060 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
2061 }
2062 
2063 TEST_F_FORK(layout1, make_dir)
2064 {
2065 	const struct rule rules[] = {
2066 		{
2067 			.path = dir_s1d2,
2068 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
2069 		},
2070 		{},
2071 	};
2072 	const int ruleset_fd =
2073 		create_ruleset(_metadata, rules[0].access, rules);
2074 
2075 	ASSERT_LE(0, ruleset_fd);
2076 
2077 	ASSERT_EQ(0, unlink(file1_s1d1));
2078 	ASSERT_EQ(0, unlink(file1_s1d2));
2079 	ASSERT_EQ(0, unlink(file1_s1d3));
2080 
2081 	enforce_ruleset(_metadata, ruleset_fd);
2082 	ASSERT_EQ(0, close(ruleset_fd));
2083 
2084 	/* Uses file_* as directory names. */
2085 	ASSERT_EQ(-1, mkdir(file1_s1d1, 0700));
2086 	ASSERT_EQ(EACCES, errno);
2087 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
2088 	ASSERT_EQ(0, mkdir(file1_s1d3, 0700));
2089 }
2090 
2091 static int open_proc_fd(struct __test_metadata *const _metadata, const int fd,
2092 			const int open_flags)
2093 {
2094 	static const char path_template[] = "/proc/self/fd/%d";
2095 	char procfd_path[sizeof(path_template) + 10];
2096 	const int procfd_path_size =
2097 		snprintf(procfd_path, sizeof(procfd_path), path_template, fd);
2098 
2099 	ASSERT_LT(procfd_path_size, sizeof(procfd_path));
2100 	return open(procfd_path, open_flags);
2101 }
2102 
2103 TEST_F_FORK(layout1, proc_unlinked_file)
2104 {
2105 	const struct rule rules[] = {
2106 		{
2107 			.path = file1_s1d2,
2108 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2109 		},
2110 		{},
2111 	};
2112 	int reg_fd, proc_fd;
2113 	const int ruleset_fd = create_ruleset(
2114 		_metadata,
2115 		LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
2116 		rules);
2117 
2118 	ASSERT_LE(0, ruleset_fd);
2119 	enforce_ruleset(_metadata, ruleset_fd);
2120 	ASSERT_EQ(0, close(ruleset_fd));
2121 
2122 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
2123 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2124 	reg_fd = open(file1_s1d2, O_RDONLY | O_CLOEXEC);
2125 	ASSERT_LE(0, reg_fd);
2126 	ASSERT_EQ(0, unlink(file1_s1d2));
2127 
2128 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDONLY | O_CLOEXEC);
2129 	ASSERT_LE(0, proc_fd);
2130 	ASSERT_EQ(0, close(proc_fd));
2131 
2132 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC);
2133 	ASSERT_EQ(-1, proc_fd)
2134 	{
2135 		TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd,
2136 		       strerror(errno));
2137 	}
2138 	ASSERT_EQ(EACCES, errno);
2139 
2140 	ASSERT_EQ(0, close(reg_fd));
2141 }
2142 
2143 TEST_F_FORK(layout1, proc_pipe)
2144 {
2145 	int proc_fd;
2146 	int pipe_fds[2];
2147 	char buf = '\0';
2148 	const struct rule rules[] = {
2149 		{
2150 			.path = dir_s1d2,
2151 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2152 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2153 		},
2154 		{},
2155 	};
2156 	/* Limits read and write access to files tied to the filesystem. */
2157 	const int ruleset_fd =
2158 		create_ruleset(_metadata, rules[0].access, rules);
2159 
2160 	ASSERT_LE(0, ruleset_fd);
2161 	enforce_ruleset(_metadata, ruleset_fd);
2162 	ASSERT_EQ(0, close(ruleset_fd));
2163 
2164 	/* Checks enforcement for normal files. */
2165 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
2166 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
2167 
2168 	/* Checks access to pipes through FD. */
2169 	ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC));
2170 	ASSERT_EQ(1, write(pipe_fds[1], ".", 1))
2171 	{
2172 		TH_LOG("Failed to write in pipe: %s", strerror(errno));
2173 	}
2174 	ASSERT_EQ(1, read(pipe_fds[0], &buf, 1));
2175 	ASSERT_EQ('.', buf);
2176 
2177 	/* Checks write access to pipe through /proc/self/fd . */
2178 	proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC);
2179 	ASSERT_LE(0, proc_fd);
2180 	ASSERT_EQ(1, write(proc_fd, ".", 1))
2181 	{
2182 		TH_LOG("Failed to write through /proc/self/fd/%d: %s",
2183 		       pipe_fds[1], strerror(errno));
2184 	}
2185 	ASSERT_EQ(0, close(proc_fd));
2186 
2187 	/* Checks read access to pipe through /proc/self/fd . */
2188 	proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC);
2189 	ASSERT_LE(0, proc_fd);
2190 	buf = '\0';
2191 	ASSERT_EQ(1, read(proc_fd, &buf, 1))
2192 	{
2193 		TH_LOG("Failed to read through /proc/self/fd/%d: %s",
2194 		       pipe_fds[1], strerror(errno));
2195 	}
2196 	ASSERT_EQ(0, close(proc_fd));
2197 
2198 	ASSERT_EQ(0, close(pipe_fds[0]));
2199 	ASSERT_EQ(0, close(pipe_fds[1]));
2200 }
2201 
2202 /* clang-format off */
2203 FIXTURE(layout1_bind) {};
2204 /* clang-format on */
2205 
2206 FIXTURE_SETUP(layout1_bind)
2207 {
2208 	prepare_layout(_metadata);
2209 
2210 	create_layout1(_metadata);
2211 
2212 	set_cap(_metadata, CAP_SYS_ADMIN);
2213 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
2214 	clear_cap(_metadata, CAP_SYS_ADMIN);
2215 }
2216 
2217 FIXTURE_TEARDOWN(layout1_bind)
2218 {
2219 	set_cap(_metadata, CAP_SYS_ADMIN);
2220 	EXPECT_EQ(0, umount(dir_s2d2));
2221 	clear_cap(_metadata, CAP_SYS_ADMIN);
2222 
2223 	remove_layout1(_metadata);
2224 
2225 	cleanup_layout(_metadata);
2226 }
2227 
2228 static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
2229 static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
2230 
2231 /*
2232  * layout1_bind hierarchy:
2233  *
2234  * tmp
2235  * ├── s1d1
2236  * │   ├── f1
2237  * │   ├── f2
2238  * │   └── s1d2
2239  * │       ├── f1
2240  * │       ├── f2
2241  * │       └── s1d3
2242  * │           ├── f1
2243  * │           └── f2
2244  * ├── s2d1
2245  * │   ├── f1
2246  * │   └── s2d2
2247  * │       ├── f1
2248  * │       ├── f2
2249  * │       └── s1d3
2250  * │           ├── f1
2251  * │           └── f2
2252  * └── s3d1
2253  *     └── s3d2
2254  *         └── s3d3
2255  */
2256 
2257 TEST_F_FORK(layout1_bind, no_restriction)
2258 {
2259 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
2260 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2261 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
2262 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2263 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
2264 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2265 
2266 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
2267 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
2268 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
2269 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
2270 	ASSERT_EQ(ENOENT, test_open(dir_s2d3, O_RDONLY));
2271 	ASSERT_EQ(ENOENT, test_open(file1_s2d3, O_RDONLY));
2272 
2273 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY));
2274 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
2275 
2276 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
2277 }
2278 
2279 TEST_F_FORK(layout1_bind, same_content_same_file)
2280 {
2281 	/*
2282 	 * Sets access right on parent directories of both source and
2283 	 * destination mount points.
2284 	 */
2285 	const struct rule layer1_parent[] = {
2286 		{
2287 			.path = dir_s1d1,
2288 			.access = ACCESS_RO,
2289 		},
2290 		{
2291 			.path = dir_s2d1,
2292 			.access = ACCESS_RW,
2293 		},
2294 		{},
2295 	};
2296 	/*
2297 	 * Sets access rights on the same bind-mounted directories.  The result
2298 	 * should be ACCESS_RW for both directories, but not both hierarchies
2299 	 * because of the first layer.
2300 	 */
2301 	const struct rule layer2_mount_point[] = {
2302 		{
2303 			.path = dir_s1d2,
2304 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2305 		},
2306 		{
2307 			.path = dir_s2d2,
2308 			.access = ACCESS_RW,
2309 		},
2310 		{},
2311 	};
2312 	/* Only allow read-access to the s1d3 hierarchies. */
2313 	const struct rule layer3_source[] = {
2314 		{
2315 			.path = dir_s1d3,
2316 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2317 		},
2318 		{},
2319 	};
2320 	/* Removes all access rights. */
2321 	const struct rule layer4_destination[] = {
2322 		{
2323 			.path = bind_file1_s1d3,
2324 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
2325 		},
2326 		{},
2327 	};
2328 	int ruleset_fd;
2329 
2330 	/* Sets rules for the parent directories. */
2331 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_parent);
2332 	ASSERT_LE(0, ruleset_fd);
2333 	enforce_ruleset(_metadata, ruleset_fd);
2334 	ASSERT_EQ(0, close(ruleset_fd));
2335 
2336 	/* Checks source hierarchy. */
2337 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2338 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
2339 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
2340 
2341 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2342 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2343 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2344 
2345 	/* Checks destination hierarchy. */
2346 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDWR));
2347 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
2348 
2349 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
2350 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2351 
2352 	/* Sets rules for the mount points. */
2353 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_mount_point);
2354 	ASSERT_LE(0, ruleset_fd);
2355 	enforce_ruleset(_metadata, ruleset_fd);
2356 	ASSERT_EQ(0, close(ruleset_fd));
2357 
2358 	/* Checks source hierarchy. */
2359 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
2360 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
2361 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
2362 
2363 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2364 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2365 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2366 
2367 	/* Checks destination hierarchy. */
2368 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_RDONLY));
2369 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_WRONLY));
2370 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
2371 
2372 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
2373 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2374 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
2375 
2376 	/* Sets a (shared) rule only on the source. */
2377 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_source);
2378 	ASSERT_LE(0, ruleset_fd);
2379 	enforce_ruleset(_metadata, ruleset_fd);
2380 	ASSERT_EQ(0, close(ruleset_fd));
2381 
2382 	/* Checks source hierarchy. */
2383 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
2384 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2385 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2386 
2387 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2388 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
2389 	ASSERT_EQ(EACCES, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
2390 
2391 	/* Checks destination hierarchy. */
2392 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_RDONLY));
2393 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_WRONLY));
2394 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2395 
2396 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
2397 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
2398 	ASSERT_EQ(EACCES, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
2399 
2400 	/* Sets a (shared) rule only on the destination. */
2401 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_destination);
2402 	ASSERT_LE(0, ruleset_fd);
2403 	enforce_ruleset(_metadata, ruleset_fd);
2404 	ASSERT_EQ(0, close(ruleset_fd));
2405 
2406 	/* Checks source hierarchy. */
2407 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
2408 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
2409 
2410 	/* Checks destination hierarchy. */
2411 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_RDONLY));
2412 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
2413 }
2414 
2415 #define LOWER_BASE TMP_DIR "/lower"
2416 #define LOWER_DATA LOWER_BASE "/data"
2417 static const char lower_fl1[] = LOWER_DATA "/fl1";
2418 static const char lower_dl1[] = LOWER_DATA "/dl1";
2419 static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2";
2420 static const char lower_fo1[] = LOWER_DATA "/fo1";
2421 static const char lower_do1[] = LOWER_DATA "/do1";
2422 static const char lower_do1_fo2[] = LOWER_DATA "/do1/fo2";
2423 static const char lower_do1_fl3[] = LOWER_DATA "/do1/fl3";
2424 
2425 static const char (*lower_base_files[])[] = {
2426 	&lower_fl1,
2427 	&lower_fo1,
2428 	NULL,
2429 };
2430 static const char (*lower_base_directories[])[] = {
2431 	&lower_dl1,
2432 	&lower_do1,
2433 	NULL,
2434 };
2435 static const char (*lower_sub_files[])[] = {
2436 	&lower_dl1_fl2,
2437 	&lower_do1_fo2,
2438 	&lower_do1_fl3,
2439 	NULL,
2440 };
2441 
2442 #define UPPER_BASE TMP_DIR "/upper"
2443 #define UPPER_DATA UPPER_BASE "/data"
2444 #define UPPER_WORK UPPER_BASE "/work"
2445 static const char upper_fu1[] = UPPER_DATA "/fu1";
2446 static const char upper_du1[] = UPPER_DATA "/du1";
2447 static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2";
2448 static const char upper_fo1[] = UPPER_DATA "/fo1";
2449 static const char upper_do1[] = UPPER_DATA "/do1";
2450 static const char upper_do1_fo2[] = UPPER_DATA "/do1/fo2";
2451 static const char upper_do1_fu3[] = UPPER_DATA "/do1/fu3";
2452 
2453 static const char (*upper_base_files[])[] = {
2454 	&upper_fu1,
2455 	&upper_fo1,
2456 	NULL,
2457 };
2458 static const char (*upper_base_directories[])[] = {
2459 	&upper_du1,
2460 	&upper_do1,
2461 	NULL,
2462 };
2463 static const char (*upper_sub_files[])[] = {
2464 	&upper_du1_fu2,
2465 	&upper_do1_fo2,
2466 	&upper_do1_fu3,
2467 	NULL,
2468 };
2469 
2470 #define MERGE_BASE TMP_DIR "/merge"
2471 #define MERGE_DATA MERGE_BASE "/data"
2472 static const char merge_fl1[] = MERGE_DATA "/fl1";
2473 static const char merge_dl1[] = MERGE_DATA "/dl1";
2474 static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2";
2475 static const char merge_fu1[] = MERGE_DATA "/fu1";
2476 static const char merge_du1[] = MERGE_DATA "/du1";
2477 static const char merge_du1_fu2[] = MERGE_DATA "/du1/fu2";
2478 static const char merge_fo1[] = MERGE_DATA "/fo1";
2479 static const char merge_do1[] = MERGE_DATA "/do1";
2480 static const char merge_do1_fo2[] = MERGE_DATA "/do1/fo2";
2481 static const char merge_do1_fl3[] = MERGE_DATA "/do1/fl3";
2482 static const char merge_do1_fu3[] = MERGE_DATA "/do1/fu3";
2483 
2484 static const char (*merge_base_files[])[] = {
2485 	&merge_fl1,
2486 	&merge_fu1,
2487 	&merge_fo1,
2488 	NULL,
2489 };
2490 static const char (*merge_base_directories[])[] = {
2491 	&merge_dl1,
2492 	&merge_du1,
2493 	&merge_do1,
2494 	NULL,
2495 };
2496 static const char (*merge_sub_files[])[] = {
2497 	&merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2,
2498 	&merge_do1_fl3, &merge_do1_fu3, NULL,
2499 };
2500 
2501 /*
2502  * layout2_overlay hierarchy:
2503  *
2504  * tmp
2505  * ├── lower
2506  * │   └── data
2507  * │       ├── dl1
2508  * │       │   └── fl2
2509  * │       ├── do1
2510  * │       │   ├── fl3
2511  * │       │   └── fo2
2512  * │       ├── fl1
2513  * │       └── fo1
2514  * ├── merge
2515  * │   └── data
2516  * │       ├── dl1
2517  * │       │   └── fl2
2518  * │       ├── do1
2519  * │       │   ├── fl3
2520  * │       │   ├── fo2
2521  * │       │   └── fu3
2522  * │       ├── du1
2523  * │       │   └── fu2
2524  * │       ├── fl1
2525  * │       ├── fo1
2526  * │       └── fu1
2527  * └── upper
2528  *     ├── data
2529  *     │   ├── do1
2530  *     │   │   ├── fo2
2531  *     │   │   └── fu3
2532  *     │   ├── du1
2533  *     │   │   └── fu2
2534  *     │   ├── fo1
2535  *     │   └── fu1
2536  *     └── work
2537  *         └── work
2538  */
2539 
2540 /* clang-format off */
2541 FIXTURE(layout2_overlay) {};
2542 /* clang-format on */
2543 
2544 FIXTURE_SETUP(layout2_overlay)
2545 {
2546 	prepare_layout(_metadata);
2547 
2548 	create_directory(_metadata, LOWER_BASE);
2549 	set_cap(_metadata, CAP_SYS_ADMIN);
2550 	/* Creates tmpfs mount points to get deterministic overlayfs. */
2551 	ASSERT_EQ(0, mount("tmp", LOWER_BASE, "tmpfs", 0, "size=4m,mode=700"));
2552 	clear_cap(_metadata, CAP_SYS_ADMIN);
2553 	create_file(_metadata, lower_fl1);
2554 	create_file(_metadata, lower_dl1_fl2);
2555 	create_file(_metadata, lower_fo1);
2556 	create_file(_metadata, lower_do1_fo2);
2557 	create_file(_metadata, lower_do1_fl3);
2558 
2559 	create_directory(_metadata, UPPER_BASE);
2560 	set_cap(_metadata, CAP_SYS_ADMIN);
2561 	ASSERT_EQ(0, mount("tmp", UPPER_BASE, "tmpfs", 0, "size=4m,mode=700"));
2562 	clear_cap(_metadata, CAP_SYS_ADMIN);
2563 	create_file(_metadata, upper_fu1);
2564 	create_file(_metadata, upper_du1_fu2);
2565 	create_file(_metadata, upper_fo1);
2566 	create_file(_metadata, upper_do1_fo2);
2567 	create_file(_metadata, upper_do1_fu3);
2568 	ASSERT_EQ(0, mkdir(UPPER_WORK, 0700));
2569 
2570 	create_directory(_metadata, MERGE_DATA);
2571 	set_cap(_metadata, CAP_SYS_ADMIN);
2572 	set_cap(_metadata, CAP_DAC_OVERRIDE);
2573 	ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0,
2574 			   "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA
2575 			   ",workdir=" UPPER_WORK));
2576 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
2577 	clear_cap(_metadata, CAP_SYS_ADMIN);
2578 }
2579 
2580 FIXTURE_TEARDOWN(layout2_overlay)
2581 {
2582 	EXPECT_EQ(0, remove_path(lower_do1_fl3));
2583 	EXPECT_EQ(0, remove_path(lower_dl1_fl2));
2584 	EXPECT_EQ(0, remove_path(lower_fl1));
2585 	EXPECT_EQ(0, remove_path(lower_do1_fo2));
2586 	EXPECT_EQ(0, remove_path(lower_fo1));
2587 	set_cap(_metadata, CAP_SYS_ADMIN);
2588 	EXPECT_EQ(0, umount(LOWER_BASE));
2589 	clear_cap(_metadata, CAP_SYS_ADMIN);
2590 	EXPECT_EQ(0, remove_path(LOWER_BASE));
2591 
2592 	EXPECT_EQ(0, remove_path(upper_do1_fu3));
2593 	EXPECT_EQ(0, remove_path(upper_du1_fu2));
2594 	EXPECT_EQ(0, remove_path(upper_fu1));
2595 	EXPECT_EQ(0, remove_path(upper_do1_fo2));
2596 	EXPECT_EQ(0, remove_path(upper_fo1));
2597 	EXPECT_EQ(0, remove_path(UPPER_WORK "/work"));
2598 	set_cap(_metadata, CAP_SYS_ADMIN);
2599 	EXPECT_EQ(0, umount(UPPER_BASE));
2600 	clear_cap(_metadata, CAP_SYS_ADMIN);
2601 	EXPECT_EQ(0, remove_path(UPPER_BASE));
2602 
2603 	set_cap(_metadata, CAP_SYS_ADMIN);
2604 	EXPECT_EQ(0, umount(MERGE_DATA));
2605 	clear_cap(_metadata, CAP_SYS_ADMIN);
2606 	EXPECT_EQ(0, remove_path(MERGE_DATA));
2607 
2608 	cleanup_layout(_metadata);
2609 }
2610 
2611 TEST_F_FORK(layout2_overlay, no_restriction)
2612 {
2613 	ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
2614 	ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
2615 	ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
2616 	ASSERT_EQ(0, test_open(lower_fo1, O_RDONLY));
2617 	ASSERT_EQ(0, test_open(lower_do1, O_RDONLY));
2618 	ASSERT_EQ(0, test_open(lower_do1_fo2, O_RDONLY));
2619 	ASSERT_EQ(0, test_open(lower_do1_fl3, O_RDONLY));
2620 
2621 	ASSERT_EQ(0, test_open(upper_fu1, O_RDONLY));
2622 	ASSERT_EQ(0, test_open(upper_du1, O_RDONLY));
2623 	ASSERT_EQ(0, test_open(upper_du1_fu2, O_RDONLY));
2624 	ASSERT_EQ(0, test_open(upper_fo1, O_RDONLY));
2625 	ASSERT_EQ(0, test_open(upper_do1, O_RDONLY));
2626 	ASSERT_EQ(0, test_open(upper_do1_fo2, O_RDONLY));
2627 	ASSERT_EQ(0, test_open(upper_do1_fu3, O_RDONLY));
2628 
2629 	ASSERT_EQ(0, test_open(merge_fl1, O_RDONLY));
2630 	ASSERT_EQ(0, test_open(merge_dl1, O_RDONLY));
2631 	ASSERT_EQ(0, test_open(merge_dl1_fl2, O_RDONLY));
2632 	ASSERT_EQ(0, test_open(merge_fu1, O_RDONLY));
2633 	ASSERT_EQ(0, test_open(merge_du1, O_RDONLY));
2634 	ASSERT_EQ(0, test_open(merge_du1_fu2, O_RDONLY));
2635 	ASSERT_EQ(0, test_open(merge_fo1, O_RDONLY));
2636 	ASSERT_EQ(0, test_open(merge_do1, O_RDONLY));
2637 	ASSERT_EQ(0, test_open(merge_do1_fo2, O_RDONLY));
2638 	ASSERT_EQ(0, test_open(merge_do1_fl3, O_RDONLY));
2639 	ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY));
2640 }
2641 
2642 #define for_each_path(path_list, path_entry, i)               \
2643 	for (i = 0, path_entry = *path_list[i]; path_list[i]; \
2644 	     path_entry = *path_list[++i])
2645 
2646 TEST_F_FORK(layout2_overlay, same_content_different_file)
2647 {
2648 	/* Sets access right on parent directories of both layers. */
2649 	const struct rule layer1_base[] = {
2650 		{
2651 			.path = LOWER_BASE,
2652 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2653 		},
2654 		{
2655 			.path = UPPER_BASE,
2656 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2657 		},
2658 		{
2659 			.path = MERGE_BASE,
2660 			.access = ACCESS_RW,
2661 		},
2662 		{},
2663 	};
2664 	const struct rule layer2_data[] = {
2665 		{
2666 			.path = LOWER_DATA,
2667 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2668 		},
2669 		{
2670 			.path = UPPER_DATA,
2671 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2672 		},
2673 		{
2674 			.path = MERGE_DATA,
2675 			.access = ACCESS_RW,
2676 		},
2677 		{},
2678 	};
2679 	/* Sets access right on directories inside both layers. */
2680 	const struct rule layer3_subdirs[] = {
2681 		{
2682 			.path = lower_dl1,
2683 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2684 		},
2685 		{
2686 			.path = lower_do1,
2687 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2688 		},
2689 		{
2690 			.path = upper_du1,
2691 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2692 		},
2693 		{
2694 			.path = upper_do1,
2695 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2696 		},
2697 		{
2698 			.path = merge_dl1,
2699 			.access = ACCESS_RW,
2700 		},
2701 		{
2702 			.path = merge_du1,
2703 			.access = ACCESS_RW,
2704 		},
2705 		{
2706 			.path = merge_do1,
2707 			.access = ACCESS_RW,
2708 		},
2709 		{},
2710 	};
2711 	/* Tighten access rights to the files. */
2712 	const struct rule layer4_files[] = {
2713 		{
2714 			.path = lower_dl1_fl2,
2715 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2716 		},
2717 		{
2718 			.path = lower_do1_fo2,
2719 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2720 		},
2721 		{
2722 			.path = lower_do1_fl3,
2723 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2724 		},
2725 		{
2726 			.path = upper_du1_fu2,
2727 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2728 		},
2729 		{
2730 			.path = upper_do1_fo2,
2731 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2732 		},
2733 		{
2734 			.path = upper_do1_fu3,
2735 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2736 		},
2737 		{
2738 			.path = merge_dl1_fl2,
2739 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2740 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2741 		},
2742 		{
2743 			.path = merge_du1_fu2,
2744 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2745 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2746 		},
2747 		{
2748 			.path = merge_do1_fo2,
2749 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2750 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2751 		},
2752 		{
2753 			.path = merge_do1_fl3,
2754 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2755 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2756 		},
2757 		{
2758 			.path = merge_do1_fu3,
2759 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2760 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2761 		},
2762 		{},
2763 	};
2764 	const struct rule layer5_merge_only[] = {
2765 		{
2766 			.path = MERGE_DATA,
2767 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2768 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2769 		},
2770 		{},
2771 	};
2772 	int ruleset_fd;
2773 	size_t i;
2774 	const char *path_entry;
2775 
2776 	/* Sets rules on base directories (i.e. outside overlay scope). */
2777 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
2778 	ASSERT_LE(0, ruleset_fd);
2779 	enforce_ruleset(_metadata, ruleset_fd);
2780 	ASSERT_EQ(0, close(ruleset_fd));
2781 
2782 	/* Checks lower layer. */
2783 	for_each_path(lower_base_files, path_entry, i) {
2784 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2785 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2786 	}
2787 	for_each_path(lower_base_directories, path_entry, i) {
2788 		ASSERT_EQ(EACCES,
2789 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2790 	}
2791 	for_each_path(lower_sub_files, path_entry, i) {
2792 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2793 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2794 	}
2795 	/* Checks upper layer. */
2796 	for_each_path(upper_base_files, path_entry, i) {
2797 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2798 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2799 	}
2800 	for_each_path(upper_base_directories, path_entry, i) {
2801 		ASSERT_EQ(EACCES,
2802 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2803 	}
2804 	for_each_path(upper_sub_files, path_entry, i) {
2805 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2806 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2807 	}
2808 	/*
2809 	 * Checks that access rights are independent from the lower and upper
2810 	 * layers: write access to upper files viewed through the merge point
2811 	 * is still allowed, and write access to lower file viewed (and copied)
2812 	 * through the merge point is still allowed.
2813 	 */
2814 	for_each_path(merge_base_files, path_entry, i) {
2815 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2816 	}
2817 	for_each_path(merge_base_directories, path_entry, i) {
2818 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2819 	}
2820 	for_each_path(merge_sub_files, path_entry, i) {
2821 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2822 	}
2823 
2824 	/* Sets rules on data directories (i.e. inside overlay scope). */
2825 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_data);
2826 	ASSERT_LE(0, ruleset_fd);
2827 	enforce_ruleset(_metadata, ruleset_fd);
2828 	ASSERT_EQ(0, close(ruleset_fd));
2829 
2830 	/* Checks merge. */
2831 	for_each_path(merge_base_files, path_entry, i) {
2832 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2833 	}
2834 	for_each_path(merge_base_directories, path_entry, i) {
2835 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2836 	}
2837 	for_each_path(merge_sub_files, path_entry, i) {
2838 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2839 	}
2840 
2841 	/* Same checks with tighter rules. */
2842 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_subdirs);
2843 	ASSERT_LE(0, ruleset_fd);
2844 	enforce_ruleset(_metadata, ruleset_fd);
2845 	ASSERT_EQ(0, close(ruleset_fd));
2846 
2847 	/* Checks changes for lower layer. */
2848 	for_each_path(lower_base_files, path_entry, i) {
2849 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2850 	}
2851 	/* Checks changes for upper layer. */
2852 	for_each_path(upper_base_files, path_entry, i) {
2853 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2854 	}
2855 	/* Checks all merge accesses. */
2856 	for_each_path(merge_base_files, path_entry, i) {
2857 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
2858 	}
2859 	for_each_path(merge_base_directories, path_entry, i) {
2860 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2861 	}
2862 	for_each_path(merge_sub_files, path_entry, i) {
2863 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2864 	}
2865 
2866 	/* Sets rules directly on overlayed files. */
2867 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_files);
2868 	ASSERT_LE(0, ruleset_fd);
2869 	enforce_ruleset(_metadata, ruleset_fd);
2870 	ASSERT_EQ(0, close(ruleset_fd));
2871 
2872 	/* Checks unchanged accesses on lower layer. */
2873 	for_each_path(lower_sub_files, path_entry, i) {
2874 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2875 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2876 	}
2877 	/* Checks unchanged accesses on upper layer. */
2878 	for_each_path(upper_sub_files, path_entry, i) {
2879 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2880 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2881 	}
2882 	/* Checks all merge accesses. */
2883 	for_each_path(merge_base_files, path_entry, i) {
2884 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
2885 	}
2886 	for_each_path(merge_base_directories, path_entry, i) {
2887 		ASSERT_EQ(EACCES,
2888 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2889 	}
2890 	for_each_path(merge_sub_files, path_entry, i) {
2891 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2892 	}
2893 
2894 	/* Only allowes access to the merge hierarchy. */
2895 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer5_merge_only);
2896 	ASSERT_LE(0, ruleset_fd);
2897 	enforce_ruleset(_metadata, ruleset_fd);
2898 	ASSERT_EQ(0, close(ruleset_fd));
2899 
2900 	/* Checks new accesses on lower layer. */
2901 	for_each_path(lower_sub_files, path_entry, i) {
2902 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2903 	}
2904 	/* Checks new accesses on upper layer. */
2905 	for_each_path(upper_sub_files, path_entry, i) {
2906 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2907 	}
2908 	/* Checks all merge accesses. */
2909 	for_each_path(merge_base_files, path_entry, i) {
2910 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
2911 	}
2912 	for_each_path(merge_base_directories, path_entry, i) {
2913 		ASSERT_EQ(EACCES,
2914 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2915 	}
2916 	for_each_path(merge_sub_files, path_entry, i) {
2917 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2918 	}
2919 }
2920 
2921 TEST_HARNESS_MAIN
2922