aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_lib.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-08-04 08:07:45 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-08-04 08:07:45 -0400
commitb35aed22f8334ceeafbf388d024b4b8a7a6dec7e (patch)
treeb469bb3d96984e3ec26aa57984e4e41e3638a704 /src/firejail/fs_lib.c
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.tar.gz
firejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.tar.zst
firejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.zip
private-lib: bringing in private-lib list from command line
Diffstat (limited to 'src/firejail/fs_lib.c')
-rw-r--r--src/firejail/fs_lib.c114
1 files changed, 98 insertions, 16 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 576b4a0df..94d87a151 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -23,24 +23,51 @@
23#include <sys/types.h> 23#include <sys/types.h>
24#include <unistd.h> 24#include <unistd.h>
25 25
26static const char * const lib_paths[] = {
27 "/lib",
28 "/lib/x86_64-linux-gnu",
29 "/lib64",
30 "/usr/lib",
31 "/usr/lib/x86_64-linux-gnu",
32 LIBDIR,
33 "/usr/local/lib",
34 NULL
35}; // Note: this array is duplicated in src/fldd/main.c
36
37static void copy_libs(const char *exe, const char *dir, const char *file);
38
26static void duplicate(const char *fname, const char *private_run_dir) { 39static void duplicate(const char *fname, const char *private_run_dir) {
27 if (arg_debug) 40 if (arg_debug)
28 printf("copying %s to private %s\n", fname, private_run_dir); 41 printf("copying %s to private %s\n", fname, private_run_dir);
29 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir); 42 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir);
30} 43}
31 44
32static void copy_libs(const char *exe, const char *dir, const char *file) { 45
46// requires full path for exe
47static void copy_exe(const char *exe, const char *dir, const char *file) {
48 // if exe does not exist or the user does not have read access to it
49 // print a warning and exit the function.
50 if (access(exe, R_OK)) {
51 fwarning("cannot find %s executable for private-lib, skipping...\n", exe);
52 return;
53 }
54
55 copy_libs(exe, dir, file);
56}
57
58// requires full path for lib
59static void copy_libs(const char *lib, const char *dir, const char *output_file) {
33 // create an empty RUN_LIB_FILE and allow the user to write to it 60 // create an empty RUN_LIB_FILE and allow the user to write to it
34 unlink(file); // in case is there 61 unlink(output_file); // in case is there
35 create_empty_file_as_root(file, 0644); 62 create_empty_file_as_root(output_file, 0644);
36 if (chown(file, getuid(), getgid())) 63 if (chown(output_file, getuid(), getgid()))
37 errExit("chown"); 64 errExit("chown");
38 65
39 // run fldd to extact the list of file 66 // run fldd to extact the list of file
40 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, exe, file); 67 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, lib, output_file);
41 68
42 // open the list of libraries and install them on by one 69 // open the list of libraries and install them on by one
43 FILE *fp = fopen(file, "r"); 70 FILE *fp = fopen(output_file, "r");
44 if (!fp) 71 if (!fp)
45 errExit("fopen"); 72 errExit("fopen");
46 73
@@ -56,22 +83,67 @@ static void copy_libs(const char *exe, const char *dir, const char *file) {
56 fclose(fp); 83 fclose(fp);
57} 84}
58 85
86// return 1 if the file is valid
87static char *valid_library(const char *lib) {
88 // filename check
89 int len = strlen(lib);
90 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len ||
91 strstr(lib, "..")) {
92 fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib);
93 exit(1);
94 }
95
96 // find the library
97 int i;
98 for (i = 0; lib_paths[i]; i++) {
99 char *fname;
100 if (asprintf(&fname, "%s/%s", lib_paths[i], lib) == -1)
101 errExit("asprintf");
102
103 // existing file owned by root
104 struct stat s;
105 if (stat(fname, &s) == 0 && s.st_uid == 0) {
106 return fname;
107 }
108 free(fname);
109 }
110
111 fwarning("%s library not found, skipping...\n", lib);
112 return NULL;
113}
114
59 115
60void fs_private_lib(void) { 116void fs_private_lib(void) {
61// char *private_list = cfg.lib_private_keep; 117 char *private_list = cfg.lib_private_keep;
118
119 if (arg_debug)
120 printf("Starting private-lib processing: program %s, shell %s\n",
121 (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none",
122 (arg_shell_none)? "none": cfg.shell);
62 123
63 // create /run/firejail/mnt/lib directory 124 // create /run/firejail/mnt/lib directory
64 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); 125 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0);
65 126
127 // fix libselinux linking problem on Debian stretch; the library is
128 // linked in most basic command utilities (ls, cp, find etc.), and it
129 // seems to have a path hardlinked under /lib/x86_64-linux-gnu directory.
130 struct stat s;
131 if (stat("/lib/x86_64-linux-gnu/libselinux.so.1", &s) == 0) {
132 mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0);
133 duplicate("/lib/x86_64-linux-gnu/libselinux.so.1", RUN_LIB_DIR "/x86_64-linux-gnu");
134 }
135
66 // copy the libs in the new lib directory for the main exe 136 // copy the libs in the new lib directory for the main exe
67 if (cfg.original_program_index > 0) 137 if (cfg.original_program_index > 0)
68 copy_libs(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE); 138 copy_exe(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE);
69 139
70 // for the shell 140 // for the shell
71 if (!arg_shell_none) 141 if (!arg_shell_none) {
72 copy_libs(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE); 142 copy_exe(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE);
143 // a shell is useless without ls command
144 copy_libs("/bin/ls", RUN_LIB_DIR, RUN_LIB_FILE);
145 }
73 146
74#if 0 // TODO - work in progress
75 // for the listed libs 147 // for the listed libs
76 if (private_list && *private_list != '\0') { 148 if (private_list && *private_list != '\0') {
77 if (arg_debug) 149 if (arg_debug)
@@ -82,14 +154,24 @@ void fs_private_lib(void) {
82 errExit("strdup"); 154 errExit("strdup");
83 155
84 char *ptr = strtok(dlist, ","); 156 char *ptr = strtok(dlist, ",");
85 copy_libs_for_lib(ptr, RUN_LIB_DIR); 157 char *lib = valid_library(ptr);
86 158 if (lib) {
87 while ((ptr = strtok(NULL, ",")) != NULL) 159 duplicate(lib, RUN_LIB_DIR);
88 copy_libs_for_lib(ptr, RUN_LIB_DIR); 160 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE);
161 free(lib);
162 }
163
164 while ((ptr = strtok(NULL, ",")) != NULL) {
165 lib = valid_library(ptr);
166 if (lib) {
167 duplicate(lib, RUN_LIB_DIR);
168 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE);
169 free(lib);
170 }
171 }
89 free(dlist); 172 free(dlist);
90 fs_logger_print(); 173 fs_logger_print();
91 } 174 }
92#endif
93 175
94 // for our trace and tracelog libs 176 // for our trace and tracelog libs
95 if (arg_trace) 177 if (arg_trace)