diff options
-rw-r--r-- | RELNOTES | 6 | ||||
-rw-r--r-- | etc/eog.profile | 2 | ||||
-rw-r--r-- | etc/evince.profile | 3 | ||||
-rw-r--r-- | etc/gedit.profile | 2 | ||||
-rw-r--r-- | etc/gnome-calculator.profile | 2 | ||||
-rw-r--r-- | etc/gnome-logs.profile | 2 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 74 |
7 files changed, 57 insertions, 34 deletions
@@ -1,4 +1,10 @@ | |||
1 | firejail (0.9.54) baseline; urgency=low | 1 | firejail (0.9.54) baseline; urgency=low |
2 | * work in progress | ||
3 | * support full paths in private-lib | ||
4 | * globbing support in private-lib | ||
5 | -- netblue30 <netblue30@yahoo.com> Fri, 5 May 2018 08:00:00 -0500 | ||
6 | |||
7 | firejail (0.9.54) baseline; urgency=low | ||
2 | * modif: --force removed | 8 | * modif: --force removed |
3 | * modif: --csh, --zsh removed | 9 | * modif: --csh, --zsh removed |
4 | * modif: --debug-check-filename removed | 10 | * modif: --debug-check-filename removed |
diff --git a/etc/eog.profile b/etc/eog.profile index 8a0925655..5b9ed9bd6 100644 --- a/etc/eog.profile +++ b/etc/eog.profile | |||
@@ -37,7 +37,7 @@ shell none | |||
37 | private-bin eog | 37 | private-bin eog |
38 | private-dev | 38 | private-dev |
39 | private-etc fonts | 39 | private-etc fonts |
40 | private-lib gdk-pixbuf-2.0,gio,girepository-1.0,gvfs,libgconf-2.so.4 | 40 | private-lib gdk-pixbuf-2.*,gio,girepository-1.*,gvfs,libgconf-2.so.* |
41 | private-tmp | 41 | private-tmp |
42 | 42 | ||
43 | #memory-deny-write-execute - breaks on Arch | 43 | #memory-deny-write-execute - breaks on Arch |
diff --git a/etc/evince.profile b/etc/evince.profile index cca564557..4a8c1a898 100644 --- a/etc/evince.profile +++ b/etc/evince.profile | |||
@@ -37,8 +37,7 @@ private-bin evince,evince-previewer,evince-thumbnailer | |||
37 | private-dev | 37 | private-dev |
38 | private-etc fonts | 38 | private-etc fonts |
39 | 39 | ||
40 | #private-lib - seems to be breaking on Gnome Shell 3.26.2, Mutter WM, issue 1711 | 40 | private-lib evince,gdk-pixbuf-2.*,gio,gvfs/libgvfscommon.so,libgconf-2.so.*,libpoppler-glib.so.*,librsvg-2.so.* |
41 | private-lib evince,gdk-pixbuf-2.0,gio,gvfs/libgvfscommon.so,libgconf-2.so.4,libpoppler-glib.so.8,librsvg-2.so.2 | ||
42 | 41 | ||
43 | private-tmp | 42 | private-tmp |
44 | 43 | ||
diff --git a/etc/gedit.profile b/etc/gedit.profile index d7ac6d36c..67ea43ca3 100644 --- a/etc/gedit.profile +++ b/etc/gedit.profile | |||
@@ -38,7 +38,7 @@ tracelog | |||
38 | # private-bin gedit | 38 | # private-bin gedit |
39 | private-dev | 39 | private-dev |
40 | # private-etc fonts | 40 | # private-etc fonts |
41 | private-lib /usr/bin/gedit,libtinfo.so.5,libreadline.so.7,gedit,libgspell-1.so.1,gconv,aspell | 41 | private-lib /usr/bin/gedit,libtinfo.so.*,libreadline.so.*,gedit,libgspell-1.so.*,gconv,aspell |
42 | private-tmp | 42 | private-tmp |
43 | 43 | ||
44 | noexec ${HOME} | 44 | noexec ${HOME} |
diff --git a/etc/gnome-calculator.profile b/etc/gnome-calculator.profile index 0aed6f52a..b915b0bce 100644 --- a/etc/gnome-calculator.profile +++ b/etc/gnome-calculator.profile | |||
@@ -35,7 +35,7 @@ shell none | |||
35 | disable-mnt | 35 | disable-mnt |
36 | private-bin gnome-calculator | 36 | private-bin gnome-calculator |
37 | private-dev | 37 | private-dev |
38 | private-lib gdk-pixbuf-2.0,gio,girepository-1.0,gvfs,libgconf-2.so.4,libgnutls.so.30,libproxy.so.1,librsvg-2.so.2,libxml2.so.2 | 38 | private-lib gdk-pixbuf-2.*,gio,girepository-1.*,gvfs,libgconf-2.so.*,libgnutls.so.*,libproxy.so.*,librsvg-2.so.*,libxml2.so.* |
39 | private-tmp | 39 | private-tmp |
40 | 40 | ||
41 | #memory-deny-write-execute - breaks on Arch | 41 | #memory-deny-write-execute - breaks on Arch |
diff --git a/etc/gnome-logs.profile b/etc/gnome-logs.profile index f8bb68fdd..ca4e5f204 100644 --- a/etc/gnome-logs.profile +++ b/etc/gnome-logs.profile | |||
@@ -35,7 +35,7 @@ disable-mnt | |||
35 | private-bin gnome-logs | 35 | private-bin gnome-logs |
36 | private-dev | 36 | private-dev |
37 | private-etc fonts,localtime,machine-id | 37 | private-etc fonts,localtime,machine-id |
38 | private-lib gdk-pixbuf-2.0,gio,gvfs/libgvfscommon.so,libgconf-2.so.4,librsvg-2.so.2 | 38 | private-lib gdk-pixbuf-2.*,gio,gvfs/libgvfscommon.so,libgconf-2.so.*,librsvg-2.so.* |
39 | private-tmp | 39 | private-tmp |
40 | writable-var-log | 40 | writable-var-log |
41 | 41 | ||
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index ec12ff01b..501188ca7 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | #include <dirent.h> | 26 | #include <dirent.h> |
27 | #include <glob.h> | ||
27 | #define MAXBUF 4096 | 28 | #define MAXBUF 4096 |
28 | 29 | ||
29 | extern void fslib_install_stdc(void); | 30 | extern void fslib_install_stdc(void); |
@@ -171,59 +172,76 @@ void fslib_copy_dir(const char *full_path) { | |||
171 | free(dest); | 172 | free(dest); |
172 | } | 173 | } |
173 | 174 | ||
175 | // fname should be a vallid full path at this point | ||
176 | static void load_library(const char *fname) { | ||
177 | assert(fname); | ||
178 | assert(*fname == '/'); | ||
174 | 179 | ||
180 | // existing file owned by root, read access | ||
181 | struct stat s; | ||
182 | if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) { | ||
183 | // load directories, regular 64 bit libraries, and 64 bit executables | ||
184 | if (is_dir(fname) || is_lib_64(fname)) { | ||
185 | if (is_dir(fname)) | ||
186 | fslib_copy_dir(fname); | ||
187 | else { | ||
188 | if (strstr(fname, ".so") || | ||
189 | access(fname, X_OK) != 0) // don't duplicate executables, just install the libraries | ||
190 | fslib_duplicate(fname); | ||
191 | |||
192 | fslib_copy_libs(fname); | ||
193 | } | ||
194 | } | ||
195 | } | ||
196 | } | ||
175 | 197 | ||
176 | static void install_list_entry(const char *lib) { | 198 | static void install_list_entry(const char *lib) { |
177 | char *fname = NULL; | ||
178 | |||
179 | // filename check | 199 | // filename check |
180 | int len = strlen(lib); | 200 | int len = strlen(lib); |
181 | if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len || | 201 | if (strcspn(lib, "\\&!?\"'<>%^(){}[];,") != (size_t)len || |
182 | strstr(lib, "..")) { | 202 | strstr(lib, "..")) { |
183 | fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib); | 203 | fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib); |
184 | exit(1); | 204 | exit(1); |
185 | } | 205 | } |
186 | 206 | ||
187 | // if this is a full path, use it as is | 207 | // if this is a full path, use it as is |
188 | if (*lib == '/') { | 208 | if (*lib == '/') |
189 | fname = strdup(lib); | 209 | return load_library(lib); |
190 | goto load_library; | ||
191 | } | ||
192 | 210 | ||
193 | 211 | ||
194 | // find the library | 212 | // find the library |
195 | int i; | 213 | int i; |
196 | for (i = 0; default_lib_paths[i]; i++) { | 214 | for (i = 0; default_lib_paths[i]; i++) { |
215 | char *fname = NULL; | ||
197 | if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1) | 216 | if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1) |
198 | errExit("asprintf"); | 217 | errExit("asprintf"); |
199 | 218 | ||
200 | // existing file owned by root, read access | 219 | #define DO_GLOBBING |
201 | struct stat s; | 220 | #ifdef DO_GLOBBING |
202 | if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) { | 221 | // globbing |
203 | // load directories and regular 64 bit libraries | 222 | glob_t globbuf; |
204 | if (is_dir(fname) || is_lib_64(fname)) | 223 | int globerr = glob(fname, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf); |
205 | goto load_library; | 224 | if (globerr) { |
206 | // if not 64bit, continue searching | 225 | fprintf(stderr, "Error: failed to glob private-lib pattern %s\n", fname); |
226 | exit(1); | ||
227 | } | ||
228 | size_t j; | ||
229 | for (j = 0; j < globbuf.gl_pathc; j++) { | ||
230 | assert(globbuf.gl_pathv[j]); | ||
231 | //printf("glob %s\n", globbuf.gl_pathv[j]); | ||
232 | // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway | ||
233 | load_library(globbuf.gl_pathv[j]); | ||
207 | } | 234 | } |
235 | |||
236 | globfree(&globbuf); | ||
237 | #else | ||
238 | load_library(fname); | ||
239 | #endif | ||
208 | free(fname); | 240 | free(fname); |
209 | } | 241 | } |
210 | 242 | ||
211 | // fwarning("%s library not found, skipping...\n", lib); | 243 | // fwarning("%s library not found, skipping...\n", lib); |
212 | return; | 244 | return; |
213 | |||
214 | load_library: | ||
215 | if (fname) { | ||
216 | if (is_dir(fname)) | ||
217 | fslib_copy_dir(fname); | ||
218 | else { | ||
219 | if (strstr(fname, ".so") || | ||
220 | access(fname, X_OK) != 0) // don't duplicate executables | ||
221 | fslib_duplicate(fname); | ||
222 | |||
223 | fslib_copy_libs(fname); | ||
224 | } | ||
225 | free(fname); | ||
226 | } | ||
227 | } | 245 | } |
228 | 246 | ||
229 | 247 | ||