diff options
author | netblue30 <netblue30@yahoo.com> | 2018-05-25 07:12:00 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2018-05-25 07:12:00 -0400 |
commit | 7dbb224505d6b34a0eb1da15c185fe4851d3c76b (patch) | |
tree | 8300715baacf70142e7c0ad191c0cb7be8be9921 /src | |
parent | little x11_xorg cleanup (diff) | |
download | firejail-7dbb224505d6b34a0eb1da15c185fe4851d3c76b.tar.gz firejail-7dbb224505d6b34a0eb1da15c185fe4851d3c76b.tar.zst firejail-7dbb224505d6b34a0eb1da15c185fe4851d3c76b.zip |
globbing support in private-lib
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/fs_lib.c | 74 |
1 files changed, 46 insertions, 28 deletions
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 | ||