aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/fs_lib.c')
-rw-r--r--src/firejail/fs_lib.c74
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
29extern void fslib_install_stdc(void); 30extern 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
176static 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
176static void install_list_entry(const char *lib) { 198static 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
214load_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