diff options
-rw-r--r-- | src/firejail/firejail.h | 5 | ||||
-rw-r--r-- | src/firejail/landlock.c | 61 |
2 files changed, 35 insertions, 31 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 95b25b658..b0fdc83aa 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -967,11 +967,6 @@ void oom_set(const char *oom_string); | |||
967 | // landlock.c | 967 | // landlock.c |
968 | #ifdef HAVE_LANDLOCK | 968 | #ifdef HAVE_LANDLOCK |
969 | int ll_get_fd(void); | 969 | int ll_get_fd(void); |
970 | int ll_is_supported(void); | ||
971 | int ll_read(const char *allowed_path); | ||
972 | int ll_write(const char *allowed_path); | ||
973 | int ll_special(const char *allowed_path); | ||
974 | int ll_exec(const char *allowed_path); | ||
975 | int ll_restrict(uint32_t flags); | 970 | int ll_restrict(uint32_t flags); |
976 | void ll_add_profile(int type, const char *data); | 971 | void ll_add_profile(int type, const char *data); |
977 | #endif /* HAVE_LANDLOCK */ | 972 | #endif /* HAVE_LANDLOCK */ |
diff --git a/src/firejail/landlock.c b/src/firejail/landlock.c index a5fd55232..962c71ae8 100644 --- a/src/firejail/landlock.c +++ b/src/firejail/landlock.c | |||
@@ -60,7 +60,7 @@ landlock_restrict_self(const int ruleset_fd, const __u32 flags) { | |||
60 | } | 60 | } |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | int ll_is_supported(void) { | 63 | static int ll_is_supported(void) { |
64 | if (ll_abi != -1) | 64 | if (ll_abi != -1) |
65 | goto out; | 65 | goto out; |
66 | 66 | ||
@@ -83,9 +83,6 @@ out: | |||
83 | } | 83 | } |
84 | 84 | ||
85 | static int ll_create_full_ruleset(void) { | 85 | static int ll_create_full_ruleset(void) { |
86 | if (!ll_is_supported()) | ||
87 | return -1; | ||
88 | |||
89 | struct landlock_ruleset_attr attr; | 86 | struct landlock_ruleset_attr attr; |
90 | attr.handled_access_fs = | 87 | attr.handled_access_fs = |
91 | LANDLOCK_ACCESS_FS_EXECUTE | | 88 | LANDLOCK_ACCESS_FS_EXECUTE | |
@@ -117,11 +114,8 @@ static int ll_create_full_ruleset(void) { | |||
117 | return ruleset_fd; | 114 | return ruleset_fd; |
118 | } | 115 | } |
119 | 116 | ||
120 | static int _ll_fs(const char *allowed_path, const __u64 allowed_access, | 117 | static void _ll_fs(const char *allowed_path, const __u64 allowed_access, |
121 | const char *caller) { | 118 | const char *caller) { |
122 | if (!ll_is_supported()) | ||
123 | return 0; | ||
124 | |||
125 | if (ll_ruleset_fd == -1) | 119 | if (ll_ruleset_fd == -1) |
126 | ll_ruleset_fd = ll_create_full_ruleset(); | 120 | ll_ruleset_fd = ll_create_full_ruleset(); |
127 | 121 | ||
@@ -130,20 +124,19 @@ static int _ll_fs(const char *allowed_path, const __u64 allowed_access, | |||
130 | caller, ll_abi, allowed_access, allowed_path); | 124 | caller, ll_abi, allowed_access, allowed_path); |
131 | } | 125 | } |
132 | 126 | ||
133 | int error; | ||
134 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); | 127 | int allowed_fd = open(allowed_path, O_PATH | O_CLOEXEC); |
135 | if (allowed_fd < 0) { | 128 | if (allowed_fd < 0) { |
136 | if (arg_debug) { | 129 | if (arg_debug) { |
137 | fprintf(stderr, "%s: failed to open %s: %s\n", | 130 | fprintf(stderr, "%s: failed to open %s: %s\n", |
138 | caller, allowed_path, strerror(errno)); | 131 | caller, allowed_path, strerror(errno)); |
139 | } | 132 | } |
140 | return 0; | 133 | return; |
141 | } | 134 | } |
142 | 135 | ||
143 | struct landlock_path_beneath_attr target; | 136 | struct landlock_path_beneath_attr target; |
144 | target.parent_fd = allowed_fd; | 137 | target.parent_fd = allowed_fd; |
145 | target.allowed_access = allowed_access; | 138 | target.allowed_access = allowed_access; |
146 | error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, | 139 | int error = landlock_add_rule(ll_ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, |
147 | &target, 0); | 140 | &target, 0); |
148 | if (error) { | 141 | if (error) { |
149 | fprintf(stderr, "Error: %s: failed to add Landlock rule " | 142 | fprintf(stderr, "Error: %s: failed to add Landlock rule " |
@@ -152,28 +145,44 @@ static int _ll_fs(const char *allowed_path, const __u64 allowed_access, | |||
152 | strerror(errno)); | 145 | strerror(errno)); |
153 | } | 146 | } |
154 | close(allowed_fd); | 147 | close(allowed_fd); |
155 | return error; | ||
156 | } | 148 | } |
157 | 149 | ||
158 | // TODO: Add support for the ${PATH} macro. | 150 | static void ll_fs(const char *allowed_path, const __u64 allowed_access, |
159 | static int ll_fs(const char *allowed_path, const __u64 allowed_access, | ||
160 | const char *caller) { | 151 | const char *caller) { |
161 | char *expanded_path = expand_macros(allowed_path); | 152 | char *expanded_path; |
162 | int error = _ll_fs(expanded_path, allowed_access, caller); | 153 | |
154 | // ${PATH} macro is not included by default in expand_macros() | ||
155 | if (strncmp(allowed_path, "${PATH}", 7) == 0) { | ||
156 | char **paths = build_paths(); | ||
157 | int i = 0; | ||
158 | while (paths[i] != NULL) { | ||
159 | if (asprintf(&expanded_path, "%s%s", paths[i], allowed_path + 7) == -1) | ||
160 | errExit("asprintf"); | ||
161 | if (arg_debug) | ||
162 | fprintf(stderr, "landlock expand path %s\n", expanded_path); | ||
163 | |||
164 | _ll_fs(expanded_path, allowed_access, caller); | ||
165 | free(expanded_path); | ||
166 | i++; | ||
167 | } | ||
168 | return; | ||
169 | } | ||
170 | |||
163 | 171 | ||
172 | expanded_path = expand_macros(allowed_path); | ||
173 | _ll_fs(expanded_path, allowed_access, caller); | ||
164 | free(expanded_path); | 174 | free(expanded_path); |
165 | return error; | ||
166 | } | 175 | } |
167 | 176 | ||
168 | int ll_read(const char *allowed_path) { | 177 | static void ll_read(const char *allowed_path) { |
169 | __u64 allowed_access = | 178 | __u64 allowed_access = |
170 | LANDLOCK_ACCESS_FS_READ_DIR | | 179 | LANDLOCK_ACCESS_FS_READ_DIR | |
171 | LANDLOCK_ACCESS_FS_READ_FILE; | 180 | LANDLOCK_ACCESS_FS_READ_FILE; |
172 | 181 | ||
173 | return ll_fs(allowed_path, allowed_access, __func__); | 182 | ll_fs(allowed_path, allowed_access, __func__); |
174 | } | 183 | } |
175 | 184 | ||
176 | int ll_write(const char *allowed_path) { | 185 | static void ll_write(const char *allowed_path) { |
177 | __u64 allowed_access = | 186 | __u64 allowed_access = |
178 | LANDLOCK_ACCESS_FS_MAKE_DIR | | 187 | LANDLOCK_ACCESS_FS_MAKE_DIR | |
179 | LANDLOCK_ACCESS_FS_MAKE_REG | | 188 | LANDLOCK_ACCESS_FS_MAKE_REG | |
@@ -182,24 +191,24 @@ int ll_write(const char *allowed_path) { | |||
182 | LANDLOCK_ACCESS_FS_REMOVE_FILE | | 191 | LANDLOCK_ACCESS_FS_REMOVE_FILE | |
183 | LANDLOCK_ACCESS_FS_WRITE_FILE; | 192 | LANDLOCK_ACCESS_FS_WRITE_FILE; |
184 | 193 | ||
185 | return ll_fs(allowed_path, allowed_access, __func__); | 194 | ll_fs(allowed_path, allowed_access, __func__); |
186 | } | 195 | } |
187 | 196 | ||
188 | int ll_special(const char *allowed_path) { | 197 | static void ll_special(const char *allowed_path) { |
189 | __u64 allowed_access = | 198 | __u64 allowed_access = |
190 | LANDLOCK_ACCESS_FS_MAKE_BLOCK | | 199 | LANDLOCK_ACCESS_FS_MAKE_BLOCK | |
191 | LANDLOCK_ACCESS_FS_MAKE_CHAR | | 200 | LANDLOCK_ACCESS_FS_MAKE_CHAR | |
192 | LANDLOCK_ACCESS_FS_MAKE_FIFO | | 201 | LANDLOCK_ACCESS_FS_MAKE_FIFO | |
193 | LANDLOCK_ACCESS_FS_MAKE_SOCK; | 202 | LANDLOCK_ACCESS_FS_MAKE_SOCK; |
194 | 203 | ||
195 | return ll_fs(allowed_path, allowed_access, __func__); | 204 | ll_fs(allowed_path, allowed_access, __func__); |
196 | } | 205 | } |
197 | 206 | ||
198 | int ll_exec(const char *allowed_path) { | 207 | static void ll_exec(const char *allowed_path) { |
199 | __u64 allowed_access = | 208 | __u64 allowed_access = |
200 | LANDLOCK_ACCESS_FS_EXECUTE; | 209 | LANDLOCK_ACCESS_FS_EXECUTE; |
201 | 210 | ||
202 | return ll_fs(allowed_path, allowed_access, __func__); | 211 | ll_fs(allowed_path, allowed_access, __func__); |
203 | } | 212 | } |
204 | 213 | ||
205 | int ll_restrict(uint32_t flags) { | 214 | int ll_restrict(uint32_t flags) { |
@@ -211,7 +220,7 @@ int ll_restrict(uint32_t flags) { | |||
211 | if (arg_debug) | 220 | if (arg_debug) |
212 | fprintf(stderr, "%s: Starting Landlock restrict\n", __func__); | 221 | fprintf(stderr, "%s: Starting Landlock restrict\n", __func__); |
213 | 222 | ||
214 | int (*fnc[])(const char *) = { | 223 | void (*fnc[])(const char *) = { |
215 | ll_read, | 224 | ll_read, |
216 | ll_write, | 225 | ll_write, |
217 | ll_special, | 226 | ll_special, |