1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
4 */
5
6 /*\
7 * [Description]
8 *
9 * This test verifies LANDLOCK_ACCESS_FS_REFER access in the
10 * landlock sandbox.
11 *
12 * [Algorithm]
13 *
14 * - apply LANDLOCK_ACCESS_FS_REFER in the folder1
15 * - apply LANDLOCK_ACCESS_FS_REFER in the folder2
16 * - create folder3
17 * - verify that file can be moved from folder1 to folder2
18 * - verify that file can't be moved from folder1 to folder3
19 */
20
21 #include "landlock_common.h"
22
23 #define MNTPOINT "sandbox"
24 #define DIR1 MNTPOINT"/folder1"
25 #define DIR2 MNTPOINT"/folder2"
26 #define DIR3 MNTPOINT"/folder3"
27 #define FILENAME1 DIR1"/file"
28 #define FILENAME2 DIR2"/file"
29 #define FILENAME3 DIR3"/file"
30
31 static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
32 static struct landlock_path_beneath_attr *path_beneath_attr;
33
run(void)34 static void run(void)
35 {
36 if (SAFE_FORK())
37 return;
38
39 TST_EXP_PASS(rename(FILENAME1, FILENAME2));
40 if (TST_RET == -1)
41 return;
42
43 TST_EXP_FAIL(rename(FILENAME2, FILENAME3), EXDEV);
44 TST_EXP_PASS(rename(FILENAME2, FILENAME1));
45
46 _exit(0);
47 }
48
setup(void)49 static void setup(void)
50 {
51 int abi;
52 int ruleset_fd;
53
54 abi = verify_landlock_is_enabled();
55 if (abi < 2)
56 tst_brk(TCONF, "LANDLOCK_ACCESS_FS_REFER is unsupported on ABI < 2");
57
58 SAFE_MKDIR(DIR1, 0640);
59 SAFE_MKDIR(DIR2, 0640);
60 SAFE_MKDIR(DIR3, 0640);
61 SAFE_TOUCH(FILENAME1, 0640, NULL);
62
63 tst_res(TINFO, "Applying LANDLOCK_ACCESS_FS_REFER");
64
65 ruleset_attr->handled_access_fs =
66 LANDLOCK_ACCESS_FS_READ_FILE |
67 LANDLOCK_ACCESS_FS_WRITE_FILE |
68 LANDLOCK_ACCESS_FS_REFER;
69
70 ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
71 ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0);
72
73 apply_landlock_fs_rule(
74 path_beneath_attr,
75 ruleset_fd,
76 LANDLOCK_ACCESS_FS_REFER,
77 DIR1);
78
79 apply_landlock_fs_rule(
80 path_beneath_attr,
81 ruleset_fd,
82 LANDLOCK_ACCESS_FS_REFER,
83 DIR2);
84
85 enforce_ruleset(ruleset_fd);
86
87 SAFE_CLOSE(ruleset_fd);
88 }
89
90 static struct tst_test test = {
91 .test_all = run,
92 .setup = setup,
93 .needs_root = 1,
94 .forks_child = 1,
95 .bufs = (struct tst_buffers []) {
96 {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
97 {&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
98 {},
99 },
100 .caps = (struct tst_cap []) {
101 TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
102 {}
103 },
104 .mount_device = 1,
105 .mntpoint = MNTPOINT,
106 .all_filesystems = 1,
107 .skip_filesystems = (const char *[]) {
108 "vfat",
109 "exfat",
110 NULL
111 },
112 };
113