diff options
author | netblue30 <netblue30@protonmail.com> | 2021-02-24 10:46:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-24 10:46:04 -0500 |
commit | 14c5ecfdb4a9f370a24165a664b27cd303477db7 (patch) | |
tree | 5f54bd8d92d1b790ac9c68b33cded80aeb515c48 | |
parent | Merge pull request #3998 from Tomin1/first_fixes (diff) | |
parent | add PATH_FCOPY to private-lib automatically (diff) | |
download | firejail-14c5ecfdb4a9f370a24165a664b27cd303477db7.tar.gz firejail-14c5ecfdb4a9f370a24165a664b27cd303477db7.tar.zst firejail-14c5ecfdb4a9f370a24165a664b27cd303477db7.zip |
Merge pull request #4004 from smitsohu/privatelib4
add PATH_FCOPY to private-lib automatically
-rw-r--r-- | src/firejail/fs_lib.c | 52 | ||||
-rw-r--r-- | src/firejail/fs_lib2.c | 57 | ||||
-rw-r--r-- | src/firejail/sbox.c | 7 |
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 | ||
30 | extern void fslib_install_stdc(void); | 30 | extern void fslib_install_stdc(void); |
31 | extern void fslib_install_firejail(void); | ||
31 | extern void fslib_install_system(void); | 32 | extern void fslib_install_system(void); |
32 | 33 | ||
33 | static int lib_cnt = 0; | 34 | static 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 |
144 | void fslib_copy_libs(const char *full_path) { | 145 | static 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 | ||
185 | void 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 | |||
192 | void 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 | ||
186 | void fslib_copy_dir(const char *full_path) { | 199 | void 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 | ||
24 | extern void fslib_duplicate(const char *full_path); | 24 | extern void fslib_duplicate(const char *full_path); |
25 | extern void fslib_copy_libs(const char *full_path); | 25 | extern void fslib_copy_libs_parse_as_user(const char *full_path); |
26 | extern void fslib_copy_libs_parse_as_root(const char *full_path); | ||
26 | extern void fslib_copy_dir(const char *full_path); | 27 | extern 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 | |||
131 | static 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 | |||
152 | void 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); |