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