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