diff options
Diffstat (limited to 'src/firejail/caps.c')
-rw-r--r-- | src/firejail/caps.c | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/src/firejail/caps.c b/src/firejail/caps.c index ba811cada..6cfa36629 100644 --- a/src/firejail/caps.c +++ b/src/firejail/caps.c | |||
@@ -181,12 +181,10 @@ static int caps_find_name(const char *name) { | |||
181 | } | 181 | } |
182 | 182 | ||
183 | // return 1 if error, 0 if OK | 183 | // return 1 if error, 0 if OK |
184 | int caps_check_list(const char *clist, void (*callback)(int)) { | 184 | void caps_check_list(const char *clist, void (*callback)(int)) { |
185 | // don't allow empty lists | 185 | // don't allow empty lists |
186 | if (clist == NULL || *clist == '\0') { | 186 | if (clist == NULL || *clist == '\0') |
187 | fprintf(stderr, "Error: empty capabilities lists are not allowed\n"); | 187 | goto errexit; |
188 | return -1; | ||
189 | } | ||
190 | 188 | ||
191 | // work on a copy of the string | 189 | // work on a copy of the string |
192 | char *str = strdup(clist); | 190 | char *str = strdup(clist); |
@@ -201,11 +199,8 @@ int caps_check_list(const char *clist, void (*callback)(int)) { | |||
201 | else if (*ptr == ',') { | 199 | else if (*ptr == ',') { |
202 | *ptr = '\0'; | 200 | *ptr = '\0'; |
203 | int nr = caps_find_name(start); | 201 | int nr = caps_find_name(start); |
204 | if (nr == -1) { | 202 | if (nr == -1) |
205 | fprintf(stderr, "Error: capability %s not found\n", start); | 203 | goto errexit; |
206 | free(str); | ||
207 | return -1; | ||
208 | } | ||
209 | else if (callback != NULL) | 204 | else if (callback != NULL) |
210 | callback(nr); | 205 | callback(nr); |
211 | 206 | ||
@@ -215,17 +210,18 @@ int caps_check_list(const char *clist, void (*callback)(int)) { | |||
215 | } | 210 | } |
216 | if (*start != '\0') { | 211 | if (*start != '\0') { |
217 | int nr = caps_find_name(start); | 212 | int nr = caps_find_name(start); |
218 | if (nr == -1) { | 213 | if (nr == -1) |
219 | fprintf(stderr, "Error: capability %s not found\n", start); | 214 | goto errexit; |
220 | free(str); | ||
221 | return -1; | ||
222 | } | ||
223 | else if (callback != NULL) | 215 | else if (callback != NULL) |
224 | callback(nr); | 216 | callback(nr); |
225 | } | 217 | } |
226 | 218 | ||
227 | free(str); | 219 | free(str); |
228 | return 0; | 220 | return; |
221 | |||
222 | errexit: | ||
223 | fprintf(stderr, "Error: capability \"%s\" not found\n", start); | ||
224 | exit(1); | ||
229 | } | 225 | } |
230 | 226 | ||
231 | void caps_print(void) { | 227 | void caps_print(void) { |
@@ -256,49 +252,53 @@ void caps_print(void) { | |||
256 | // enabled by default | 252 | // enabled by default |
257 | int caps_default_filter(void) { | 253 | int caps_default_filter(void) { |
258 | // drop capabilities | 254 | // drop capabilities |
259 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_MODULE, 0, 0, 0) && arg_debug) | 255 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_MODULE, 0, 0, 0)) |
260 | fprintf(stderr, "Warning: cannot drop CAP_SYS_MODULE"); | 256 | goto errexit; |
261 | else if (arg_debug) | 257 | else if (arg_debug) |
262 | printf("Drop CAP_SYS_MODULE\n"); | 258 | printf("Drop CAP_SYS_MODULE\n"); |
263 | 259 | ||
264 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_RAWIO, 0, 0, 0) && arg_debug) | 260 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_RAWIO, 0, 0, 0)) |
265 | fprintf(stderr, "Warning: cannot drop CAP_SYS_RAWIO"); | 261 | goto errexit; |
266 | else if (arg_debug) | 262 | else if (arg_debug) |
267 | printf("Drop CAP_SYS_RAWIO\n"); | 263 | printf("Drop CAP_SYS_RAWIO\n"); |
268 | 264 | ||
269 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0) && arg_debug) | 265 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) |
270 | fprintf(stderr, "Warning: cannot drop CAP_SYS_BOOT"); | 266 | goto errexit; |
271 | else if (arg_debug) | 267 | else if (arg_debug) |
272 | printf("Drop CAP_SYS_BOOT\n"); | 268 | printf("Drop CAP_SYS_BOOT\n"); |
273 | 269 | ||
274 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_NICE, 0, 0, 0) && arg_debug) | 270 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_NICE, 0, 0, 0)) |
275 | fprintf(stderr, "Warning: cannot drop CAP_SYS_NICE"); | 271 | goto errexit; |
276 | else if (arg_debug) | 272 | else if (arg_debug) |
277 | printf("Drop CAP_SYS_NICE\n"); | 273 | printf("Drop CAP_SYS_NICE\n"); |
278 | 274 | ||
279 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_TTY_CONFIG, 0, 0, 0) && arg_debug) | 275 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_TTY_CONFIG, 0, 0, 0)) |
280 | fprintf(stderr, "Warning: cannot drop CAP_SYS_TTY_CONFIG"); | 276 | goto errexit; |
281 | else if (arg_debug) | 277 | else if (arg_debug) |
282 | printf("Drop CAP_SYS_TTY_CONFIG\n"); | 278 | printf("Drop CAP_SYS_TTY_CONFIG\n"); |
283 | 279 | ||
284 | #ifdef CAP_SYSLOG | 280 | #ifdef CAP_SYSLOG |
285 | if (prctl(PR_CAPBSET_DROP, CAP_SYSLOG, 0, 0, 0) && arg_debug) | 281 | if (prctl(PR_CAPBSET_DROP, CAP_SYSLOG, 0, 0, 0)) |
286 | fprintf(stderr, "Warning: cannot drop CAP_SYSLOG"); | 282 | goto errexit; |
287 | else if (arg_debug) | 283 | else if (arg_debug) |
288 | printf("Drop CAP_SYSLOG\n"); | 284 | printf("Drop CAP_SYSLOG\n"); |
289 | #endif | 285 | #endif |
290 | 286 | ||
291 | if (prctl(PR_CAPBSET_DROP, CAP_MKNOD, 0, 0, 0) && arg_debug) | 287 | if (prctl(PR_CAPBSET_DROP, CAP_MKNOD, 0, 0, 0)) |
292 | fprintf(stderr, "Warning: cannot drop CAP_MKNOD"); | 288 | goto errexit; |
293 | else if (arg_debug) | 289 | else if (arg_debug) |
294 | printf("Drop CAP_MKNOD\n"); | 290 | printf("Drop CAP_MKNOD\n"); |
295 | 291 | ||
296 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_ADMIN, 0, 0, 0) && arg_debug) | 292 | if (prctl(PR_CAPBSET_DROP, CAP_SYS_ADMIN, 0, 0, 0)) |
297 | fprintf(stderr, "Warning: cannot drop CAP_SYS_ADMIN"); | 293 | goto errexit; |
298 | else if (arg_debug) | 294 | else if (arg_debug) |
299 | printf("Drop CAP_SYS_ADMIN\n"); | 295 | printf("Drop CAP_SYS_ADMIN\n"); |
300 | 296 | ||
301 | return 0; | 297 | return 0; |
298 | |||
299 | errexit: | ||
300 | fprintf(stderr, "Error: cannot drop capabilities\n"); | ||
301 | exit(1); | ||
302 | } | 302 | } |
303 | 303 | ||
304 | void caps_drop_all(void) { | 304 | void caps_drop_all(void) { |
@@ -359,19 +359,14 @@ static uint64_t extract_caps(int pid) { | |||
359 | EUID_ASSERT(); | 359 | EUID_ASSERT(); |
360 | 360 | ||
361 | char *file; | 361 | char *file; |
362 | if (asprintf(&file, "/proc/%d/status", pid) == -1) { | 362 | if (asprintf(&file, "/proc/%d/status", pid) == -1) |
363 | errExit("asprintf"); | 363 | errExit("asprintf"); |
364 | exit(1); | ||
365 | } | ||
366 | 364 | ||
367 | EUID_ROOT(); // grsecurity | 365 | EUID_ROOT(); // grsecurity |
368 | FILE *fp = fopen(file, "r"); | 366 | FILE *fp = fopen(file, "r"); |
369 | EUID_USER(); // grsecurity | 367 | EUID_USER(); // grsecurity |
370 | if (!fp) { | 368 | if (!fp) |
371 | printf("Error: cannot open %s\n", file); | 369 | goto errexit; |
372 | free(file); | ||
373 | exit(1); | ||
374 | } | ||
375 | 370 | ||
376 | char buf[MAXBUF]; | 371 | char buf[MAXBUF]; |
377 | while (fgets(buf, MAXBUF, fp)) { | 372 | while (fgets(buf, MAXBUF, fp)) { |
@@ -385,6 +380,8 @@ static uint64_t extract_caps(int pid) { | |||
385 | } | 380 | } |
386 | } | 381 | } |
387 | fclose(fp); | 382 | fclose(fp); |
383 | |||
384 | errexit: | ||
388 | free(file); | 385 | free(file); |
389 | fprintf(stderr, "Error: cannot read caps configuration\n"); | 386 | fprintf(stderr, "Error: cannot read caps configuration\n"); |
390 | exit(1); | 387 | exit(1); |