aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-02-23 22:08:46 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2021-02-24 03:35:52 +0100
commita274ad13bb5a0fcf7b42ab13955be6e042301cf4 (patch)
treeaa0c182e7f0853697419724770beda0b08f96e3f
parentjailtest fix (diff)
downloadfirejail-a274ad13bb5a0fcf7b42ab13955be6e042301cf4.tar.gz
firejail-a274ad13bb5a0fcf7b42ab13955be6e042301cf4.tar.zst
firejail-a274ad13bb5a0fcf7b42ab13955be6e042301cf4.zip
add PATH_FCOPY to private-lib automatically
restore 45304621a6c600d8e30e98bfbef05149caaf56c5, but now run fldd as root user. This became necessary because in the meantime read permission on helper executables was removed. Puts infrastructure in place to add other helper binaries to private-lib as well, should the need arise.
-rw-r--r--src/firejail/fs_lib.c52
-rw-r--r--src/firejail/fs_lib2.c57
-rw-r--r--src/firejail/sbox.c7
3 files changed, 82 insertions, 34 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index a7f5b0bfc..9bf17b981 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -28,6 +28,7 @@
28#define MAXBUF 4096 28#define MAXBUF 4096
29 29
30extern void fslib_install_stdc(void); 30extern void fslib_install_stdc(void);
31extern void fslib_install_firejail(void);
31extern void fslib_install_system(void); 32extern void fslib_install_system(void);
32 33
33static int lib_cnt = 0; 34static int lib_cnt = 0;
@@ -141,14 +142,11 @@ void fslib_duplicate(const char *full_path) {
141// requires full path for lib 142// requires full path for lib
142// it could be a library or an executable 143// it could be a library or an executable
143// lib is not copied, only libraries used by it 144// lib is not copied, only libraries used by it
144void fslib_copy_libs(const char *full_path) { 145static void fslib_copy_libs(const char *full_path, unsigned mask) {
145 assert(full_path);
146 if (arg_debug || arg_debug_private_lib)
147 printf(" fslib_copy_libs %s\n", full_path);
148
149 // if library/executable does not exist or the user does not have read access to it 146 // if library/executable does not exist or the user does not have read access to it
150 // print a warning and exit the function. 147 // print a warning and exit the function.
151 if (access(full_path, R_OK)) { 148 if (((mask & SBOX_USER) && access(full_path, R_OK)) ||
149 ((mask & SBOX_ROOT) && access(full_path, F_OK))) {
152 if (arg_debug || arg_debug_private_lib) 150 if (arg_debug || arg_debug_private_lib)
153 printf("cannot find %s for private-lib, skipping...\n", full_path); 151 printf("cannot find %s for private-lib, skipping...\n", full_path);
154 return; 152 return;
@@ -157,13 +155,15 @@ void fslib_copy_libs(const char *full_path) {
157 // create an empty RUN_LIB_FILE and allow the user to write to it 155 // create an empty RUN_LIB_FILE and allow the user to write to it
158 unlink(RUN_LIB_FILE); // in case is there 156 unlink(RUN_LIB_FILE); // in case is there
159 create_empty_file_as_root(RUN_LIB_FILE, 0644); 157 create_empty_file_as_root(RUN_LIB_FILE, 0644);
160 if (chown(RUN_LIB_FILE, getuid(), getgid())) 158 if (mask & SBOX_USER) {
161 errExit("chown"); 159 if (chown(RUN_LIB_FILE, getuid(), getgid()))
160 errExit("chown");
161 }
162 162
163 // run fldd to extract the list of files 163 // run fldd to extract the list of files
164 if (arg_debug || arg_debug_private_lib) 164 if (arg_debug || arg_debug_private_lib)
165 printf(" running fldd %s\n", full_path); 165 printf(" running fldd %s\n", full_path);
166 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); 166 sbox_run(mask | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
167 167
168 // open the list of libraries and install them on by one 168 // open the list of libraries and install them on by one
169 FILE *fp = fopen(RUN_LIB_FILE, "r"); 169 FILE *fp = fopen(RUN_LIB_FILE, "r");
@@ -182,6 +182,19 @@ void fslib_copy_libs(const char *full_path) {
182 unlink(RUN_LIB_FILE); 182 unlink(RUN_LIB_FILE);
183} 183}
184 184
185void fslib_copy_libs_parse_as_root(const char *full_path) {
186 assert(full_path);
187 if (arg_debug || arg_debug_private_lib)
188 printf(" fslib_copy_libs_parse_as_root %s\n", full_path);
189 fslib_copy_libs(full_path, SBOX_ROOT);
190}
191
192void fslib_copy_libs_parse_as_user(const char *full_path) {
193 assert(full_path);
194 if (arg_debug || arg_debug_private_lib)
195 printf(" fslib_copy_libs_parse_as_user %s\n", full_path);
196 fslib_copy_libs(full_path, SBOX_USER);
197}
185 198
186void fslib_copy_dir(const char *full_path) { 199void fslib_copy_dir(const char *full_path) {
187 assert(full_path); 200 assert(full_path);
@@ -236,7 +249,7 @@ static void load_library(const char *fname) {
236 access(fname, X_OK) != 0) // don't duplicate executables, just install the libraries 249 access(fname, X_OK) != 0) // don't duplicate executables, just install the libraries
237 fslib_duplicate(fname); 250 fslib_duplicate(fname);
238 251
239 fslib_copy_libs(fname); 252 fslib_copy_libs_parse_as_user(fname);
240 } 253 }
241 } 254 }
242 } 255 }
@@ -379,25 +392,12 @@ void fs_private_lib(void) {
379 printf("Installing standard C library\n"); 392 printf("Installing standard C library\n");
380 fslib_install_stdc(); 393 fslib_install_stdc();
381 394
382 // start timetrace 395 // install other libraries needed by firejail
383 timetrace_start();
384
385 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
386 if (arg_debug || arg_debug_private_lib) 396 if (arg_debug || arg_debug_private_lib)
387 printf("Installing Firejail libraries\n"); 397 printf("Installing Firejail libraries\n");
388 fslib_install_list(PATH_FIREJAIL); 398 fslib_install_firejail();
389
390 // bring in firejail directory
391 fslib_install_list(LIBDIR "/firejail");
392
393 // bring in dhclient libraries
394 if (any_dhcp()) {
395 if (arg_debug || arg_debug_private_lib)
396 printf("Installing dhclient libraries\n");
397 fslib_install_list(RUN_MNT_DIR "/dhclient");
398 }
399 fmessage("Firejail libraries installed in %0.2f ms\n", timetrace_end());
400 399
400 // start timetrace
401 timetrace_start(); 401 timetrace_start();
402 402
403 // copy the libs in the new lib directory for the main exe 403 // copy the libs in the new lib directory for the main exe
diff --git a/src/firejail/fs_lib2.c b/src/firejail/fs_lib2.c
index 30e993438..d46cfed86 100644
--- a/src/firejail/fs_lib2.c
+++ b/src/firejail/fs_lib2.c
@@ -22,7 +22,8 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23 23
24extern void fslib_duplicate(const char *full_path); 24extern void fslib_duplicate(const char *full_path);
25extern void fslib_copy_libs(const char *full_path); 25extern void fslib_copy_libs_parse_as_user(const char *full_path);
26extern void fslib_copy_libs_parse_as_root(const char *full_path);
26extern void fslib_copy_dir(const char *full_path); 27extern void fslib_copy_dir(const char *full_path);
27 28
28//*************************************************************** 29//***************************************************************
@@ -123,6 +124,52 @@ void fslib_install_stdc(void) {
123 fmessage("Standard C library installed in %0.2f ms\n", timetrace_end()); 124 fmessage("Standard C library installed in %0.2f ms\n", timetrace_end());
124} 125}
125 126
127//***************************************************************
128// Firejail libraries
129//***************************************************************
130
131static void fdir(void) {
132 fslib_copy_dir(LIBDIR "/firejail");
133
134 // executables and libraries from firejail directory
135 static const char * const fbin[] = {
136 PATH_FCOPY, // currently sufficient to find all needed libraries
137 // PATH_FSECCOMP,
138 // PATH_FSEC_OPTIMIZE,
139 // PATH_FSEC_PRINT,
140 // RUN_FIREJAIL_LIB_DIR "/libtrace.so",
141 // RUN_FIREJAIL_LIB_DIR "/libtracelog.so",
142 // RUN_FIREJAIL_LIB_DIR "/libpostexecseccomp.so",
143 NULL,
144 };
145
146 // need to run fldd as root user, unprivileged users have no read permission on executables
147 int i;
148 for (i = 0; fbin[i]; i++)
149 fslib_copy_libs_parse_as_root(fbin[i]);
150}
151
152void fslib_install_firejail(void) {
153 timetrace_start();
154 // bring in firejail executable libraries, in case we are redirected here
155 // by a firejail symlink from /usr/local/bin/firejail
156 fslib_copy_libs_parse_as_user(PATH_FIREJAIL);
157
158 // bring in firejail directory
159 fdir();
160
161 // bring in dhclient libraries
162 if (any_dhcp())
163 fslib_copy_libs_parse_as_user(RUN_MNT_DIR "/dhclient");
164
165#ifdef HAVE_X11
166 // bring in xauth libraries
167 if (arg_x11_xorg)
168 fslib_copy_libs_parse_as_user("/usr/bin/xauth");
169#endif
170
171 fmessage("Firejail libraries installed in %0.2f ms\n", timetrace_end());
172}
126 173
127//*************************************************************** 174//***************************************************************
128// various system libraries 175// various system libraries
@@ -268,7 +315,7 @@ void fslib_install_system(void) {
268 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir1) == -1) 315 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir1) == -1)
269 errExit("asprintf"); 316 errExit("asprintf");
270 if (access(name, R_OK) == 0) { 317 if (access(name, R_OK) == 0) {
271 fslib_copy_libs(name); 318 fslib_copy_libs_parse_as_user(name);
272 fslib_copy_dir(name); 319 fslib_copy_dir(name);
273 } 320 }
274 else { 321 else {
@@ -277,7 +324,7 @@ void fslib_install_system(void) {
277 if (asprintf(&name, "/usr/lib64/%s", ptr->dir1) == -1) 324 if (asprintf(&name, "/usr/lib64/%s", ptr->dir1) == -1)
278 errExit("asprintf"); 325 errExit("asprintf");
279 if (access(name, R_OK) == 0) { 326 if (access(name, R_OK) == 0) {
280 fslib_copy_libs(name); 327 fslib_copy_libs_parse_as_user(name);
281 fslib_copy_dir(name); 328 fslib_copy_dir(name);
282 } 329 }
283 } 330 }
@@ -288,7 +335,7 @@ void fslib_install_system(void) {
288 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir2) == -1) 335 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir2) == -1)
289 errExit("asprintf"); 336 errExit("asprintf");
290 if (access(name, R_OK) == 0) { 337 if (access(name, R_OK) == 0) {
291 fslib_copy_libs(name); 338 fslib_copy_libs_parse_as_user(name);
292 fslib_copy_dir(name); 339 fslib_copy_dir(name);
293 } 340 }
294 else { 341 else {
@@ -297,7 +344,7 @@ void fslib_install_system(void) {
297 if (asprintf(&name, "/usr/lib64/%s", ptr->dir2) == -1) 344 if (asprintf(&name, "/usr/lib64/%s", ptr->dir2) == -1)
298 errExit("asprintf"); 345 errExit("asprintf");
299 if (access(name, R_OK) == 0) { 346 if (access(name, R_OK) == 0) {
300 fslib_copy_libs(name); 347 fslib_copy_libs_parse_as_user(name);
301 fslib_copy_dir(name); 348 fslib_copy_dir(name);
302 } 349 }
303 } 350 }
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index 933c93b0d..f9c41f661 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -203,15 +203,16 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char *
203 } 203 }
204 } 204 }
205 205
206 if (filtermask & SBOX_ROOT) { 206 if (filtermask & SBOX_USER)
207 drop_privs(1);
208 else if (filtermask & SBOX_ROOT) {
207 // elevate privileges in order to get grsecurity working 209 // elevate privileges in order to get grsecurity working
208 if (setreuid(0, 0)) 210 if (setreuid(0, 0))
209 errExit("setreuid"); 211 errExit("setreuid");
210 if (setregid(0, 0)) 212 if (setregid(0, 0))
211 errExit("setregid"); 213 errExit("setregid");
212 } 214 }
213 else if (filtermask & SBOX_USER) 215 else assert(0);
214 drop_privs(1);
215 216
216 if (arg[0]) { // get rid of scan-build warning 217 if (arg[0]) { // get rid of scan-build warning
217 int fd = open(arg[0], O_PATH | O_CLOEXEC); 218 int fd = open(arg[0], O_PATH | O_CLOEXEC);