diff options
author | netblue30 <netblue30@yahoo.com> | 2017-11-08 08:30:10 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-11-08 08:30:10 -0500 |
commit | b1b1e774a175fe2ee35aa22d02c097e13873a5a9 (patch) | |
tree | 22e3fda2f21723e05a2299ef30668aa5af1119af | |
parent | Merge pull request #1637 from soredake/keepassxc (diff) | |
download | firejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.tar.gz firejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.tar.zst firejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.zip |
private-bin and private-lib fixes
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | RELNOTES | 1 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/fs_bin.c | 58 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 19 | ||||
-rw-r--r-- | src/firejail/main.c | 3 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail.txt | 3 |
8 files changed, 53 insertions, 50 deletions
@@ -100,17 +100,23 @@ Use this issue to request new profiles: [#1139](https://github.com/netblue30/fir | |||
100 | 100 | ||
101 | ## Whitelisting, globbing etc. | 101 | ## Whitelisting, globbing etc. |
102 | 102 | ||
103 | Add "include /etc/firejail/whitelist-var-common.inc" to an application profile and test it. If it's working, | 103 | We deployed a whitelist for /var directory ("include /etc/firejail/whitelist-var-common.inc"). |
104 | send a pull request. I did it so far for some more common applications like Firefox, Chromium etc. | 104 | It is currently done for 115 applications. |
105 | 105 | ||
106 | Added globbing support for --private-bin. Added whitelisting support for /etc and /usr/share. | 106 | We added globbing support for --private-bin and whitelisting support for /etc and /usr/share. |
107 | 107 | ||
108 | --private-lib was enhanced to autodetect GTK2, GTK3 and Qt4 libraries. We do a test run with this option enabled | 108 | --private-lib was enhanced to autodetect GTK2, GTK3 and Qt4 libraries. In the next release we do a test run with this option enabled |
109 | for the following applications: evince, galculator, gnome-calculator, | 109 | for the following applications: evince, galculator, gnome-calculator, |
110 | leafpad, mousepad, transmission-gtk, xcalc, xmr-stak-cpu, | 110 | leafpad, mousepad, transmission-gtk, xcalc, xmr-stak-cpu, |
111 | atril, mate-color-select, tar, file, strings, gpicview, | 111 | atril, mate-color-select, tar, file, strings, gpicview, |
112 | eom, eog, gedit, pluma | 112 | eom, eog, gedit, pluma |
113 | 113 | ||
114 | Just for fun, this is a private-bin/private-lib Firefox running on Debian 9: | ||
115 | ````` | ||
116 | $ firejail --private-bin=firefox,firefox-esr,sh,which --private-lib=firefox-esr firefox | ||
117 | ```` | ||
118 | |||
119 | |||
114 | ## Profile build tool | 120 | ## Profile build tool |
115 | ````` | 121 | ````` |
116 | $ firejail --build appname | 122 | $ firejail --build appname |
@@ -201,6 +207,9 @@ $ | |||
201 | 207 | ||
202 | $ firejail --timeout=01:30:00 firefox | 208 | $ firejail --timeout=01:30:00 firefox |
203 | 209 | ||
210 | --debug-private-lib | ||
211 | Debug messages for --private-lib option. | ||
212 | |||
204 | ````` | 213 | ````` |
205 | 214 | ||
206 | ## New profiles: | 215 | ## New profiles: |
@@ -13,6 +13,7 @@ firejail (0.9.51) baseline; urgency=low | |||
13 | * feature: systemd-resolved integration | 13 | * feature: systemd-resolved integration |
14 | * feature: whitelisting /var directory in most profiles | 14 | * feature: whitelisting /var directory in most profiles |
15 | * feature: GTK2, GTK3 and Qt4 private-lib support | 15 | * feature: GTK2, GTK3 and Qt4 private-lib support |
16 | * feature: --debug-private-lib | ||
16 | * feature: test deployment of private-lib for the following | 17 | * feature: test deployment of private-lib for the following |
17 | applications: evince, galculator, gnome-calculator, | 18 | applications: evince, galculator, gnome-calculator, |
18 | leafpad, mousepad, transmission-gtk, xcalc, xmr-stak-cpu, | 19 | leafpad, mousepad, transmission-gtk, xcalc, xmr-stak-cpu, |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index b0b7e4e77..5d6d94d16 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -310,6 +310,7 @@ extern int arg_debug; // print debug messages | |||
310 | extern int arg_debug_check_filename; // print debug messages for filename checking | 310 | extern int arg_debug_check_filename; // print debug messages for filename checking |
311 | extern int arg_debug_blacklists; // print debug messages for blacklists | 311 | extern int arg_debug_blacklists; // print debug messages for blacklists |
312 | extern int arg_debug_whitelists; // print debug messages for whitelists | 312 | extern int arg_debug_whitelists; // print debug messages for whitelists |
313 | extern int arg_debug_private_lib; // print debug messages for private-lib | ||
313 | extern int arg_nonetwork; // --net=none | 314 | extern int arg_nonetwork; // --net=none |
314 | extern int arg_command; // -c | 315 | extern int arg_command; // -c |
315 | extern int arg_overlay; // overlay option | 316 | extern int arg_overlay; // overlay option |
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c index a17c8dac0..364431077 100644 --- a/src/firejail/fs_bin.c +++ b/src/firejail/fs_bin.c | |||
@@ -99,16 +99,23 @@ static char *check_dir_or_file(const char *name) { | |||
99 | static int valid_full_path_file(const char *name) { | 99 | static int valid_full_path_file(const char *name) { |
100 | assert(name); | 100 | assert(name); |
101 | 101 | ||
102 | char *real_path = realpath(name, NULL); | 102 | if (*name != '/') |
103 | if (!real_path) | 103 | return 0; |
104 | goto errexit; | 104 | if (strstr(name, "..")) |
105 | char *fname = strrchr(real_path, '/'); | 105 | return 0; |
106 | if (!fname) | 106 | |
107 | goto errexit; | 107 | // do we have a file? |
108 | if (*(++fname) == '\0') | 108 | struct stat s; |
109 | goto errexit; | 109 | if (stat(name, &s) == -1) |
110 | 110 | return 0; | |
111 | int found = 0; | 111 | // directories not allowed |
112 | if (S_ISDIR(s.st_mode)) | ||
113 | return 0; | ||
114 | // checking access | ||
115 | if (access(name, X_OK) == -1) | ||
116 | return 0; | ||
117 | |||
118 | // check standard paths | ||
112 | int i = 0; | 119 | int i = 0; |
113 | while (paths[i]) { | 120 | while (paths[i]) { |
114 | // private-bin-no-local can be disabled in /etc/firejail/firejail.config | 121 | // private-bin-no-local can be disabled in /etc/firejail/firejail.config |
@@ -117,34 +124,13 @@ static int valid_full_path_file(const char *name) { | |||
117 | continue; | 124 | continue; |
118 | } | 125 | } |
119 | 126 | ||
120 | // check file | 127 | int len = strlen(paths[i]); |
121 | char *path; | 128 | if (strncmp(name, paths[i], len) == 0 && name[len] == '/' && name[len + 1] != '\0') |
122 | if (asprintf(&path, "%s/%s", paths[i], fname) == -1) | 129 | return 1; |
123 | errExit("asprintf"); | ||
124 | |||
125 | if (strcmp(real_path, path) == 0) { | ||
126 | free(path); | ||
127 | // checking access | ||
128 | if (access(real_path, X_OK) == 0) | ||
129 | found = 1; | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | free(path); | ||
134 | i++; | 130 | i++; |
135 | } | 131 | } |
136 | |||
137 | if (!found) | ||
138 | goto errexit; | ||
139 | |||
140 | free(real_path); | ||
141 | return 1; | ||
142 | |||
143 | errexit: | ||
144 | if (arg_debug) | 132 | if (arg_debug) |
145 | fwarning("file %s not found\n", name); | 133 | printf("file %s not found\n", name); |
146 | if (real_path) | ||
147 | free(real_path); | ||
148 | return 0; | 134 | return 0; |
149 | } | 135 | } |
150 | 136 | ||
@@ -205,6 +191,7 @@ static void duplicate(char *fname, FILE *fplist) { | |||
205 | char *actual_path = realpath(full_path, NULL); | 191 | char *actual_path = realpath(full_path, NULL); |
206 | if (actual_path) { | 192 | if (actual_path) { |
207 | if (valid_full_path_file(actual_path)) { | 193 | if (valid_full_path_file(actual_path)) { |
194 | // solving problems such as /bin/sh -> /bin/dash | ||
208 | // copy the real file pointed by symlink | 195 | // copy the real file pointed by symlink |
209 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); | 196 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); |
210 | char *f = strrchr(actual_path, '/'); | 197 | char *f = strrchr(actual_path, '/'); |
@@ -214,6 +201,7 @@ static void duplicate(char *fname, FILE *fplist) { | |||
214 | free(actual_path); | 201 | free(actual_path); |
215 | } | 202 | } |
216 | } | 203 | } |
204 | |||
217 | // copy a file or a symlink | 205 | // copy a file or a symlink |
218 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); | 206 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); |
219 | } | 207 | } |
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 59c0c5261..23fdb8a6a 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <dirent.h> | 25 | #include <dirent.h> |
26 | |||
27 | #define MAXBUF 4096 | 26 | #define MAXBUF 4096 |
28 | 27 | ||
29 | static const char * const lib_paths[] = { | 28 | static const char * const lib_paths[] = { |
@@ -69,8 +68,6 @@ static char *build_dest_dir(const char *full_path) { | |||
69 | // copy fname in private_run_dir | 68 | // copy fname in private_run_dir |
70 | void fslib_duplicate(const char *full_path) { | 69 | void fslib_duplicate(const char *full_path) { |
71 | assert(full_path); | 70 | assert(full_path); |
72 | if (arg_debug) | ||
73 | printf("fslib_duplicate %s\n", full_path); | ||
74 | 71 | ||
75 | struct stat s; | 72 | struct stat s; |
76 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK)) | 73 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK)) |
@@ -95,7 +92,7 @@ void fslib_duplicate(const char *full_path) { | |||
95 | } | 92 | } |
96 | free(name); | 93 | free(name); |
97 | 94 | ||
98 | if (arg_debug) | 95 | if (arg_debug || arg_debug_private_lib) |
99 | printf("copying %s to private %s\n", full_path, dest_dir); | 96 | printf("copying %s to private %s\n", full_path, dest_dir); |
100 | 97 | ||
101 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir); | 98 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir); |
@@ -109,13 +106,13 @@ void fslib_duplicate(const char *full_path) { | |||
109 | // lib is not copied, only libraries used by it | 106 | // lib is not copied, only libraries used by it |
110 | void fslib_copy_libs(const char *full_path) { | 107 | void fslib_copy_libs(const char *full_path) { |
111 | assert(full_path); | 108 | assert(full_path); |
112 | if (arg_debug) | 109 | if (arg_debug || arg_debug_private_lib) |
113 | printf("fslib_copy_libs %s\n", full_path); | 110 | printf("fslib_copy_libs %s\n", full_path); |
114 | 111 | ||
115 | // if library/executable does not exist or the user does not have read access to it | 112 | // if library/executable does not exist or the user does not have read access to it |
116 | // print a warning and exit the function. | 113 | // print a warning and exit the function. |
117 | if (access(full_path, R_OK)) { | 114 | if (access(full_path, R_OK)) { |
118 | if (arg_debug) | 115 | if (arg_debug || arg_debug_private_lib) |
119 | printf("cannot find %s for private-lib, skipping...\n", full_path); | 116 | printf("cannot find %s for private-lib, skipping...\n", full_path); |
120 | return; | 117 | return; |
121 | } | 118 | } |
@@ -127,7 +124,7 @@ void fslib_copy_libs(const char *full_path) { | |||
127 | errExit("chown"); | 124 | errExit("chown"); |
128 | 125 | ||
129 | // run fldd to extact the list of files | 126 | // run fldd to extact the list of files |
130 | if (arg_debug) | 127 | if (arg_debug || arg_debug_private_lib) |
131 | printf("runing fldd %s\n", full_path); | 128 | printf("runing fldd %s\n", full_path); |
132 | sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); | 129 | sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); |
133 | 130 | ||
@@ -150,7 +147,7 @@ void fslib_copy_libs(const char *full_path) { | |||
150 | 147 | ||
151 | void fslib_copy_dir(const char *full_path) { | 148 | void fslib_copy_dir(const char *full_path) { |
152 | assert(full_path); | 149 | assert(full_path); |
153 | if (arg_debug) | 150 | if (arg_debug || arg_debug_private_lib) |
154 | printf("fslib_copy_dir %s\n", full_path); | 151 | printf("fslib_copy_dir %s\n", full_path); |
155 | 152 | ||
156 | // do nothing if the directory does not exist or is not owned by root | 153 | // do nothing if the directory does not exist or is not owned by root |
@@ -216,7 +213,7 @@ static char *valid_file(const char *lib) { | |||
216 | 213 | ||
217 | 214 | ||
218 | static void mount_directories(void) { | 215 | static void mount_directories(void) { |
219 | if (arg_debug) | 216 | if (arg_debug || arg_debug_private_lib) |
220 | printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR); | 217 | printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR); |
221 | 218 | ||
222 | if (is_dir("/lib")) { | 219 | if (is_dir("/lib")) { |
@@ -262,7 +259,7 @@ void fs_private_lib(void) { | |||
262 | return; | 259 | return; |
263 | #endif | 260 | #endif |
264 | char *private_list = cfg.lib_private_keep; | 261 | char *private_list = cfg.lib_private_keep; |
265 | if (arg_debug) | 262 | if (arg_debug || arg_debug_private_lib) |
266 | printf("Starting private-lib processing: program %s, shell %s\n", | 263 | printf("Starting private-lib processing: program %s, shell %s\n", |
267 | (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none", | 264 | (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none", |
268 | (arg_shell_none)? "none": cfg.shell); | 265 | (arg_shell_none)? "none": cfg.shell); |
@@ -288,7 +285,7 @@ void fs_private_lib(void) { | |||
288 | 285 | ||
289 | // for the listed libs | 286 | // for the listed libs |
290 | if (private_list && *private_list != '\0') { | 287 | if (private_list && *private_list != '\0') { |
291 | if (arg_debug) | 288 | if (arg_debug || arg_debug_private_lib) |
292 | printf("Copying extra files (%s) in the new lib directory\n", private_list); | 289 | printf("Copying extra files (%s) in the new lib directory\n", private_list); |
293 | 290 | ||
294 | char *dlist = strdup(private_list); | 291 | char *dlist = strdup(private_list); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 7730e8384..c8b347b5f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -49,6 +49,7 @@ int arg_debug = 0; // print debug messages | |||
49 | int arg_debug_check_filename = 0; // print debug messages for filename checking | 49 | int arg_debug_check_filename = 0; // print debug messages for filename checking |
50 | int arg_debug_blacklists = 0; // print debug messages for blacklists | 50 | int arg_debug_blacklists = 0; // print debug messages for blacklists |
51 | int arg_debug_whitelists = 0; // print debug messages for whitelists | 51 | int arg_debug_whitelists = 0; // print debug messages for whitelists |
52 | int arg_debug_private_lib = 0; // print debug messages for private-lib | ||
52 | int arg_nonetwork = 0; // --net=none | 53 | int arg_nonetwork = 0; // --net=none |
53 | int arg_command = 0; // -c | 54 | int arg_command = 0; // -c |
54 | int arg_overlay = 0; // overlay option | 55 | int arg_overlay = 0; // overlay option |
@@ -1125,6 +1126,8 @@ int main(int argc, char **argv) { | |||
1125 | arg_debug_blacklists = 1; | 1126 | arg_debug_blacklists = 1; |
1126 | else if (strcmp(argv[i], "--debug-whitelists") == 0) | 1127 | else if (strcmp(argv[i], "--debug-whitelists") == 0) |
1127 | arg_debug_whitelists = 1; | 1128 | arg_debug_whitelists = 1; |
1129 | else if (strcmp(argv[i], "--debug-private-lib") == 0) | ||
1130 | arg_debug_private_lib = 1; | ||
1128 | else if (strcmp(argv[i], "--quiet") == 0) { | 1131 | else if (strcmp(argv[i], "--quiet") == 0) { |
1129 | arg_quiet = 1; | 1132 | arg_quiet = 1; |
1130 | arg_debug = 0; | 1133 | arg_debug = 0; |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 0bc3b20fd..38de99471 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -64,6 +64,7 @@ void usage(void) { | |||
64 | printf(" --debug-caps - print all recognized capabilities.\n"); | 64 | printf(" --debug-caps - print all recognized capabilities.\n"); |
65 | printf(" --debug-check-filename - debug filename checking.\n"); | 65 | printf(" --debug-check-filename - debug filename checking.\n"); |
66 | printf(" --debug-errnos - print all recognized error numbers.\n"); | 66 | printf(" --debug-errnos - print all recognized error numbers.\n"); |
67 | printf(" --debug-private-lib - debug for --private-lib option.\n"); | ||
67 | printf(" --debug-protocols - print all recognized protocols.\n"); | 68 | printf(" --debug-protocols - print all recognized protocols.\n"); |
68 | printf(" --debug-syscalls - print all recognized system calls.\n"); | 69 | printf(" --debug-syscalls - print all recognized system calls.\n"); |
69 | #ifdef HAVE_WHITELIST | 70 | #ifdef HAVE_WHITELIST |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 476050d9c..9f6da87ee 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -356,6 +356,9 @@ Example: | |||
356 | .br | 356 | .br |
357 | $ firejail \-\-debug-errnos | 357 | $ firejail \-\-debug-errnos |
358 | .TP | 358 | .TP |
359 | \fB\-\-debug-private-lib | ||
360 | Debug messages for --private-lib option. | ||
361 | .TP | ||
359 | \fB\-\-debug-protocols | 362 | \fB\-\-debug-protocols |
360 | Print all recognized protocols in the current Firejail software build and exit. | 363 | Print all recognized protocols in the current Firejail software build and exit. |
361 | .br | 364 | .br |