diff options
Diffstat (limited to 'src/firejail/profile.c')
-rw-r--r-- | src/firejail/profile.c | 159 |
1 files changed, 158 insertions, 1 deletions
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 6ded0ca2f..d358594d9 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -319,7 +319,126 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
319 | return 0; | 319 | return 0; |
320 | } | 320 | } |
321 | 321 | ||
322 | 322 | ||
323 | // from here | ||
324 | else if (strncmp(ptr, "mac ", 4) == 0) { | ||
325 | #ifdef HAVE_NETWORK | ||
326 | if (checkcfg(CFG_NETWORK)) { | ||
327 | Bridge *br = last_bridge_configured(); | ||
328 | if (br == NULL) { | ||
329 | fprintf(stderr, "Error: no network device configured\n"); | ||
330 | exit(1); | ||
331 | } | ||
332 | |||
333 | if (mac_not_zero(br->macsandbox)) { | ||
334 | fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); | ||
335 | exit(1); | ||
336 | } | ||
337 | |||
338 | // read the address | ||
339 | if (atomac(ptr + 4, br->macsandbox)) { | ||
340 | fprintf(stderr, "Error: invalid MAC address\n"); | ||
341 | exit(1); | ||
342 | } | ||
343 | } | ||
344 | else | ||
345 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); | ||
346 | #endif | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | else if (strncmp(ptr, "mtu ", 4) == 0) { | ||
351 | #ifdef HAVE_NETWORK | ||
352 | if (checkcfg(CFG_NETWORK)) { | ||
353 | Bridge *br = last_bridge_configured(); | ||
354 | if (br == NULL) { | ||
355 | fprintf(stderr, "Error: no network device configured\n"); | ||
356 | exit(1); | ||
357 | } | ||
358 | |||
359 | if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) { | ||
360 | fprintf(stderr, "Error: invalid mtu value\n"); | ||
361 | exit(1); | ||
362 | } | ||
363 | } | ||
364 | else | ||
365 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); | ||
366 | #endif | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | else if (strncmp(ptr, "ip ", 3) == 0) { | ||
371 | #ifdef HAVE_NETWORK | ||
372 | if (checkcfg(CFG_NETWORK)) { | ||
373 | Bridge *br = last_bridge_configured(); | ||
374 | if (br == NULL) { | ||
375 | fprintf(stderr, "Error: no network device configured\n"); | ||
376 | exit(1); | ||
377 | } | ||
378 | if (br->arg_ip_none || br->ipsandbox) { | ||
379 | fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); | ||
380 | exit(1); | ||
381 | } | ||
382 | |||
383 | // configure this IP address for the last bridge defined | ||
384 | if (strcmp(ptr + 3, "none") == 0) | ||
385 | br->arg_ip_none = 1; | ||
386 | else { | ||
387 | if (atoip(ptr + 3, &br->ipsandbox)) { | ||
388 | fprintf(stderr, "Error: invalid IP address\n"); | ||
389 | exit(1); | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | else | ||
394 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); | ||
395 | #endif | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | else if (strncmp(ptr, "ip6 ", 4) == 0) { | ||
400 | #ifdef HAVE_NETWORK | ||
401 | if (checkcfg(CFG_NETWORK)) { | ||
402 | Bridge *br = last_bridge_configured(); | ||
403 | if (br == NULL) { | ||
404 | fprintf(stderr, "Error: no network device configured\n"); | ||
405 | exit(1); | ||
406 | } | ||
407 | if (br->arg_ip_none || br->ip6sandbox) { | ||
408 | fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); | ||
409 | exit(1); | ||
410 | } | ||
411 | |||
412 | // configure this IP address for the last bridge defined | ||
413 | // todo: verify ipv6 syntax | ||
414 | br->ip6sandbox = ptr + 4; | ||
415 | // if (atoip(argv[i] + 5, &br->ipsandbox)) { | ||
416 | // fprintf(stderr, "Error: invalid IP address\n"); | ||
417 | // exit(1); | ||
418 | // } | ||
419 | |||
420 | } | ||
421 | else | ||
422 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); | ||
423 | #endif | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | else if (strncmp(ptr, "defaultgw ", 10) == 0) { | ||
428 | #ifdef HAVE_NETWORK | ||
429 | if (checkcfg(CFG_NETWORK)) { | ||
430 | Bridge *br = last_bridge_configured(); | ||
431 | if (atoip(ptr + 10, &cfg.defaultgw)) { | ||
432 | fprintf(stderr, "Error: invalid IP address\n"); | ||
433 | exit(1); | ||
434 | } | ||
435 | } | ||
436 | else | ||
437 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); | ||
438 | #endif | ||
439 | return 0; | ||
440 | } | ||
441 | |||
323 | if (strncmp(ptr, "protocol ", 9) == 0) { | 442 | if (strncmp(ptr, "protocol ", 9) == 0) { |
324 | #ifdef HAVE_SECCOMP | 443 | #ifdef HAVE_SECCOMP |
325 | if (checkcfg(CFG_SECCOMP)) | 444 | if (checkcfg(CFG_SECCOMP)) |
@@ -451,6 +570,30 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
451 | return 0; | 570 | return 0; |
452 | } | 571 | } |
453 | 572 | ||
573 | // writable-etc | ||
574 | if (strcmp(ptr, "writable-etc") == 0) { | ||
575 | if (getuid() != 0) { | ||
576 | fprintf(stderr, "Error: writable-etc is available only for root user\n"); | ||
577 | exit(1); | ||
578 | } | ||
579 | if (cfg.etc_private_keep) { | ||
580 | fprintf(stderr, "Error: private-etc and writable-etc are mutually exclusive\n"); | ||
581 | exit(1); | ||
582 | } | ||
583 | arg_writable_etc = 1; | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | // writable-var | ||
588 | if (strcmp(ptr, "writable-var") == 0) { | ||
589 | if (getuid() != 0) { | ||
590 | fprintf(stderr, "Error: writable-var is available only for root user\n"); | ||
591 | exit(1); | ||
592 | } | ||
593 | arg_writable_var = 1; | ||
594 | return 0; | ||
595 | } | ||
596 | |||
454 | // private directory | 597 | // private directory |
455 | if (strncmp(ptr, "private ", 8) == 0) { | 598 | if (strncmp(ptr, "private ", 8) == 0) { |
456 | cfg.home_private = ptr + 8; | 599 | cfg.home_private = ptr + 8; |
@@ -461,6 +604,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
461 | 604 | ||
462 | // private /etc list of files and directories | 605 | // private /etc list of files and directories |
463 | if (strncmp(ptr, "private-etc ", 12) == 0) { | 606 | if (strncmp(ptr, "private-etc ", 12) == 0) { |
607 | if (arg_writable_etc) { | ||
608 | fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n"); | ||
609 | exit(1); | ||
610 | } | ||
464 | cfg.etc_private_keep = ptr + 12; | 611 | cfg.etc_private_keep = ptr + 12; |
465 | fs_check_etc_list(); | 612 | fs_check_etc_list(); |
466 | if (*cfg.etc_private_keep != '\0') | 613 | if (*cfg.etc_private_keep != '\0') |
@@ -569,6 +716,16 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
569 | return 0; | 716 | return 0; |
570 | } | 717 | } |
571 | 718 | ||
719 | // read-write | ||
720 | if (strncmp(ptr, "read-write ", 11) == 0) { | ||
721 | if (getuid() != 0) { | ||
722 | fprintf(stderr, "Error: read-write command is available only for root user\n"); | ||
723 | exit(1); | ||
724 | } | ||
725 | fs_rdwr_add(ptr + 11); | ||
726 | return 0; | ||
727 | } | ||
728 | |||
572 | // rest of filesystem | 729 | // rest of filesystem |
573 | if (strncmp(ptr, "blacklist ", 10) == 0) | 730 | if (strncmp(ptr, "blacklist ", 10) == 0) |
574 | ptr += 10; | 731 | ptr += 10; |