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, layer_rule_unions)
762 {
763 	const struct rule layer1[] = {
764 		{
765 			.path = dir_s1d2,
766 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
767 		},
768 		/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
769 		{
770 			.path = dir_s1d3,
771 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
772 		},
773 		{},
774 	};
775 	const struct rule layer2[] = {
776 		/* Doesn't change anything from layer1. */
777 		{
778 			.path = dir_s1d2,
779 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
780 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
781 		},
782 		{},
783 	};
784 	const struct rule layer3[] = {
785 		/* Only allows write (but not read) to dir_s1d3. */
786 		{
787 			.path = dir_s1d2,
788 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
789 		},
790 		{},
791 	};
792 	int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1);
793 
794 	ASSERT_LE(0, ruleset_fd);
795 	enforce_ruleset(_metadata, ruleset_fd);
796 	ASSERT_EQ(0, close(ruleset_fd));
797 
798 	/* Checks s1d1 hierarchy with layer1. */
799 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
800 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
801 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
802 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
803 
804 	/* Checks s1d2 hierarchy with layer1. */
805 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
806 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
807 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
808 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
809 
810 	/* Checks s1d3 hierarchy with layer1. */
811 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
812 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
813 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
814 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
815 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
816 
817 	/* Doesn't change anything from layer1. */
818 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2);
819 	ASSERT_LE(0, ruleset_fd);
820 	enforce_ruleset(_metadata, ruleset_fd);
821 	ASSERT_EQ(0, close(ruleset_fd));
822 
823 	/* Checks s1d1 hierarchy with layer2. */
824 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
825 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
826 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
827 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
828 
829 	/* Checks s1d2 hierarchy with layer2. */
830 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
831 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
832 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
833 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
834 
835 	/* Checks s1d3 hierarchy with layer2. */
836 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
837 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
838 	/* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */
839 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
840 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
841 
842 	/* Only allows write (but not read) to dir_s1d3. */
843 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3);
844 	ASSERT_LE(0, ruleset_fd);
845 	enforce_ruleset(_metadata, ruleset_fd);
846 	ASSERT_EQ(0, close(ruleset_fd));
847 
848 	/* Checks s1d1 hierarchy with layer3. */
849 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
850 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
851 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
852 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
853 
854 	/* Checks s1d2 hierarchy with layer3. */
855 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
856 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
857 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
858 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
859 
860 	/* Checks s1d3 hierarchy with layer3. */
861 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
862 	ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY));
863 	/* dir_s1d3 should now deny READ_FILE and WRITE_FILE (O_RDWR). */
864 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDWR));
865 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
866 }
867 
868 TEST_F_FORK(layout1, non_overlapping_accesses)
869 {
870 	const struct rule layer1[] = {
871 		{
872 			.path = dir_s1d2,
873 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
874 		},
875 		{},
876 	};
877 	const struct rule layer2[] = {
878 		{
879 			.path = dir_s1d3,
880 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
881 		},
882 		{},
883 	};
884 	int ruleset_fd;
885 
886 	ASSERT_EQ(0, unlink(file1_s1d1));
887 	ASSERT_EQ(0, unlink(file1_s1d2));
888 
889 	ruleset_fd =
890 		create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1);
891 	ASSERT_LE(0, ruleset_fd);
892 	enforce_ruleset(_metadata, ruleset_fd);
893 	ASSERT_EQ(0, close(ruleset_fd));
894 
895 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
896 	ASSERT_EQ(EACCES, errno);
897 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
898 	ASSERT_EQ(0, unlink(file1_s1d2));
899 
900 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE,
901 				    layer2);
902 	ASSERT_LE(0, ruleset_fd);
903 	enforce_ruleset(_metadata, ruleset_fd);
904 	ASSERT_EQ(0, close(ruleset_fd));
905 
906 	/* Unchanged accesses for file creation. */
907 	ASSERT_EQ(-1, mknod(file1_s1d1, S_IFREG | 0700, 0));
908 	ASSERT_EQ(EACCES, errno);
909 	ASSERT_EQ(0, mknod(file1_s1d2, S_IFREG | 0700, 0));
910 
911 	/* Checks file removing. */
912 	ASSERT_EQ(-1, unlink(file1_s1d2));
913 	ASSERT_EQ(EACCES, errno);
914 	ASSERT_EQ(0, unlink(file1_s1d3));
915 }
916 
917 TEST_F_FORK(layout1, interleaved_masked_accesses)
918 {
919 	/*
920 	 * Checks overly restrictive rules:
921 	 * layer 1: allows R   s1d1/s1d2/s1d3/file1
922 	 * layer 2: allows RW  s1d1/s1d2/s1d3
923 	 *          allows  W  s1d1/s1d2
924 	 *          denies R   s1d1/s1d2
925 	 * layer 3: allows R   s1d1
926 	 * layer 4: allows R   s1d1/s1d2
927 	 *          denies  W  s1d1/s1d2
928 	 * layer 5: allows R   s1d1/s1d2
929 	 * layer 6: allows   X ----
930 	 * layer 7: allows  W  s1d1/s1d2
931 	 *          denies R   s1d1/s1d2
932 	 */
933 	const struct rule layer1_read[] = {
934 		/* Allows read access to file1_s1d3 with the first layer. */
935 		{
936 			.path = file1_s1d3,
937 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
938 		},
939 		{},
940 	};
941 	/* First rule with write restrictions. */
942 	const struct rule layer2_read_write[] = {
943 		/* Start by granting read-write access via its parent directory... */
944 		{
945 			.path = dir_s1d3,
946 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
947 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
948 		},
949 		/* ...but also denies read access via its grandparent directory. */
950 		{
951 			.path = dir_s1d2,
952 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
953 		},
954 		{},
955 	};
956 	const struct rule layer3_read[] = {
957 		/* Allows read access via its great-grandparent directory. */
958 		{
959 			.path = dir_s1d1,
960 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
961 		},
962 		{},
963 	};
964 	const struct rule layer4_read_write[] = {
965 		/*
966 		 * Try to confuse the deny access by denying write (but not
967 		 * read) access via its grandparent directory.
968 		 */
969 		{
970 			.path = dir_s1d2,
971 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
972 		},
973 		{},
974 	};
975 	const struct rule layer5_read[] = {
976 		/*
977 		 * Try to override layer2's deny read access by explicitly
978 		 * allowing read access via file1_s1d3's grandparent.
979 		 */
980 		{
981 			.path = dir_s1d2,
982 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
983 		},
984 		{},
985 	};
986 	const struct rule layer6_execute[] = {
987 		/*
988 		 * Restricts an unrelated file hierarchy with a new access
989 		 * (non-overlapping) type.
990 		 */
991 		{
992 			.path = dir_s2d1,
993 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
994 		},
995 		{},
996 	};
997 	const struct rule layer7_read_write[] = {
998 		/*
999 		 * Finally, denies read access to file1_s1d3 via its
1000 		 * grandparent.
1001 		 */
1002 		{
1003 			.path = dir_s1d2,
1004 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
1005 		},
1006 		{},
1007 	};
1008 	int ruleset_fd;
1009 
1010 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1011 				    layer1_read);
1012 	ASSERT_LE(0, ruleset_fd);
1013 	enforce_ruleset(_metadata, ruleset_fd);
1014 	ASSERT_EQ(0, close(ruleset_fd));
1015 
1016 	/* Checks that read access is granted for file1_s1d3 with layer 1. */
1017 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1018 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1019 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1020 
1021 	ruleset_fd = create_ruleset(_metadata,
1022 				    LANDLOCK_ACCESS_FS_READ_FILE |
1023 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1024 				    layer2_read_write);
1025 	ASSERT_LE(0, ruleset_fd);
1026 	enforce_ruleset(_metadata, ruleset_fd);
1027 	ASSERT_EQ(0, close(ruleset_fd));
1028 
1029 	/* Checks that previous access rights are unchanged with layer 2. */
1030 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1031 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1032 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1033 
1034 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1035 				    layer3_read);
1036 	ASSERT_LE(0, ruleset_fd);
1037 	enforce_ruleset(_metadata, ruleset_fd);
1038 	ASSERT_EQ(0, close(ruleset_fd));
1039 
1040 	/* Checks that previous access rights are unchanged with layer 3. */
1041 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR));
1042 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1043 	ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
1044 
1045 	/* This time, denies write access for the file hierarchy. */
1046 	ruleset_fd = create_ruleset(_metadata,
1047 				    LANDLOCK_ACCESS_FS_READ_FILE |
1048 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1049 				    layer4_read_write);
1050 	ASSERT_LE(0, ruleset_fd);
1051 	enforce_ruleset(_metadata, ruleset_fd);
1052 	ASSERT_EQ(0, close(ruleset_fd));
1053 
1054 	/*
1055 	 * Checks that the only change with layer 4 is that write access is
1056 	 * denied.
1057 	 */
1058 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1059 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1060 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1061 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1062 
1063 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
1064 				    layer5_read);
1065 	ASSERT_LE(0, ruleset_fd);
1066 	enforce_ruleset(_metadata, ruleset_fd);
1067 	ASSERT_EQ(0, close(ruleset_fd));
1068 
1069 	/* Checks that previous access rights are unchanged with layer 5. */
1070 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1071 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1072 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1073 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1074 
1075 	ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_EXECUTE,
1076 				    layer6_execute);
1077 	ASSERT_LE(0, ruleset_fd);
1078 	enforce_ruleset(_metadata, ruleset_fd);
1079 	ASSERT_EQ(0, close(ruleset_fd));
1080 
1081 	/* Checks that previous access rights are unchanged with layer 6. */
1082 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1083 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1084 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1085 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1086 
1087 	ruleset_fd = create_ruleset(_metadata,
1088 				    LANDLOCK_ACCESS_FS_READ_FILE |
1089 					    LANDLOCK_ACCESS_FS_WRITE_FILE,
1090 				    layer7_read_write);
1091 	ASSERT_LE(0, ruleset_fd);
1092 	enforce_ruleset(_metadata, ruleset_fd);
1093 	ASSERT_EQ(0, close(ruleset_fd));
1094 
1095 	/* Checks read access is now denied with layer 7. */
1096 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
1097 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1098 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
1099 	ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
1100 }
1101 
1102 TEST_F_FORK(layout1, inherit_subset)
1103 {
1104 	const struct rule rules[] = {
1105 		{
1106 			.path = dir_s1d2,
1107 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
1108 				  LANDLOCK_ACCESS_FS_READ_DIR,
1109 		},
1110 		{},
1111 	};
1112 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1113 
1114 	ASSERT_LE(0, ruleset_fd);
1115 	enforce_ruleset(_metadata, ruleset_fd);
1116 
1117 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1118 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1119 
1120 	/* Write access is forbidden. */
1121 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1122 	/* Readdir access is allowed. */
1123 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1124 
1125 	/* Write access is forbidden. */
1126 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1127 	/* Readdir access is allowed. */
1128 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1129 
1130 	/*
1131 	 * Tests shared rule extension: the following rules should not grant
1132 	 * any new access, only remove some.  Once enforced, these rules are
1133 	 * ANDed with the previous ones.
1134 	 */
1135 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1136 			 dir_s1d2);
1137 	/*
1138 	 * According to ruleset_fd, dir_s1d2 should now have the
1139 	 * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE
1140 	 * access rights (even if this directory is opened a second time).
1141 	 * However, when enforcing this updated ruleset, the ruleset tied to
1142 	 * the current process (i.e. its domain) will still only have the
1143 	 * dir_s1d2 with LANDLOCK_ACCESS_FS_READ_FILE and
1144 	 * LANDLOCK_ACCESS_FS_READ_DIR accesses, but
1145 	 * LANDLOCK_ACCESS_FS_WRITE_FILE must not be allowed because it would
1146 	 * be a privilege escalation.
1147 	 */
1148 	enforce_ruleset(_metadata, ruleset_fd);
1149 
1150 	/* Same tests and results as above. */
1151 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1152 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1153 
1154 	/* It is still forbidden to write in file1_s1d2. */
1155 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1156 	/* Readdir access is still allowed. */
1157 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1158 
1159 	/* It is still forbidden to write in file1_s1d3. */
1160 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1161 	/* Readdir access is still allowed. */
1162 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1163 
1164 	/*
1165 	 * Try to get more privileges by adding new access rights to the parent
1166 	 * directory: dir_s1d1.
1167 	 */
1168 	add_path_beneath(_metadata, ruleset_fd, ACCESS_RW, dir_s1d1);
1169 	enforce_ruleset(_metadata, ruleset_fd);
1170 
1171 	/* Same tests and results as above. */
1172 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1173 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1174 
1175 	/* It is still forbidden to write in file1_s1d2. */
1176 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1177 	/* Readdir access is still allowed. */
1178 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1179 
1180 	/* It is still forbidden to write in file1_s1d3. */
1181 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1182 	/* Readdir access is still allowed. */
1183 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1184 
1185 	/*
1186 	 * Now, dir_s1d3 get a new rule tied to it, only allowing
1187 	 * LANDLOCK_ACCESS_FS_WRITE_FILE.  The (kernel internal) difference is
1188 	 * that there was no rule tied to it before.
1189 	 */
1190 	add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE,
1191 			 dir_s1d3);
1192 	enforce_ruleset(_metadata, ruleset_fd);
1193 	ASSERT_EQ(0, close(ruleset_fd));
1194 
1195 	/*
1196 	 * Same tests and results as above, except for open(dir_s1d3) which is
1197 	 * now denied because the new rule mask the rule previously inherited
1198 	 * from dir_s1d2.
1199 	 */
1200 
1201 	/* Same tests and results as above. */
1202 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
1203 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
1204 
1205 	/* It is still forbidden to write in file1_s1d2. */
1206 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
1207 	/* Readdir access is still allowed. */
1208 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1209 
1210 	/* It is still forbidden to write in file1_s1d3. */
1211 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
1212 	/*
1213 	 * Readdir of dir_s1d3 is still allowed because of the OR policy inside
1214 	 * the same layer.
1215 	 */
1216 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1217 }
1218 
1219 TEST_F_FORK(layout1, inherit_superset)
1220 {
1221 	const struct rule rules[] = {
1222 		{
1223 			.path = dir_s1d3,
1224 			.access = ACCESS_RO,
1225 		},
1226 		{},
1227 	};
1228 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1229 
1230 	ASSERT_LE(0, ruleset_fd);
1231 	enforce_ruleset(_metadata, ruleset_fd);
1232 
1233 	/* Readdir access is denied for dir_s1d2. */
1234 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1235 	/* Readdir access is allowed for dir_s1d3. */
1236 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1237 	/* File access is allowed for file1_s1d3. */
1238 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1239 
1240 	/* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */
1241 	add_path_beneath(_metadata, ruleset_fd,
1242 			 LANDLOCK_ACCESS_FS_READ_FILE |
1243 				 LANDLOCK_ACCESS_FS_READ_DIR,
1244 			 dir_s1d2);
1245 	enforce_ruleset(_metadata, ruleset_fd);
1246 	ASSERT_EQ(0, close(ruleset_fd));
1247 
1248 	/* Readdir access is still denied for dir_s1d2. */
1249 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
1250 	/* Readdir access is still allowed for dir_s1d3. */
1251 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
1252 	/* File access is still allowed for file1_s1d3. */
1253 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1254 }
1255 
1256 TEST_F_FORK(layout1, max_layers)
1257 {
1258 	int i, err;
1259 	const struct rule rules[] = {
1260 		{
1261 			.path = dir_s1d2,
1262 			.access = ACCESS_RO,
1263 		},
1264 		{},
1265 	};
1266 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1267 
1268 	ASSERT_LE(0, ruleset_fd);
1269 	for (i = 0; i < 16; i++)
1270 		enforce_ruleset(_metadata, ruleset_fd);
1271 
1272 	for (i = 0; i < 2; i++) {
1273 		err = landlock_restrict_self(ruleset_fd, 0);
1274 		ASSERT_EQ(-1, err);
1275 		ASSERT_EQ(E2BIG, errno);
1276 	}
1277 	ASSERT_EQ(0, close(ruleset_fd));
1278 }
1279 
1280 TEST_F_FORK(layout1, empty_or_same_ruleset)
1281 {
1282 	struct landlock_ruleset_attr ruleset_attr = {};
1283 	int ruleset_fd;
1284 
1285 	/* Tests empty handled_access_fs. */
1286 	ruleset_fd =
1287 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1288 	ASSERT_LE(-1, ruleset_fd);
1289 	ASSERT_EQ(ENOMSG, errno);
1290 
1291 	/* Enforces policy which deny read access to all files. */
1292 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE;
1293 	ruleset_fd =
1294 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1295 	ASSERT_LE(0, ruleset_fd);
1296 	enforce_ruleset(_metadata, ruleset_fd);
1297 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1298 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1299 
1300 	/* Nests a policy which deny read access to all directories. */
1301 	ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR;
1302 	ruleset_fd =
1303 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
1304 	ASSERT_LE(0, ruleset_fd);
1305 	enforce_ruleset(_metadata, ruleset_fd);
1306 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
1307 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1308 
1309 	/* Enforces a second time with the same ruleset. */
1310 	enforce_ruleset(_metadata, ruleset_fd);
1311 	ASSERT_EQ(0, close(ruleset_fd));
1312 }
1313 
1314 TEST_F_FORK(layout1, rule_on_mountpoint)
1315 {
1316 	const struct rule rules[] = {
1317 		{
1318 			.path = dir_s1d1,
1319 			.access = ACCESS_RO,
1320 		},
1321 		{
1322 			/* dir_s3d2 is a mount point. */
1323 			.path = dir_s3d2,
1324 			.access = ACCESS_RO,
1325 		},
1326 		{},
1327 	};
1328 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1329 
1330 	ASSERT_LE(0, ruleset_fd);
1331 	enforce_ruleset(_metadata, ruleset_fd);
1332 	ASSERT_EQ(0, close(ruleset_fd));
1333 
1334 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1335 
1336 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1337 
1338 	ASSERT_EQ(EACCES, test_open(dir_s3d1, O_RDONLY));
1339 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1340 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1341 }
1342 
1343 TEST_F_FORK(layout1, rule_over_mountpoint)
1344 {
1345 	const struct rule rules[] = {
1346 		{
1347 			.path = dir_s1d1,
1348 			.access = ACCESS_RO,
1349 		},
1350 		{
1351 			/* dir_s3d2 is a mount point. */
1352 			.path = dir_s3d1,
1353 			.access = ACCESS_RO,
1354 		},
1355 		{},
1356 	};
1357 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1358 
1359 	ASSERT_LE(0, ruleset_fd);
1360 	enforce_ruleset(_metadata, ruleset_fd);
1361 	ASSERT_EQ(0, close(ruleset_fd));
1362 
1363 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1364 
1365 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY));
1366 
1367 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
1368 	ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
1369 	ASSERT_EQ(0, test_open(dir_s3d3, O_RDONLY));
1370 }
1371 
1372 /*
1373  * This test verifies that we can apply a landlock rule on the root directory
1374  * (which might require special handling).
1375  */
1376 TEST_F_FORK(layout1, rule_over_root_allow_then_deny)
1377 {
1378 	struct rule rules[] = {
1379 		{
1380 			.path = "/",
1381 			.access = ACCESS_RO,
1382 		},
1383 		{},
1384 	};
1385 	int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1386 
1387 	ASSERT_LE(0, ruleset_fd);
1388 	enforce_ruleset(_metadata, ruleset_fd);
1389 	ASSERT_EQ(0, close(ruleset_fd));
1390 
1391 	/* Checks allowed access. */
1392 	ASSERT_EQ(0, test_open("/", O_RDONLY));
1393 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1394 
1395 	rules[0].access = LANDLOCK_ACCESS_FS_READ_FILE;
1396 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1397 	ASSERT_LE(0, ruleset_fd);
1398 	enforce_ruleset(_metadata, ruleset_fd);
1399 	ASSERT_EQ(0, close(ruleset_fd));
1400 
1401 	/* Checks denied access (on a directory). */
1402 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1403 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1404 }
1405 
1406 TEST_F_FORK(layout1, rule_over_root_deny)
1407 {
1408 	const struct rule rules[] = {
1409 		{
1410 			.path = "/",
1411 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
1412 		},
1413 		{},
1414 	};
1415 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1416 
1417 	ASSERT_LE(0, ruleset_fd);
1418 	enforce_ruleset(_metadata, ruleset_fd);
1419 	ASSERT_EQ(0, close(ruleset_fd));
1420 
1421 	/* Checks denied access (on a directory). */
1422 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1423 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
1424 }
1425 
1426 TEST_F_FORK(layout1, rule_inside_mount_ns)
1427 {
1428 	const struct rule rules[] = {
1429 		{
1430 			.path = "s3d3",
1431 			.access = ACCESS_RO,
1432 		},
1433 		{},
1434 	};
1435 	int ruleset_fd;
1436 
1437 	set_cap(_metadata, CAP_SYS_ADMIN);
1438 	ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3))
1439 	{
1440 		TH_LOG("Failed to pivot root: %s", strerror(errno));
1441 	};
1442 	ASSERT_EQ(0, chdir("/"));
1443 	clear_cap(_metadata, CAP_SYS_ADMIN);
1444 
1445 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1446 	ASSERT_LE(0, ruleset_fd);
1447 	enforce_ruleset(_metadata, ruleset_fd);
1448 	ASSERT_EQ(0, close(ruleset_fd));
1449 
1450 	ASSERT_EQ(0, test_open("s3d3", O_RDONLY));
1451 	ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
1452 }
1453 
1454 TEST_F_FORK(layout1, mount_and_pivot)
1455 {
1456 	const struct rule rules[] = {
1457 		{
1458 			.path = dir_s3d2,
1459 			.access = ACCESS_RO,
1460 		},
1461 		{},
1462 	};
1463 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1464 
1465 	ASSERT_LE(0, ruleset_fd);
1466 	enforce_ruleset(_metadata, ruleset_fd);
1467 	ASSERT_EQ(0, close(ruleset_fd));
1468 
1469 	set_cap(_metadata, CAP_SYS_ADMIN);
1470 	ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
1471 	ASSERT_EQ(EPERM, errno);
1472 	ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
1473 	ASSERT_EQ(EPERM, errno);
1474 	clear_cap(_metadata, CAP_SYS_ADMIN);
1475 }
1476 
1477 TEST_F_FORK(layout1, move_mount)
1478 {
1479 	const struct rule rules[] = {
1480 		{
1481 			.path = dir_s3d2,
1482 			.access = ACCESS_RO,
1483 		},
1484 		{},
1485 	};
1486 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1487 
1488 	ASSERT_LE(0, ruleset_fd);
1489 
1490 	set_cap(_metadata, CAP_SYS_ADMIN);
1491 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1492 			     dir_s1d2, 0))
1493 	{
1494 		TH_LOG("Failed to move mount: %s", strerror(errno));
1495 	}
1496 
1497 	ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
1498 			     dir_s3d2, 0));
1499 	clear_cap(_metadata, CAP_SYS_ADMIN);
1500 
1501 	enforce_ruleset(_metadata, ruleset_fd);
1502 	ASSERT_EQ(0, close(ruleset_fd));
1503 
1504 	set_cap(_metadata, CAP_SYS_ADMIN);
1505 	ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
1506 			      dir_s1d2, 0));
1507 	ASSERT_EQ(EPERM, errno);
1508 	clear_cap(_metadata, CAP_SYS_ADMIN);
1509 }
1510 
1511 TEST_F_FORK(layout1, release_inodes)
1512 {
1513 	const struct rule rules[] = {
1514 		{
1515 			.path = dir_s1d1,
1516 			.access = ACCESS_RO,
1517 		},
1518 		{
1519 			.path = dir_s3d2,
1520 			.access = ACCESS_RO,
1521 		},
1522 		{
1523 			.path = dir_s3d3,
1524 			.access = ACCESS_RO,
1525 		},
1526 		{},
1527 	};
1528 	const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
1529 
1530 	ASSERT_LE(0, ruleset_fd);
1531 	/* Unmount a file hierarchy while it is being used by a ruleset. */
1532 	set_cap(_metadata, CAP_SYS_ADMIN);
1533 	ASSERT_EQ(0, umount(dir_s3d2));
1534 	clear_cap(_metadata, CAP_SYS_ADMIN);
1535 
1536 	enforce_ruleset(_metadata, ruleset_fd);
1537 	ASSERT_EQ(0, close(ruleset_fd));
1538 
1539 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1540 	ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
1541 	/* This dir_s3d3 would not be allowed and does not exist anyway. */
1542 	ASSERT_EQ(ENOENT, test_open(dir_s3d3, O_RDONLY));
1543 }
1544 
1545 enum relative_access {
1546 	REL_OPEN,
1547 	REL_CHDIR,
1548 	REL_CHROOT_ONLY,
1549 	REL_CHROOT_CHDIR,
1550 };
1551 
1552 static void test_relative_path(struct __test_metadata *const _metadata,
1553 			       const enum relative_access rel)
1554 {
1555 	/*
1556 	 * Common layer to check that chroot doesn't ignore it (i.e. a chroot
1557 	 * is not a disconnected root directory).
1558 	 */
1559 	const struct rule layer1_base[] = {
1560 		{
1561 			.path = TMP_DIR,
1562 			.access = ACCESS_RO,
1563 		},
1564 		{},
1565 	};
1566 	const struct rule layer2_subs[] = {
1567 		{
1568 			.path = dir_s1d2,
1569 			.access = ACCESS_RO,
1570 		},
1571 		{
1572 			.path = dir_s2d2,
1573 			.access = ACCESS_RO,
1574 		},
1575 		{},
1576 	};
1577 	int dirfd, ruleset_fd;
1578 
1579 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
1580 	ASSERT_LE(0, ruleset_fd);
1581 	enforce_ruleset(_metadata, ruleset_fd);
1582 	ASSERT_EQ(0, close(ruleset_fd));
1583 
1584 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_subs);
1585 
1586 	ASSERT_LE(0, ruleset_fd);
1587 	switch (rel) {
1588 	case REL_OPEN:
1589 	case REL_CHDIR:
1590 		break;
1591 	case REL_CHROOT_ONLY:
1592 		ASSERT_EQ(0, chdir(dir_s2d2));
1593 		break;
1594 	case REL_CHROOT_CHDIR:
1595 		ASSERT_EQ(0, chdir(dir_s1d2));
1596 		break;
1597 	default:
1598 		ASSERT_TRUE(false);
1599 		return;
1600 	}
1601 
1602 	set_cap(_metadata, CAP_SYS_CHROOT);
1603 	enforce_ruleset(_metadata, ruleset_fd);
1604 
1605 	switch (rel) {
1606 	case REL_OPEN:
1607 		dirfd = open(dir_s1d2, O_DIRECTORY);
1608 		ASSERT_LE(0, dirfd);
1609 		break;
1610 	case REL_CHDIR:
1611 		ASSERT_EQ(0, chdir(dir_s1d2));
1612 		dirfd = AT_FDCWD;
1613 		break;
1614 	case REL_CHROOT_ONLY:
1615 		/* Do chroot into dir_s1d2 (relative to dir_s2d2). */
1616 		ASSERT_EQ(0, chroot("../../s1d1/s1d2"))
1617 		{
1618 			TH_LOG("Failed to chroot: %s", strerror(errno));
1619 		}
1620 		dirfd = AT_FDCWD;
1621 		break;
1622 	case REL_CHROOT_CHDIR:
1623 		/* Do chroot into dir_s1d2. */
1624 		ASSERT_EQ(0, chroot("."))
1625 		{
1626 			TH_LOG("Failed to chroot: %s", strerror(errno));
1627 		}
1628 		dirfd = AT_FDCWD;
1629 		break;
1630 	}
1631 
1632 	ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES,
1633 		  test_open_rel(dirfd, "..", O_RDONLY));
1634 	ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY));
1635 
1636 	if (rel == REL_CHROOT_ONLY) {
1637 		/* The current directory is dir_s2d2. */
1638 		ASSERT_EQ(0, test_open_rel(dirfd, "./s2d3", O_RDONLY));
1639 	} else {
1640 		/* The current directory is dir_s1d2. */
1641 		ASSERT_EQ(0, test_open_rel(dirfd, "./s1d3", O_RDONLY));
1642 	}
1643 
1644 	if (rel == REL_CHROOT_ONLY || rel == REL_CHROOT_CHDIR) {
1645 		/* Checks the root dir_s1d2. */
1646 		ASSERT_EQ(0, test_open_rel(dirfd, "/..", O_RDONLY));
1647 		ASSERT_EQ(0, test_open_rel(dirfd, "/", O_RDONLY));
1648 		ASSERT_EQ(0, test_open_rel(dirfd, "/f1", O_RDONLY));
1649 		ASSERT_EQ(0, test_open_rel(dirfd, "/s1d3", O_RDONLY));
1650 	}
1651 
1652 	if (rel != REL_CHROOT_CHDIR) {
1653 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY));
1654 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY));
1655 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3",
1656 					   O_RDONLY));
1657 
1658 		ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY));
1659 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY));
1660 		ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3",
1661 					   O_RDONLY));
1662 	}
1663 
1664 	if (rel == REL_OPEN)
1665 		ASSERT_EQ(0, close(dirfd));
1666 	ASSERT_EQ(0, close(ruleset_fd));
1667 }
1668 
1669 TEST_F_FORK(layout1, relative_open)
1670 {
1671 	test_relative_path(_metadata, REL_OPEN);
1672 }
1673 
1674 TEST_F_FORK(layout1, relative_chdir)
1675 {
1676 	test_relative_path(_metadata, REL_CHDIR);
1677 }
1678 
1679 TEST_F_FORK(layout1, relative_chroot_only)
1680 {
1681 	test_relative_path(_metadata, REL_CHROOT_ONLY);
1682 }
1683 
1684 TEST_F_FORK(layout1, relative_chroot_chdir)
1685 {
1686 	test_relative_path(_metadata, REL_CHROOT_CHDIR);
1687 }
1688 
1689 static void copy_binary(struct __test_metadata *const _metadata,
1690 			const char *const dst_path)
1691 {
1692 	int dst_fd, src_fd;
1693 	struct stat statbuf;
1694 
1695 	dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC);
1696 	ASSERT_LE(0, dst_fd)
1697 	{
1698 		TH_LOG("Failed to open \"%s\": %s", dst_path, strerror(errno));
1699 	}
1700 	src_fd = open(BINARY_PATH, O_RDONLY | O_CLOEXEC);
1701 	ASSERT_LE(0, src_fd)
1702 	{
1703 		TH_LOG("Failed to open \"" BINARY_PATH "\": %s",
1704 		       strerror(errno));
1705 	}
1706 	ASSERT_EQ(0, fstat(src_fd, &statbuf));
1707 	ASSERT_EQ(statbuf.st_size,
1708 		  sendfile(dst_fd, src_fd, 0, statbuf.st_size));
1709 	ASSERT_EQ(0, close(src_fd));
1710 	ASSERT_EQ(0, close(dst_fd));
1711 }
1712 
1713 static void test_execute(struct __test_metadata *const _metadata, const int err,
1714 			 const char *const path)
1715 {
1716 	int status;
1717 	char *const argv[] = { (char *)path, NULL };
1718 	const pid_t child = fork();
1719 
1720 	ASSERT_LE(0, child);
1721 	if (child == 0) {
1722 		ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL))
1723 		{
1724 			TH_LOG("Failed to execute \"%s\": %s", path,
1725 			       strerror(errno));
1726 		};
1727 		ASSERT_EQ(err, errno);
1728 		_exit(_metadata->passed ? 2 : 1);
1729 		return;
1730 	}
1731 	ASSERT_EQ(child, waitpid(child, &status, 0));
1732 	ASSERT_EQ(1, WIFEXITED(status));
1733 	ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status))
1734 	{
1735 		TH_LOG("Unexpected return code for \"%s\": %s", path,
1736 		       strerror(errno));
1737 	};
1738 }
1739 
1740 TEST_F_FORK(layout1, execute)
1741 {
1742 	const struct rule rules[] = {
1743 		{
1744 			.path = dir_s1d2,
1745 			.access = LANDLOCK_ACCESS_FS_EXECUTE,
1746 		},
1747 		{},
1748 	};
1749 	const int ruleset_fd =
1750 		create_ruleset(_metadata, rules[0].access, rules);
1751 
1752 	ASSERT_LE(0, ruleset_fd);
1753 	copy_binary(_metadata, file1_s1d1);
1754 	copy_binary(_metadata, file1_s1d2);
1755 	copy_binary(_metadata, file1_s1d3);
1756 
1757 	enforce_ruleset(_metadata, ruleset_fd);
1758 	ASSERT_EQ(0, close(ruleset_fd));
1759 
1760 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
1761 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
1762 	test_execute(_metadata, EACCES, file1_s1d1);
1763 
1764 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
1765 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
1766 	test_execute(_metadata, 0, file1_s1d2);
1767 
1768 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
1769 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
1770 	test_execute(_metadata, 0, file1_s1d3);
1771 }
1772 
1773 TEST_F_FORK(layout1, link)
1774 {
1775 	const struct rule layer1[] = {
1776 		{
1777 			.path = dir_s1d2,
1778 			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
1779 		},
1780 		{},
1781 	};
1782 	const struct rule layer2[] = {
1783 		{
1784 			.path = dir_s1d3,
1785 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1786 		},
1787 		{},
1788 	};
1789 	int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
1790 
1791 	ASSERT_LE(0, ruleset_fd);
1792 
1793 	ASSERT_EQ(0, unlink(file1_s1d1));
1794 	ASSERT_EQ(0, unlink(file1_s1d2));
1795 	ASSERT_EQ(0, unlink(file1_s1d3));
1796 
1797 	enforce_ruleset(_metadata, ruleset_fd);
1798 	ASSERT_EQ(0, close(ruleset_fd));
1799 
1800 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
1801 	ASSERT_EQ(EACCES, errno);
1802 
1803 	/* Denies linking because of reparenting. */
1804 	ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
1805 	ASSERT_EQ(EXDEV, errno);
1806 	ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
1807 	ASSERT_EQ(EXDEV, errno);
1808 	ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
1809 	ASSERT_EQ(EXDEV, errno);
1810 
1811 	ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
1812 	ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
1813 
1814 	/* Prepares for next unlinks. */
1815 	ASSERT_EQ(0, unlink(file2_s1d2));
1816 	ASSERT_EQ(0, unlink(file2_s1d3));
1817 
1818 	ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
1819 	ASSERT_LE(0, ruleset_fd);
1820 	enforce_ruleset(_metadata, ruleset_fd);
1821 	ASSERT_EQ(0, close(ruleset_fd));
1822 
1823 	/* Checks that linkind doesn't require the ability to delete a file. */
1824 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
1825 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
1826 }
1827 
1828 TEST_F_FORK(layout1, rename_file)
1829 {
1830 	const struct rule rules[] = {
1831 		{
1832 			.path = dir_s1d3,
1833 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1834 		},
1835 		{
1836 			.path = dir_s2d2,
1837 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1838 		},
1839 		{},
1840 	};
1841 	const int ruleset_fd =
1842 		create_ruleset(_metadata, rules[0].access, rules);
1843 
1844 	ASSERT_LE(0, ruleset_fd);
1845 
1846 	ASSERT_EQ(0, unlink(file1_s1d2));
1847 
1848 	enforce_ruleset(_metadata, ruleset_fd);
1849 	ASSERT_EQ(0, close(ruleset_fd));
1850 
1851 	/*
1852 	 * Tries to replace a file, from a directory that allows file removal,
1853 	 * but to a different directory (which also allows file removal).
1854 	 */
1855 	ASSERT_EQ(-1, rename(file1_s2d3, file1_s1d3));
1856 	ASSERT_EQ(EXDEV, errno);
1857 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, file1_s1d3,
1858 				RENAME_EXCHANGE));
1859 	ASSERT_EQ(EXDEV, errno);
1860 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d3, AT_FDCWD, dir_s1d3,
1861 				RENAME_EXCHANGE));
1862 	ASSERT_EQ(EXDEV, errno);
1863 
1864 	/*
1865 	 * Tries to replace a file, from a directory that denies file removal,
1866 	 * to a different directory (which allows file removal).
1867 	 */
1868 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
1869 	ASSERT_EQ(EXDEV, errno);
1870 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, file1_s1d3,
1871 				RENAME_EXCHANGE));
1872 	ASSERT_EQ(EXDEV, errno);
1873 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s1d3,
1874 				RENAME_EXCHANGE));
1875 	ASSERT_EQ(EXDEV, errno);
1876 
1877 	/* Exchanges files and directories that partially allow removal. */
1878 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
1879 				RENAME_EXCHANGE));
1880 	ASSERT_EQ(EACCES, errno);
1881 	/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
1882 	ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
1883 	ASSERT_EQ(EACCES, errno);
1884 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
1885 				RENAME_EXCHANGE));
1886 	ASSERT_EQ(EACCES, errno);
1887 	/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
1888 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1889 	ASSERT_EQ(EACCES, errno);
1890 
1891 	/* Renames files with different parents. */
1892 	ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
1893 	ASSERT_EQ(EXDEV, errno);
1894 	ASSERT_EQ(0, unlink(file1_s1d3));
1895 	ASSERT_EQ(-1, rename(file1_s2d1, file1_s1d3));
1896 	ASSERT_EQ(EXDEV, errno);
1897 
1898 	/* Exchanges and renames files with same parent. */
1899 	ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3,
1900 			       RENAME_EXCHANGE));
1901 	ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3));
1902 
1903 	/* Exchanges files and directories with same parent, twice. */
1904 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
1905 			       RENAME_EXCHANGE));
1906 	ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3,
1907 			       RENAME_EXCHANGE));
1908 }
1909 
1910 TEST_F_FORK(layout1, rename_dir)
1911 {
1912 	const struct rule rules[] = {
1913 		{
1914 			.path = dir_s1d2,
1915 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1916 		},
1917 		{
1918 			.path = dir_s2d1,
1919 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1920 		},
1921 		{},
1922 	};
1923 	const int ruleset_fd =
1924 		create_ruleset(_metadata, rules[0].access, rules);
1925 
1926 	ASSERT_LE(0, ruleset_fd);
1927 
1928 	/* Empties dir_s1d3 to allow renaming. */
1929 	ASSERT_EQ(0, unlink(file1_s1d3));
1930 	ASSERT_EQ(0, unlink(file2_s1d3));
1931 
1932 	enforce_ruleset(_metadata, ruleset_fd);
1933 	ASSERT_EQ(0, close(ruleset_fd));
1934 
1935 	/* Exchanges and renames directory to a different parent. */
1936 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d3, AT_FDCWD, dir_s1d3,
1937 				RENAME_EXCHANGE));
1938 	ASSERT_EQ(EXDEV, errno);
1939 	ASSERT_EQ(-1, rename(dir_s2d3, dir_s1d3));
1940 	ASSERT_EQ(EXDEV, errno);
1941 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s1d3,
1942 				RENAME_EXCHANGE));
1943 	ASSERT_EQ(EXDEV, errno);
1944 
1945 	/*
1946 	 * Exchanges directory to the same parent, which doesn't allow
1947 	 * directory removal.
1948 	 */
1949 	ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
1950 				RENAME_EXCHANGE));
1951 	ASSERT_EQ(EACCES, errno);
1952 	/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
1953 	ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
1954 	ASSERT_EQ(EACCES, errno);
1955 	ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
1956 				RENAME_EXCHANGE));
1957 	ASSERT_EQ(EACCES, errno);
1958 	/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
1959 	ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1960 	ASSERT_EQ(EACCES, errno);
1961 
1962 	/*
1963 	 * Exchanges and renames directory to the same parent, which allows
1964 	 * directory removal.
1965 	 */
1966 	ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2,
1967 			       RENAME_EXCHANGE));
1968 	ASSERT_EQ(0, unlink(dir_s1d3));
1969 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
1970 	ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3));
1971 	ASSERT_EQ(0, rmdir(dir_s1d3));
1972 }
1973 
1974 TEST_F_FORK(layout1, remove_dir)
1975 {
1976 	const struct rule rules[] = {
1977 		{
1978 			.path = dir_s1d2,
1979 			.access = LANDLOCK_ACCESS_FS_REMOVE_DIR,
1980 		},
1981 		{},
1982 	};
1983 	const int ruleset_fd =
1984 		create_ruleset(_metadata, rules[0].access, rules);
1985 
1986 	ASSERT_LE(0, ruleset_fd);
1987 
1988 	ASSERT_EQ(0, unlink(file1_s1d1));
1989 	ASSERT_EQ(0, unlink(file1_s1d2));
1990 	ASSERT_EQ(0, unlink(file1_s1d3));
1991 	ASSERT_EQ(0, unlink(file2_s1d3));
1992 
1993 	enforce_ruleset(_metadata, ruleset_fd);
1994 	ASSERT_EQ(0, close(ruleset_fd));
1995 
1996 	ASSERT_EQ(0, rmdir(dir_s1d3));
1997 	ASSERT_EQ(0, mkdir(dir_s1d3, 0700));
1998 	ASSERT_EQ(0, unlinkat(AT_FDCWD, dir_s1d3, AT_REMOVEDIR));
1999 
2000 	/* dir_s1d2 itself cannot be removed. */
2001 	ASSERT_EQ(-1, rmdir(dir_s1d2));
2002 	ASSERT_EQ(EACCES, errno);
2003 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d2, AT_REMOVEDIR));
2004 	ASSERT_EQ(EACCES, errno);
2005 	ASSERT_EQ(-1, rmdir(dir_s1d1));
2006 	ASSERT_EQ(EACCES, errno);
2007 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, dir_s1d1, AT_REMOVEDIR));
2008 	ASSERT_EQ(EACCES, errno);
2009 }
2010 
2011 TEST_F_FORK(layout1, remove_file)
2012 {
2013 	const struct rule rules[] = {
2014 		{
2015 			.path = dir_s1d2,
2016 			.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
2017 		},
2018 		{},
2019 	};
2020 	const int ruleset_fd =
2021 		create_ruleset(_metadata, rules[0].access, rules);
2022 
2023 	ASSERT_LE(0, ruleset_fd);
2024 	enforce_ruleset(_metadata, ruleset_fd);
2025 	ASSERT_EQ(0, close(ruleset_fd));
2026 
2027 	ASSERT_EQ(-1, unlink(file1_s1d1));
2028 	ASSERT_EQ(EACCES, errno);
2029 	ASSERT_EQ(-1, unlinkat(AT_FDCWD, file1_s1d1, 0));
2030 	ASSERT_EQ(EACCES, errno);
2031 	ASSERT_EQ(0, unlink(file1_s1d2));
2032 	ASSERT_EQ(0, unlinkat(AT_FDCWD, file1_s1d3, 0));
2033 }
2034 
2035 static void test_make_file(struct __test_metadata *const _metadata,
2036 			   const __u64 access, const mode_t mode,
2037 			   const dev_t dev)
2038 {
2039 	const struct rule rules[] = {
2040 		{
2041 			.path = dir_s1d2,
2042 			.access = access,
2043 		},
2044 		{},
2045 	};
2046 	const int ruleset_fd = create_ruleset(_metadata, access, rules);
2047 
2048 	ASSERT_LE(0, ruleset_fd);
2049 
2050 	ASSERT_EQ(0, unlink(file1_s1d1));
2051 	ASSERT_EQ(0, unlink(file2_s1d1));
2052 	ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev))
2053 	{
2054 		TH_LOG("Failed to make file \"%s\": %s", file2_s1d1,
2055 		       strerror(errno));
2056 	};
2057 
2058 	ASSERT_EQ(0, unlink(file1_s1d2));
2059 	ASSERT_EQ(0, unlink(file2_s1d2));
2060 
2061 	ASSERT_EQ(0, unlink(file1_s1d3));
2062 	ASSERT_EQ(0, unlink(file2_s1d3));
2063 
2064 	enforce_ruleset(_metadata, ruleset_fd);
2065 	ASSERT_EQ(0, close(ruleset_fd));
2066 
2067 	ASSERT_EQ(-1, mknod(file1_s1d1, mode | 0400, dev));
2068 	ASSERT_EQ(EACCES, errno);
2069 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2070 	ASSERT_EQ(EACCES, errno);
2071 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
2072 	ASSERT_EQ(EACCES, errno);
2073 
2074 	ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev))
2075 	{
2076 		TH_LOG("Failed to make file \"%s\": %s", file1_s1d2,
2077 		       strerror(errno));
2078 	};
2079 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
2080 	ASSERT_EQ(0, unlink(file2_s1d2));
2081 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
2082 
2083 	ASSERT_EQ(0, mknod(file1_s1d3, mode | 0400, dev));
2084 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
2085 	ASSERT_EQ(0, unlink(file2_s1d3));
2086 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
2087 }
2088 
2089 TEST_F_FORK(layout1, make_char)
2090 {
2091 	/* Creates a /dev/null device. */
2092 	set_cap(_metadata, CAP_MKNOD);
2093 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR,
2094 		       makedev(1, 3));
2095 }
2096 
2097 TEST_F_FORK(layout1, make_block)
2098 {
2099 	/* Creates a /dev/loop0 device. */
2100 	set_cap(_metadata, CAP_MKNOD);
2101 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK,
2102 		       makedev(7, 0));
2103 }
2104 
2105 TEST_F_FORK(layout1, make_reg_1)
2106 {
2107 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFREG, 0);
2108 }
2109 
2110 TEST_F_FORK(layout1, make_reg_2)
2111 {
2112 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, 0, 0);
2113 }
2114 
2115 TEST_F_FORK(layout1, make_sock)
2116 {
2117 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_SOCK, S_IFSOCK, 0);
2118 }
2119 
2120 TEST_F_FORK(layout1, make_fifo)
2121 {
2122 	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_FIFO, S_IFIFO, 0);
2123 }
2124 
2125 TEST_F_FORK(layout1, make_sym)
2126 {
2127 	const struct rule rules[] = {
2128 		{
2129 			.path = dir_s1d2,
2130 			.access = LANDLOCK_ACCESS_FS_MAKE_SYM,
2131 		},
2132 		{},
2133 	};
2134 	const int ruleset_fd =
2135 		create_ruleset(_metadata, rules[0].access, rules);
2136 
2137 	ASSERT_LE(0, ruleset_fd);
2138 
2139 	ASSERT_EQ(0, unlink(file1_s1d1));
2140 	ASSERT_EQ(0, unlink(file2_s1d1));
2141 	ASSERT_EQ(0, symlink("none", file2_s1d1));
2142 
2143 	ASSERT_EQ(0, unlink(file1_s1d2));
2144 	ASSERT_EQ(0, unlink(file2_s1d2));
2145 
2146 	ASSERT_EQ(0, unlink(file1_s1d3));
2147 	ASSERT_EQ(0, unlink(file2_s1d3));
2148 
2149 	enforce_ruleset(_metadata, ruleset_fd);
2150 	ASSERT_EQ(0, close(ruleset_fd));
2151 
2152 	ASSERT_EQ(-1, symlink("none", file1_s1d1));
2153 	ASSERT_EQ(EACCES, errno);
2154 	ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
2155 	ASSERT_EQ(EACCES, errno);
2156 	ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1));
2157 	ASSERT_EQ(EACCES, errno);
2158 
2159 	ASSERT_EQ(0, symlink("none", file1_s1d2));
2160 	ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
2161 	ASSERT_EQ(0, unlink(file2_s1d2));
2162 	ASSERT_EQ(0, rename(file1_s1d2, file2_s1d2));
2163 
2164 	ASSERT_EQ(0, symlink("none", file1_s1d3));
2165 	ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
2166 	ASSERT_EQ(0, unlink(file2_s1d3));
2167 	ASSERT_EQ(0, rename(file1_s1d3, file2_s1d3));
2168 }
2169 
2170 TEST_F_FORK(layout1, make_dir)
2171 {
2172 	const struct rule rules[] = {
2173 		{
2174 			.path = dir_s1d2,
2175 			.access = LANDLOCK_ACCESS_FS_MAKE_DIR,
2176 		},
2177 		{},
2178 	};
2179 	const int ruleset_fd =
2180 		create_ruleset(_metadata, rules[0].access, rules);
2181 
2182 	ASSERT_LE(0, ruleset_fd);
2183 
2184 	ASSERT_EQ(0, unlink(file1_s1d1));
2185 	ASSERT_EQ(0, unlink(file1_s1d2));
2186 	ASSERT_EQ(0, unlink(file1_s1d3));
2187 
2188 	enforce_ruleset(_metadata, ruleset_fd);
2189 	ASSERT_EQ(0, close(ruleset_fd));
2190 
2191 	/* Uses file_* as directory names. */
2192 	ASSERT_EQ(-1, mkdir(file1_s1d1, 0700));
2193 	ASSERT_EQ(EACCES, errno);
2194 	ASSERT_EQ(0, mkdir(file1_s1d2, 0700));
2195 	ASSERT_EQ(0, mkdir(file1_s1d3, 0700));
2196 }
2197 
2198 static int open_proc_fd(struct __test_metadata *const _metadata, const int fd,
2199 			const int open_flags)
2200 {
2201 	static const char path_template[] = "/proc/self/fd/%d";
2202 	char procfd_path[sizeof(path_template) + 10];
2203 	const int procfd_path_size =
2204 		snprintf(procfd_path, sizeof(procfd_path), path_template, fd);
2205 
2206 	ASSERT_LT(procfd_path_size, sizeof(procfd_path));
2207 	return open(procfd_path, open_flags);
2208 }
2209 
2210 TEST_F_FORK(layout1, proc_unlinked_file)
2211 {
2212 	const struct rule rules[] = {
2213 		{
2214 			.path = file1_s1d2,
2215 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2216 		},
2217 		{},
2218 	};
2219 	int reg_fd, proc_fd;
2220 	const int ruleset_fd = create_ruleset(
2221 		_metadata,
2222 		LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE,
2223 		rules);
2224 
2225 	ASSERT_LE(0, ruleset_fd);
2226 	enforce_ruleset(_metadata, ruleset_fd);
2227 	ASSERT_EQ(0, close(ruleset_fd));
2228 
2229 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR));
2230 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2231 	reg_fd = open(file1_s1d2, O_RDONLY | O_CLOEXEC);
2232 	ASSERT_LE(0, reg_fd);
2233 	ASSERT_EQ(0, unlink(file1_s1d2));
2234 
2235 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDONLY | O_CLOEXEC);
2236 	ASSERT_LE(0, proc_fd);
2237 	ASSERT_EQ(0, close(proc_fd));
2238 
2239 	proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC);
2240 	ASSERT_EQ(-1, proc_fd)
2241 	{
2242 		TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd,
2243 		       strerror(errno));
2244 	}
2245 	ASSERT_EQ(EACCES, errno);
2246 
2247 	ASSERT_EQ(0, close(reg_fd));
2248 }
2249 
2250 TEST_F_FORK(layout1, proc_pipe)
2251 {
2252 	int proc_fd;
2253 	int pipe_fds[2];
2254 	char buf = '\0';
2255 	const struct rule rules[] = {
2256 		{
2257 			.path = dir_s1d2,
2258 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2259 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2260 		},
2261 		{},
2262 	};
2263 	/* Limits read and write access to files tied to the filesystem. */
2264 	const int ruleset_fd =
2265 		create_ruleset(_metadata, rules[0].access, rules);
2266 
2267 	ASSERT_LE(0, ruleset_fd);
2268 	enforce_ruleset(_metadata, ruleset_fd);
2269 	ASSERT_EQ(0, close(ruleset_fd));
2270 
2271 	/* Checks enforcement for normal files. */
2272 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDWR));
2273 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR));
2274 
2275 	/* Checks access to pipes through FD. */
2276 	ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC));
2277 	ASSERT_EQ(1, write(pipe_fds[1], ".", 1))
2278 	{
2279 		TH_LOG("Failed to write in pipe: %s", strerror(errno));
2280 	}
2281 	ASSERT_EQ(1, read(pipe_fds[0], &buf, 1));
2282 	ASSERT_EQ('.', buf);
2283 
2284 	/* Checks write access to pipe through /proc/self/fd . */
2285 	proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC);
2286 	ASSERT_LE(0, proc_fd);
2287 	ASSERT_EQ(1, write(proc_fd, ".", 1))
2288 	{
2289 		TH_LOG("Failed to write through /proc/self/fd/%d: %s",
2290 		       pipe_fds[1], strerror(errno));
2291 	}
2292 	ASSERT_EQ(0, close(proc_fd));
2293 
2294 	/* Checks read access to pipe through /proc/self/fd . */
2295 	proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC);
2296 	ASSERT_LE(0, proc_fd);
2297 	buf = '\0';
2298 	ASSERT_EQ(1, read(proc_fd, &buf, 1))
2299 	{
2300 		TH_LOG("Failed to read through /proc/self/fd/%d: %s",
2301 		       pipe_fds[1], strerror(errno));
2302 	}
2303 	ASSERT_EQ(0, close(proc_fd));
2304 
2305 	ASSERT_EQ(0, close(pipe_fds[0]));
2306 	ASSERT_EQ(0, close(pipe_fds[1]));
2307 }
2308 
2309 /* clang-format off */
2310 FIXTURE(layout1_bind) {};
2311 /* clang-format on */
2312 
2313 FIXTURE_SETUP(layout1_bind)
2314 {
2315 	prepare_layout(_metadata);
2316 
2317 	create_layout1(_metadata);
2318 
2319 	set_cap(_metadata, CAP_SYS_ADMIN);
2320 	ASSERT_EQ(0, mount(dir_s1d2, dir_s2d2, NULL, MS_BIND, NULL));
2321 	clear_cap(_metadata, CAP_SYS_ADMIN);
2322 }
2323 
2324 FIXTURE_TEARDOWN(layout1_bind)
2325 {
2326 	set_cap(_metadata, CAP_SYS_ADMIN);
2327 	EXPECT_EQ(0, umount(dir_s2d2));
2328 	clear_cap(_metadata, CAP_SYS_ADMIN);
2329 
2330 	remove_layout1(_metadata);
2331 
2332 	cleanup_layout(_metadata);
2333 }
2334 
2335 static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
2336 static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
2337 
2338 /*
2339  * layout1_bind hierarchy:
2340  *
2341  * tmp
2342  * ├── s1d1
2343  * │   ├── f1
2344  * │   ├── f2
2345  * │   └── s1d2
2346  * │       ├── f1
2347  * │       ├── f2
2348  * │       └── s1d3
2349  * │           ├── f1
2350  * │           └── f2
2351  * ├── s2d1
2352  * │   ├── f1
2353  * │   └── s2d2
2354  * │       ├── f1
2355  * │       ├── f2
2356  * │       └── s1d3
2357  * │           ├── f1
2358  * │           └── f2
2359  * └── s3d1
2360  *     └── s3d2
2361  *         └── s3d3
2362  */
2363 
2364 TEST_F_FORK(layout1_bind, no_restriction)
2365 {
2366 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY));
2367 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2368 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
2369 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2370 	ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
2371 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2372 
2373 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY));
2374 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDONLY));
2375 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY));
2376 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
2377 	ASSERT_EQ(ENOENT, test_open(dir_s2d3, O_RDONLY));
2378 	ASSERT_EQ(ENOENT, test_open(file1_s2d3, O_RDONLY));
2379 
2380 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY));
2381 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
2382 
2383 	ASSERT_EQ(0, test_open(dir_s3d1, O_RDONLY));
2384 }
2385 
2386 TEST_F_FORK(layout1_bind, same_content_same_file)
2387 {
2388 	/*
2389 	 * Sets access right on parent directories of both source and
2390 	 * destination mount points.
2391 	 */
2392 	const struct rule layer1_parent[] = {
2393 		{
2394 			.path = dir_s1d1,
2395 			.access = ACCESS_RO,
2396 		},
2397 		{
2398 			.path = dir_s2d1,
2399 			.access = ACCESS_RW,
2400 		},
2401 		{},
2402 	};
2403 	/*
2404 	 * Sets access rights on the same bind-mounted directories.  The result
2405 	 * should be ACCESS_RW for both directories, but not both hierarchies
2406 	 * because of the first layer.
2407 	 */
2408 	const struct rule layer2_mount_point[] = {
2409 		{
2410 			.path = dir_s1d2,
2411 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2412 		},
2413 		{
2414 			.path = dir_s2d2,
2415 			.access = ACCESS_RW,
2416 		},
2417 		{},
2418 	};
2419 	/* Only allow read-access to the s1d3 hierarchies. */
2420 	const struct rule layer3_source[] = {
2421 		{
2422 			.path = dir_s1d3,
2423 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2424 		},
2425 		{},
2426 	};
2427 	/* Removes all access rights. */
2428 	const struct rule layer4_destination[] = {
2429 		{
2430 			.path = bind_file1_s1d3,
2431 			.access = LANDLOCK_ACCESS_FS_WRITE_FILE,
2432 		},
2433 		{},
2434 	};
2435 	int ruleset_fd;
2436 
2437 	/* Sets rules for the parent directories. */
2438 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_parent);
2439 	ASSERT_LE(0, ruleset_fd);
2440 	enforce_ruleset(_metadata, ruleset_fd);
2441 	ASSERT_EQ(0, close(ruleset_fd));
2442 
2443 	/* Checks source hierarchy. */
2444 	ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY));
2445 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
2446 	ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
2447 
2448 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2449 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2450 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2451 
2452 	/* Checks destination hierarchy. */
2453 	ASSERT_EQ(0, test_open(file1_s2d1, O_RDWR));
2454 	ASSERT_EQ(0, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
2455 
2456 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
2457 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2458 
2459 	/* Sets rules for the mount points. */
2460 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_mount_point);
2461 	ASSERT_LE(0, ruleset_fd);
2462 	enforce_ruleset(_metadata, ruleset_fd);
2463 	ASSERT_EQ(0, close(ruleset_fd));
2464 
2465 	/* Checks source hierarchy. */
2466 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
2467 	ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY));
2468 	ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY));
2469 
2470 	ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
2471 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2472 	ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2473 
2474 	/* Checks destination hierarchy. */
2475 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_RDONLY));
2476 	ASSERT_EQ(EACCES, test_open(file1_s2d1, O_WRONLY));
2477 	ASSERT_EQ(EACCES, test_open(dir_s2d1, O_RDONLY | O_DIRECTORY));
2478 
2479 	ASSERT_EQ(0, test_open(file1_s2d2, O_RDWR));
2480 	ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2481 	ASSERT_EQ(0, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
2482 
2483 	/* Sets a (shared) rule only on the source. */
2484 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_source);
2485 	ASSERT_LE(0, ruleset_fd);
2486 	enforce_ruleset(_metadata, ruleset_fd);
2487 	ASSERT_EQ(0, close(ruleset_fd));
2488 
2489 	/* Checks source hierarchy. */
2490 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY));
2491 	ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY));
2492 	ASSERT_EQ(EACCES, test_open(dir_s1d2, O_RDONLY | O_DIRECTORY));
2493 
2494 	ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
2495 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
2496 	ASSERT_EQ(EACCES, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY));
2497 
2498 	/* Checks destination hierarchy. */
2499 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_RDONLY));
2500 	ASSERT_EQ(EACCES, test_open(file1_s2d2, O_WRONLY));
2501 	ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY | O_DIRECTORY));
2502 
2503 	ASSERT_EQ(0, test_open(bind_file1_s1d3, O_RDONLY));
2504 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
2505 	ASSERT_EQ(EACCES, test_open(bind_dir_s1d3, O_RDONLY | O_DIRECTORY));
2506 
2507 	/* Sets a (shared) rule only on the destination. */
2508 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_destination);
2509 	ASSERT_LE(0, ruleset_fd);
2510 	enforce_ruleset(_metadata, ruleset_fd);
2511 	ASSERT_EQ(0, close(ruleset_fd));
2512 
2513 	/* Checks source hierarchy. */
2514 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY));
2515 	ASSERT_EQ(EACCES, test_open(file1_s1d3, O_WRONLY));
2516 
2517 	/* Checks destination hierarchy. */
2518 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_RDONLY));
2519 	ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY));
2520 }
2521 
2522 #define LOWER_BASE TMP_DIR "/lower"
2523 #define LOWER_DATA LOWER_BASE "/data"
2524 static const char lower_fl1[] = LOWER_DATA "/fl1";
2525 static const char lower_dl1[] = LOWER_DATA "/dl1";
2526 static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2";
2527 static const char lower_fo1[] = LOWER_DATA "/fo1";
2528 static const char lower_do1[] = LOWER_DATA "/do1";
2529 static const char lower_do1_fo2[] = LOWER_DATA "/do1/fo2";
2530 static const char lower_do1_fl3[] = LOWER_DATA "/do1/fl3";
2531 
2532 static const char (*lower_base_files[])[] = {
2533 	&lower_fl1,
2534 	&lower_fo1,
2535 	NULL,
2536 };
2537 static const char (*lower_base_directories[])[] = {
2538 	&lower_dl1,
2539 	&lower_do1,
2540 	NULL,
2541 };
2542 static const char (*lower_sub_files[])[] = {
2543 	&lower_dl1_fl2,
2544 	&lower_do1_fo2,
2545 	&lower_do1_fl3,
2546 	NULL,
2547 };
2548 
2549 #define UPPER_BASE TMP_DIR "/upper"
2550 #define UPPER_DATA UPPER_BASE "/data"
2551 #define UPPER_WORK UPPER_BASE "/work"
2552 static const char upper_fu1[] = UPPER_DATA "/fu1";
2553 static const char upper_du1[] = UPPER_DATA "/du1";
2554 static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2";
2555 static const char upper_fo1[] = UPPER_DATA "/fo1";
2556 static const char upper_do1[] = UPPER_DATA "/do1";
2557 static const char upper_do1_fo2[] = UPPER_DATA "/do1/fo2";
2558 static const char upper_do1_fu3[] = UPPER_DATA "/do1/fu3";
2559 
2560 static const char (*upper_base_files[])[] = {
2561 	&upper_fu1,
2562 	&upper_fo1,
2563 	NULL,
2564 };
2565 static const char (*upper_base_directories[])[] = {
2566 	&upper_du1,
2567 	&upper_do1,
2568 	NULL,
2569 };
2570 static const char (*upper_sub_files[])[] = {
2571 	&upper_du1_fu2,
2572 	&upper_do1_fo2,
2573 	&upper_do1_fu3,
2574 	NULL,
2575 };
2576 
2577 #define MERGE_BASE TMP_DIR "/merge"
2578 #define MERGE_DATA MERGE_BASE "/data"
2579 static const char merge_fl1[] = MERGE_DATA "/fl1";
2580 static const char merge_dl1[] = MERGE_DATA "/dl1";
2581 static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2";
2582 static const char merge_fu1[] = MERGE_DATA "/fu1";
2583 static const char merge_du1[] = MERGE_DATA "/du1";
2584 static const char merge_du1_fu2[] = MERGE_DATA "/du1/fu2";
2585 static const char merge_fo1[] = MERGE_DATA "/fo1";
2586 static const char merge_do1[] = MERGE_DATA "/do1";
2587 static const char merge_do1_fo2[] = MERGE_DATA "/do1/fo2";
2588 static const char merge_do1_fl3[] = MERGE_DATA "/do1/fl3";
2589 static const char merge_do1_fu3[] = MERGE_DATA "/do1/fu3";
2590 
2591 static const char (*merge_base_files[])[] = {
2592 	&merge_fl1,
2593 	&merge_fu1,
2594 	&merge_fo1,
2595 	NULL,
2596 };
2597 static const char (*merge_base_directories[])[] = {
2598 	&merge_dl1,
2599 	&merge_du1,
2600 	&merge_do1,
2601 	NULL,
2602 };
2603 static const char (*merge_sub_files[])[] = {
2604 	&merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2,
2605 	&merge_do1_fl3, &merge_do1_fu3, NULL,
2606 };
2607 
2608 /*
2609  * layout2_overlay hierarchy:
2610  *
2611  * tmp
2612  * ├── lower
2613  * │   └── data
2614  * │       ├── dl1
2615  * │       │   └── fl2
2616  * │       ├── do1
2617  * │       │   ├── fl3
2618  * │       │   └── fo2
2619  * │       ├── fl1
2620  * │       └── fo1
2621  * ├── merge
2622  * │   └── data
2623  * │       ├── dl1
2624  * │       │   └── fl2
2625  * │       ├── do1
2626  * │       │   ├── fl3
2627  * │       │   ├── fo2
2628  * │       │   └── fu3
2629  * │       ├── du1
2630  * │       │   └── fu2
2631  * │       ├── fl1
2632  * │       ├── fo1
2633  * │       └── fu1
2634  * └── upper
2635  *     ├── data
2636  *     │   ├── do1
2637  *     │   │   ├── fo2
2638  *     │   │   └── fu3
2639  *     │   ├── du1
2640  *     │   │   └── fu2
2641  *     │   ├── fo1
2642  *     │   └── fu1
2643  *     └── work
2644  *         └── work
2645  */
2646 
2647 /* clang-format off */
2648 FIXTURE(layout2_overlay) {};
2649 /* clang-format on */
2650 
2651 FIXTURE_SETUP(layout2_overlay)
2652 {
2653 	prepare_layout(_metadata);
2654 
2655 	create_directory(_metadata, LOWER_BASE);
2656 	set_cap(_metadata, CAP_SYS_ADMIN);
2657 	/* Creates tmpfs mount points to get deterministic overlayfs. */
2658 	ASSERT_EQ(0, mount("tmp", LOWER_BASE, "tmpfs", 0, "size=4m,mode=700"));
2659 	clear_cap(_metadata, CAP_SYS_ADMIN);
2660 	create_file(_metadata, lower_fl1);
2661 	create_file(_metadata, lower_dl1_fl2);
2662 	create_file(_metadata, lower_fo1);
2663 	create_file(_metadata, lower_do1_fo2);
2664 	create_file(_metadata, lower_do1_fl3);
2665 
2666 	create_directory(_metadata, UPPER_BASE);
2667 	set_cap(_metadata, CAP_SYS_ADMIN);
2668 	ASSERT_EQ(0, mount("tmp", UPPER_BASE, "tmpfs", 0, "size=4m,mode=700"));
2669 	clear_cap(_metadata, CAP_SYS_ADMIN);
2670 	create_file(_metadata, upper_fu1);
2671 	create_file(_metadata, upper_du1_fu2);
2672 	create_file(_metadata, upper_fo1);
2673 	create_file(_metadata, upper_do1_fo2);
2674 	create_file(_metadata, upper_do1_fu3);
2675 	ASSERT_EQ(0, mkdir(UPPER_WORK, 0700));
2676 
2677 	create_directory(_metadata, MERGE_DATA);
2678 	set_cap(_metadata, CAP_SYS_ADMIN);
2679 	set_cap(_metadata, CAP_DAC_OVERRIDE);
2680 	ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0,
2681 			   "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA
2682 			   ",workdir=" UPPER_WORK));
2683 	clear_cap(_metadata, CAP_DAC_OVERRIDE);
2684 	clear_cap(_metadata, CAP_SYS_ADMIN);
2685 }
2686 
2687 FIXTURE_TEARDOWN(layout2_overlay)
2688 {
2689 	EXPECT_EQ(0, remove_path(lower_do1_fl3));
2690 	EXPECT_EQ(0, remove_path(lower_dl1_fl2));
2691 	EXPECT_EQ(0, remove_path(lower_fl1));
2692 	EXPECT_EQ(0, remove_path(lower_do1_fo2));
2693 	EXPECT_EQ(0, remove_path(lower_fo1));
2694 	set_cap(_metadata, CAP_SYS_ADMIN);
2695 	EXPECT_EQ(0, umount(LOWER_BASE));
2696 	clear_cap(_metadata, CAP_SYS_ADMIN);
2697 	EXPECT_EQ(0, remove_path(LOWER_BASE));
2698 
2699 	EXPECT_EQ(0, remove_path(upper_do1_fu3));
2700 	EXPECT_EQ(0, remove_path(upper_du1_fu2));
2701 	EXPECT_EQ(0, remove_path(upper_fu1));
2702 	EXPECT_EQ(0, remove_path(upper_do1_fo2));
2703 	EXPECT_EQ(0, remove_path(upper_fo1));
2704 	EXPECT_EQ(0, remove_path(UPPER_WORK "/work"));
2705 	set_cap(_metadata, CAP_SYS_ADMIN);
2706 	EXPECT_EQ(0, umount(UPPER_BASE));
2707 	clear_cap(_metadata, CAP_SYS_ADMIN);
2708 	EXPECT_EQ(0, remove_path(UPPER_BASE));
2709 
2710 	set_cap(_metadata, CAP_SYS_ADMIN);
2711 	EXPECT_EQ(0, umount(MERGE_DATA));
2712 	clear_cap(_metadata, CAP_SYS_ADMIN);
2713 	EXPECT_EQ(0, remove_path(MERGE_DATA));
2714 
2715 	cleanup_layout(_metadata);
2716 }
2717 
2718 TEST_F_FORK(layout2_overlay, no_restriction)
2719 {
2720 	ASSERT_EQ(0, test_open(lower_fl1, O_RDONLY));
2721 	ASSERT_EQ(0, test_open(lower_dl1, O_RDONLY));
2722 	ASSERT_EQ(0, test_open(lower_dl1_fl2, O_RDONLY));
2723 	ASSERT_EQ(0, test_open(lower_fo1, O_RDONLY));
2724 	ASSERT_EQ(0, test_open(lower_do1, O_RDONLY));
2725 	ASSERT_EQ(0, test_open(lower_do1_fo2, O_RDONLY));
2726 	ASSERT_EQ(0, test_open(lower_do1_fl3, O_RDONLY));
2727 
2728 	ASSERT_EQ(0, test_open(upper_fu1, O_RDONLY));
2729 	ASSERT_EQ(0, test_open(upper_du1, O_RDONLY));
2730 	ASSERT_EQ(0, test_open(upper_du1_fu2, O_RDONLY));
2731 	ASSERT_EQ(0, test_open(upper_fo1, O_RDONLY));
2732 	ASSERT_EQ(0, test_open(upper_do1, O_RDONLY));
2733 	ASSERT_EQ(0, test_open(upper_do1_fo2, O_RDONLY));
2734 	ASSERT_EQ(0, test_open(upper_do1_fu3, O_RDONLY));
2735 
2736 	ASSERT_EQ(0, test_open(merge_fl1, O_RDONLY));
2737 	ASSERT_EQ(0, test_open(merge_dl1, O_RDONLY));
2738 	ASSERT_EQ(0, test_open(merge_dl1_fl2, O_RDONLY));
2739 	ASSERT_EQ(0, test_open(merge_fu1, O_RDONLY));
2740 	ASSERT_EQ(0, test_open(merge_du1, O_RDONLY));
2741 	ASSERT_EQ(0, test_open(merge_du1_fu2, O_RDONLY));
2742 	ASSERT_EQ(0, test_open(merge_fo1, O_RDONLY));
2743 	ASSERT_EQ(0, test_open(merge_do1, O_RDONLY));
2744 	ASSERT_EQ(0, test_open(merge_do1_fo2, O_RDONLY));
2745 	ASSERT_EQ(0, test_open(merge_do1_fl3, O_RDONLY));
2746 	ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY));
2747 }
2748 
2749 #define for_each_path(path_list, path_entry, i)               \
2750 	for (i = 0, path_entry = *path_list[i]; path_list[i]; \
2751 	     path_entry = *path_list[++i])
2752 
2753 TEST_F_FORK(layout2_overlay, same_content_different_file)
2754 {
2755 	/* Sets access right on parent directories of both layers. */
2756 	const struct rule layer1_base[] = {
2757 		{
2758 			.path = LOWER_BASE,
2759 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2760 		},
2761 		{
2762 			.path = UPPER_BASE,
2763 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2764 		},
2765 		{
2766 			.path = MERGE_BASE,
2767 			.access = ACCESS_RW,
2768 		},
2769 		{},
2770 	};
2771 	const struct rule layer2_data[] = {
2772 		{
2773 			.path = LOWER_DATA,
2774 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2775 		},
2776 		{
2777 			.path = UPPER_DATA,
2778 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2779 		},
2780 		{
2781 			.path = MERGE_DATA,
2782 			.access = ACCESS_RW,
2783 		},
2784 		{},
2785 	};
2786 	/* Sets access right on directories inside both layers. */
2787 	const struct rule layer3_subdirs[] = {
2788 		{
2789 			.path = lower_dl1,
2790 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2791 		},
2792 		{
2793 			.path = lower_do1,
2794 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2795 		},
2796 		{
2797 			.path = upper_du1,
2798 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2799 		},
2800 		{
2801 			.path = upper_do1,
2802 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2803 		},
2804 		{
2805 			.path = merge_dl1,
2806 			.access = ACCESS_RW,
2807 		},
2808 		{
2809 			.path = merge_du1,
2810 			.access = ACCESS_RW,
2811 		},
2812 		{
2813 			.path = merge_do1,
2814 			.access = ACCESS_RW,
2815 		},
2816 		{},
2817 	};
2818 	/* Tighten access rights to the files. */
2819 	const struct rule layer4_files[] = {
2820 		{
2821 			.path = lower_dl1_fl2,
2822 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2823 		},
2824 		{
2825 			.path = lower_do1_fo2,
2826 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2827 		},
2828 		{
2829 			.path = lower_do1_fl3,
2830 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2831 		},
2832 		{
2833 			.path = upper_du1_fu2,
2834 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2835 		},
2836 		{
2837 			.path = upper_do1_fo2,
2838 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2839 		},
2840 		{
2841 			.path = upper_do1_fu3,
2842 			.access = LANDLOCK_ACCESS_FS_READ_FILE,
2843 		},
2844 		{
2845 			.path = merge_dl1_fl2,
2846 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2847 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2848 		},
2849 		{
2850 			.path = merge_du1_fu2,
2851 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2852 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2853 		},
2854 		{
2855 			.path = merge_do1_fo2,
2856 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2857 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2858 		},
2859 		{
2860 			.path = merge_do1_fl3,
2861 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2862 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2863 		},
2864 		{
2865 			.path = merge_do1_fu3,
2866 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2867 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2868 		},
2869 		{},
2870 	};
2871 	const struct rule layer5_merge_only[] = {
2872 		{
2873 			.path = MERGE_DATA,
2874 			.access = LANDLOCK_ACCESS_FS_READ_FILE |
2875 				  LANDLOCK_ACCESS_FS_WRITE_FILE,
2876 		},
2877 		{},
2878 	};
2879 	int ruleset_fd;
2880 	size_t i;
2881 	const char *path_entry;
2882 
2883 	/* Sets rules on base directories (i.e. outside overlay scope). */
2884 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1_base);
2885 	ASSERT_LE(0, ruleset_fd);
2886 	enforce_ruleset(_metadata, ruleset_fd);
2887 	ASSERT_EQ(0, close(ruleset_fd));
2888 
2889 	/* Checks lower layer. */
2890 	for_each_path(lower_base_files, path_entry, i) {
2891 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2892 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2893 	}
2894 	for_each_path(lower_base_directories, path_entry, i) {
2895 		ASSERT_EQ(EACCES,
2896 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2897 	}
2898 	for_each_path(lower_sub_files, path_entry, i) {
2899 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2900 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2901 	}
2902 	/* Checks upper layer. */
2903 	for_each_path(upper_base_files, path_entry, i) {
2904 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2905 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2906 	}
2907 	for_each_path(upper_base_directories, path_entry, i) {
2908 		ASSERT_EQ(EACCES,
2909 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2910 	}
2911 	for_each_path(upper_sub_files, path_entry, i) {
2912 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2913 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2914 	}
2915 	/*
2916 	 * Checks that access rights are independent from the lower and upper
2917 	 * layers: write access to upper files viewed through the merge point
2918 	 * is still allowed, and write access to lower file viewed (and copied)
2919 	 * through the merge point is still allowed.
2920 	 */
2921 	for_each_path(merge_base_files, path_entry, i) {
2922 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2923 	}
2924 	for_each_path(merge_base_directories, path_entry, i) {
2925 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2926 	}
2927 	for_each_path(merge_sub_files, path_entry, i) {
2928 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2929 	}
2930 
2931 	/* Sets rules on data directories (i.e. inside overlay scope). */
2932 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2_data);
2933 	ASSERT_LE(0, ruleset_fd);
2934 	enforce_ruleset(_metadata, ruleset_fd);
2935 	ASSERT_EQ(0, close(ruleset_fd));
2936 
2937 	/* Checks merge. */
2938 	for_each_path(merge_base_files, path_entry, i) {
2939 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2940 	}
2941 	for_each_path(merge_base_directories, path_entry, i) {
2942 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2943 	}
2944 	for_each_path(merge_sub_files, path_entry, i) {
2945 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2946 	}
2947 
2948 	/* Same checks with tighter rules. */
2949 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3_subdirs);
2950 	ASSERT_LE(0, ruleset_fd);
2951 	enforce_ruleset(_metadata, ruleset_fd);
2952 	ASSERT_EQ(0, close(ruleset_fd));
2953 
2954 	/* Checks changes for lower layer. */
2955 	for_each_path(lower_base_files, path_entry, i) {
2956 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2957 	}
2958 	/* Checks changes for upper layer. */
2959 	for_each_path(upper_base_files, path_entry, i) {
2960 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
2961 	}
2962 	/* Checks all merge accesses. */
2963 	for_each_path(merge_base_files, path_entry, i) {
2964 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
2965 	}
2966 	for_each_path(merge_base_directories, path_entry, i) {
2967 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY | O_DIRECTORY));
2968 	}
2969 	for_each_path(merge_sub_files, path_entry, i) {
2970 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2971 	}
2972 
2973 	/* Sets rules directly on overlayed files. */
2974 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer4_files);
2975 	ASSERT_LE(0, ruleset_fd);
2976 	enforce_ruleset(_metadata, ruleset_fd);
2977 	ASSERT_EQ(0, close(ruleset_fd));
2978 
2979 	/* Checks unchanged accesses on lower layer. */
2980 	for_each_path(lower_sub_files, path_entry, i) {
2981 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2982 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2983 	}
2984 	/* Checks unchanged accesses on upper layer. */
2985 	for_each_path(upper_sub_files, path_entry, i) {
2986 		ASSERT_EQ(0, test_open(path_entry, O_RDONLY));
2987 		ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY));
2988 	}
2989 	/* Checks all merge accesses. */
2990 	for_each_path(merge_base_files, path_entry, i) {
2991 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
2992 	}
2993 	for_each_path(merge_base_directories, path_entry, i) {
2994 		ASSERT_EQ(EACCES,
2995 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
2996 	}
2997 	for_each_path(merge_sub_files, path_entry, i) {
2998 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
2999 	}
3000 
3001 	/* Only allowes access to the merge hierarchy. */
3002 	ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer5_merge_only);
3003 	ASSERT_LE(0, ruleset_fd);
3004 	enforce_ruleset(_metadata, ruleset_fd);
3005 	ASSERT_EQ(0, close(ruleset_fd));
3006 
3007 	/* Checks new accesses on lower layer. */
3008 	for_each_path(lower_sub_files, path_entry, i) {
3009 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
3010 	}
3011 	/* Checks new accesses on upper layer. */
3012 	for_each_path(upper_sub_files, path_entry, i) {
3013 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY));
3014 	}
3015 	/* Checks all merge accesses. */
3016 	for_each_path(merge_base_files, path_entry, i) {
3017 		ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR));
3018 	}
3019 	for_each_path(merge_base_directories, path_entry, i) {
3020 		ASSERT_EQ(EACCES,
3021 			  test_open(path_entry, O_RDONLY | O_DIRECTORY));
3022 	}
3023 	for_each_path(merge_sub_files, path_entry, i) {
3024 		ASSERT_EQ(0, test_open(path_entry, O_RDWR));
3025 	}
3026 }
3027 
3028 TEST_HARNESS_MAIN
3029