diff options
author | netblue30 <netblue30@yahoo.com> | 2016-11-29 21:38:09 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-11-29 21:38:09 -0500 |
commit | 84fa03cd77b0afcdee5cc6816596ab5c8a633185 (patch) | |
tree | 97b0ef919fbe2a32cbfcf61ccad86cc20ef41ce4 /src | |
parent | testing (diff) | |
download | firejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.tar.gz firejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.tar.zst firejail-84fa03cd77b0afcdee5cc6816596ab5c8a633185.zip |
private-opt and private-srv
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 8 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 34 | ||||
-rw-r--r-- | src/firejail/main.c | 20 | ||||
-rw-r--r-- | src/firejail/profile.c | 16 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 22 |
5 files changed, 83 insertions, 17 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 61de17bf8..d172efce1 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -43,6 +43,8 @@ | |||
43 | #define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" | 43 | #define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" |
44 | #define RUN_HOME_DIR "/run/firejail/mnt/home" | 44 | #define RUN_HOME_DIR "/run/firejail/mnt/home" |
45 | #define RUN_ETC_DIR "/run/firejail/mnt/etc" | 45 | #define RUN_ETC_DIR "/run/firejail/mnt/etc" |
46 | #define RUN_OPT_DIR "/run/firejail/mnt/opt" | ||
47 | #define RUN_SRV_DIR "/run/firejail/mnt/srv" | ||
46 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" | 48 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" |
47 | #define RUN_PULSE_DIR "/run/firejail/mnt/pulse" | 49 | #define RUN_PULSE_DIR "/run/firejail/mnt/pulse" |
48 | 50 | ||
@@ -200,6 +202,8 @@ typedef struct config_t { | |||
200 | char *home_private; // private home directory | 202 | char *home_private; // private home directory |
201 | char *home_private_keep; // keep list for private home directory | 203 | char *home_private_keep; // keep list for private home directory |
202 | char *etc_private_keep; // keep list for private etc directory | 204 | char *etc_private_keep; // keep list for private etc directory |
205 | char *opt_private_keep; // keep list for private opt directory | ||
206 | char *srv_private_keep; // keep list for private srv directory | ||
203 | char *bin_private_keep; // keep list for private bin directory | 207 | char *bin_private_keep; // keep list for private bin directory |
204 | char *cwd; // current working directory | 208 | char *cwd; // current working directory |
205 | char *overlay_dir; | 209 | char *overlay_dir; |
@@ -315,6 +319,8 @@ extern int arg_doubledash; // double dash | |||
315 | extern int arg_shell_none; // run the program directly without a shell | 319 | extern int arg_shell_none; // run the program directly without a shell |
316 | extern int arg_private_dev; // private dev directory | 320 | extern int arg_private_dev; // private dev directory |
317 | extern int arg_private_etc; // private etc directory | 321 | extern int arg_private_etc; // private etc directory |
322 | extern int arg_private_opt; // private opt directory | ||
323 | extern int arg_private_srv; // private srv directory | ||
318 | extern int arg_private_bin; // private bin directory | 324 | extern int arg_private_bin; // private bin directory |
319 | extern int arg_private_tmp; // private tmp directory | 325 | extern int arg_private_tmp; // private tmp directory |
320 | extern int arg_scan; // arp-scan all interfaces | 326 | extern int arg_scan; // arp-scan all interfaces |
@@ -556,7 +562,7 @@ void network_del_run_file(pid_t pid); | |||
556 | void network_set_run_file(pid_t pid); | 562 | void network_set_run_file(pid_t pid); |
557 | 563 | ||
558 | // fs_etc.c | 564 | // fs_etc.c |
559 | void fs_private_etc_list(void); | 565 | void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list); |
560 | 566 | ||
561 | // no_sandbox.c | 567 | // no_sandbox.c |
562 | int check_namespace_virt(void); | 568 | int check_namespace_virt(void); |
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 80329d5ba..9a28ac601 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c | |||
@@ -47,7 +47,7 @@ errexit: | |||
47 | exit(1); | 47 | exit(1); |
48 | } | 48 | } |
49 | 49 | ||
50 | static void duplicate(char *fname) { | 50 | static void duplicate(const char *fname, const char *private_dir, const char *private_run_dir) { |
51 | if (*fname == '~' || *fname == '/' || strstr(fname, "..")) { | 51 | if (*fname == '~' || *fname == '/' || strstr(fname, "..")) { |
52 | fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname); | 52 | fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname); |
53 | exit(1); | 53 | exit(1); |
@@ -55,40 +55,44 @@ static void duplicate(char *fname) { | |||
55 | invalid_filename(fname); | 55 | invalid_filename(fname); |
56 | 56 | ||
57 | char *src; | 57 | char *src; |
58 | if (asprintf(&src, "/etc/%s", fname) == -1) | 58 | if (asprintf(&src, "%s/%s", private_dir, fname) == -1) |
59 | errExit("asprintf"); | 59 | errExit("asprintf"); |
60 | if (check_dir_or_file(src) == 0) { | 60 | if (check_dir_or_file(src) == 0) { |
61 | if (!arg_quiet) | 61 | if (!arg_quiet) |
62 | fprintf(stderr, "Warning: skipping %s for private bin\n", fname); | 62 | fprintf(stderr, "Warning: skipping %s for private %s\n", fname, private_dir); |
63 | free(src); | 63 | free(src); |
64 | return; | 64 | return; |
65 | } | 65 | } |
66 | 66 | ||
67 | if (arg_debug) | ||
68 | printf("copying %s to private %s\n", src, private_dir); | ||
69 | |||
67 | struct stat s; | 70 | struct stat s; |
68 | if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) { | 71 | if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) { |
69 | // create the directory in RUN_ETC_DIR | 72 | // create the directory in RUN_ETC_DIR |
70 | char *dirname; | 73 | char *dirname; |
71 | if (asprintf(&dirname, "%s/%s", RUN_ETC_DIR, fname) == -1) | 74 | if (asprintf(&dirname, "%s/%s", private_run_dir, fname) == -1) |
72 | errExit("asprintf"); | 75 | errExit("asprintf"); |
73 | create_empty_dir_as_root(dirname, s.st_mode); | 76 | create_empty_dir_as_root(dirname, s.st_mode); |
74 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname); | 77 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname); |
75 | free(dirname); | 78 | free(dirname); |
76 | } | 79 | } |
77 | else | 80 | else |
78 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, RUN_ETC_DIR); | 81 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, private_run_dir); |
79 | 82 | ||
80 | fs_logger2("clone", src); | 83 | fs_logger2("clone", src); |
81 | free(src); | 84 | free(src); |
82 | } | 85 | } |
83 | 86 | ||
84 | 87 | ||
85 | void fs_private_etc_list(void) { | 88 | void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list) { |
86 | char *private_list = cfg.etc_private_keep; | 89 | assert(private_dir); |
90 | assert(private_run_dir); | ||
87 | assert(private_list); | 91 | assert(private_list); |
88 | 92 | ||
89 | // create /run/firejail/mnt/etc directory | 93 | // create /run/firejail/mnt/etc directory |
90 | mkdir_attr(RUN_ETC_DIR, 0755, 0, 0); | 94 | mkdir_attr(private_run_dir, 0755, 0, 0); |
91 | fs_logger("tmpfs /etc"); | 95 | fs_logger2("tmpfs", private_dir); |
92 | 96 | ||
93 | fs_logger_print(); // save the current log | 97 | fs_logger_print(); // save the current log |
94 | 98 | ||
@@ -97,7 +101,7 @@ void fs_private_etc_list(void) { | |||
97 | // using a new child process with root privileges | 101 | // using a new child process with root privileges |
98 | if (*private_list != '\0') { | 102 | if (*private_list != '\0') { |
99 | if (arg_debug) | 103 | if (arg_debug) |
100 | printf("Copying files in the new etc directory:\n"); | 104 | printf("Copying files in the new %s directory:\n", private_dir); |
101 | 105 | ||
102 | // copy the list of files in the new home directory | 106 | // copy the list of files in the new home directory |
103 | char *dlist = strdup(private_list); | 107 | char *dlist = strdup(private_list); |
@@ -106,18 +110,18 @@ void fs_private_etc_list(void) { | |||
106 | 110 | ||
107 | 111 | ||
108 | char *ptr = strtok(dlist, ","); | 112 | char *ptr = strtok(dlist, ","); |
109 | duplicate(ptr); | 113 | duplicate(ptr, private_dir, private_run_dir); |
110 | 114 | ||
111 | while ((ptr = strtok(NULL, ",")) != NULL) | 115 | while ((ptr = strtok(NULL, ",")) != NULL) |
112 | duplicate(ptr); | 116 | duplicate(ptr, private_dir, private_run_dir); |
113 | free(dlist); | 117 | free(dlist); |
114 | fs_logger_print(); | 118 | fs_logger_print(); |
115 | } | 119 | } |
116 | 120 | ||
117 | if (arg_debug) | 121 | if (arg_debug) |
118 | printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR); | 122 | printf("Mount-bind %s on top of %s\n", private_run_dir, private_dir); |
119 | if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) | 123 | if (mount(private_run_dir, private_dir, NULL, MS_BIND|MS_REC, NULL) < 0) |
120 | errExit("mount bind"); | 124 | errExit("mount bind"); |
121 | fs_logger("mount /etc"); | 125 | fs_logger2("mount", private_dir); |
122 | } | 126 | } |
123 | 127 | ||
diff --git a/src/firejail/main.c b/src/firejail/main.c index 0929347b7..4ccbb6a86 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -88,6 +88,8 @@ int arg_doubledash = 0; // double dash | |||
88 | int arg_shell_none = 0; // run the program directly without a shell | 88 | int arg_shell_none = 0; // run the program directly without a shell |
89 | int arg_private_dev = 0; // private dev directory | 89 | int arg_private_dev = 0; // private dev directory |
90 | int arg_private_etc = 0; // private etc directory | 90 | int arg_private_etc = 0; // private etc directory |
91 | int arg_private_opt = 0; // private opt directory | ||
92 | int arg_private_srv = 0; // private srv directory | ||
91 | int arg_private_bin = 0; // private bin directory | 93 | int arg_private_bin = 0; // private bin directory |
92 | int arg_private_tmp = 0; // private tmp directory | 94 | int arg_private_tmp = 0; // private tmp directory |
93 | int arg_scan = 0; // arp-scan all interfaces | 95 | int arg_scan = 0; // arp-scan all interfaces |
@@ -1624,6 +1626,24 @@ int main(int argc, char **argv) { | |||
1624 | } | 1626 | } |
1625 | arg_private_etc = 1; | 1627 | arg_private_etc = 1; |
1626 | } | 1628 | } |
1629 | else if (strncmp(argv[i], "--private-opt=", 14) == 0) { | ||
1630 | // extract private opt list | ||
1631 | cfg.opt_private_keep = argv[i] + 14; | ||
1632 | if (*cfg.opt_private_keep == '\0') { | ||
1633 | fprintf(stderr, "Error: invalid private-opt option\n"); | ||
1634 | exit(1); | ||
1635 | } | ||
1636 | arg_private_opt = 1; | ||
1637 | } | ||
1638 | else if (strncmp(argv[i], "--private-srv=", 14) == 0) { | ||
1639 | // extract private srv list | ||
1640 | cfg.srv_private_keep = argv[i] + 14; | ||
1641 | if (*cfg.srv_private_keep == '\0') { | ||
1642 | fprintf(stderr, "Error: invalid private-etc option\n"); | ||
1643 | exit(1); | ||
1644 | } | ||
1645 | arg_private_srv = 1; | ||
1646 | } | ||
1627 | else if (strncmp(argv[i], "--private-bin=", 14) == 0) { | 1647 | else if (strncmp(argv[i], "--private-bin=", 14) == 0) { |
1628 | // extract private bin list | 1648 | // extract private bin list |
1629 | cfg.bin_private_keep = argv[i] + 14; | 1649 | cfg.bin_private_keep = argv[i] + 14; |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 9acb1b813..2be6948f0 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -739,6 +739,22 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
739 | return 0; | 739 | return 0; |
740 | } | 740 | } |
741 | 741 | ||
742 | // private /opt list of files and directories | ||
743 | if (strncmp(ptr, "private-opt ", 12) == 0) { | ||
744 | cfg.opt_private_keep = ptr + 12; | ||
745 | arg_private_opt = 1; | ||
746 | |||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | // private /srv list of files and directories | ||
751 | if (strncmp(ptr, "private-srv ", 12) == 0) { | ||
752 | cfg.srv_private_keep = ptr + 12; | ||
753 | arg_private_srv = 1; | ||
754 | |||
755 | return 0; | ||
756 | } | ||
757 | |||
742 | // private /bin list of files | 758 | // private /bin list of files |
743 | if (strncmp(ptr, "private-bin ", 12) == 0) { | 759 | if (strncmp(ptr, "private-bin ", 12) == 0) { |
744 | cfg.bin_private_keep = ptr + 12; | 760 | cfg.bin_private_keep = ptr + 12; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 0a6777fef..68b8f554d 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -671,13 +671,33 @@ int sandbox(void* sandbox_arg) { | |||
671 | else if (arg_overlay) | 671 | else if (arg_overlay) |
672 | fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n"); | 672 | fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n"); |
673 | else { | 673 | else { |
674 | fs_private_etc_list(); | 674 | fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep); |
675 | // create /etc/ld.so.preload file again | 675 | // create /etc/ld.so.preload file again |
676 | if (arg_trace || arg_tracelog || mask_x11_abstract_socket) | 676 | if (arg_trace || arg_tracelog || mask_x11_abstract_socket) |
677 | fs_trace_preload(); | 677 | fs_trace_preload(); |
678 | } | 678 | } |
679 | } | 679 | } |
680 | 680 | ||
681 | if (arg_private_opt) { | ||
682 | if (cfg.chrootdir) | ||
683 | fprintf(stderr, "Warning: private-opt feature is disabled in chroot\n"); | ||
684 | else if (arg_overlay) | ||
685 | fprintf(stderr, "Warning: private-opt feature is disabled in overlay\n"); | ||
686 | else { | ||
687 | fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep); | ||
688 | } | ||
689 | } | ||
690 | |||
691 | if (arg_private_srv) { | ||
692 | if (cfg.chrootdir) | ||
693 | fprintf(stderr, "Warning: private-srv feature is disabled in chroot\n"); | ||
694 | else if (arg_overlay) | ||
695 | fprintf(stderr, "Warning: private-srv feature is disabled in overlay\n"); | ||
696 | else { | ||
697 | fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep); | ||
698 | } | ||
699 | } | ||
700 | |||
681 | if (arg_private_bin) { | 701 | if (arg_private_bin) { |
682 | if (cfg.chrootdir) | 702 | if (cfg.chrootdir) |
683 | fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); | 703 | fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n"); |