aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar startx2017 <vradu.startx@yandex.com>2018-03-12 08:41:01 -0400
committerLibravatar startx2017 <vradu.startx@yandex.com>2018-03-12 08:41:01 -0400
commit14b5746d8fba392c02733ce4c90befc32a93fb15 (patch)
tree2ac6a7de4adaafc730511a70f11b88aca1f47244 /src
parentfix bash on CentOS 7 (diff)
downloadfirejail-14b5746d8fba392c02733ce4c90befc32a93fb15.tar.gz
firejail-14b5746d8fba392c02733ce4c90befc32a93fb15.tar.zst
firejail-14b5746d8fba392c02733ce4c90befc32a93fb15.zip
private-lib bug: 32 bit libraries being copied instead of 64 bit versions; splitting common code for firejail and fldd in a common static library
Diffstat (limited to 'src')
-rw-r--r--src/firejail/Makefile.in4
-rw-r--r--src/firejail/fs_lib.c47
-rw-r--r--src/fldd/Makefile.in6
-rw-r--r--src/fldd/main.c55
-rw-r--r--src/include/ldd_utils.h46
-rw-r--r--src/lib/Makefile.in2
-rw-r--r--src/lib/ldd_utils.c62
7 files changed, 162 insertions, 60 deletions
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in
index 146bf8242..01cb929e2 100644
--- a/src/firejail/Makefile.in
+++ b/src/firejail/Makefile.in
@@ -36,8 +36,8 @@ LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
36%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h 36%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h
37 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 37 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
38 38
39firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o 39firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o ../lib/ldd_utils.o
40 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS) 40 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS)
41 41
42clean:; rm -f *.o firejail firejail.1 firejail.1.gz *.gcov *.gcda *.gcno 42clean:; rm -f *.o firejail firejail.1 firejail.1.gz *.gcov *.gcda *.gcno
43 43
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index f7351339c..8a105be97 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -18,6 +18,7 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20#include "firejail.h" 20#include "firejail.h"
21#include "../include/ldd_utils.h"
21#include <sys/mount.h> 22#include <sys/mount.h>
22#include <sys/stat.h> 23#include <sys/stat.h>
23#include <sys/types.h> 24#include <sys/types.h>
@@ -25,17 +26,6 @@
25#include <dirent.h> 26#include <dirent.h>
26#define MAXBUF 4096 27#define MAXBUF 4096
27 28
28static const char * const lib_paths[] = {
29 "/lib",
30 "/lib/x86_64-linux-gnu",
31 "/lib64",
32 "/usr/lib",
33 "/usr/lib/x86_64-linux-gnu",
34 LIBDIR,
35 "/usr/local/lib",
36 NULL
37}; // Note: this array is duplicated in src/fldd/main.c
38
39extern void fslib_install_stdc(void); 29extern void fslib_install_stdc(void);
40extern void fslib_install_system(void); 30extern void fslib_install_system(void);
41 31
@@ -47,9 +37,9 @@ static void report_duplication(const char *full_path) {
47 if (fname && *(++fname) != '\0') { 37 if (fname && *(++fname) != '\0') {
48 // report the file on all bin paths 38 // report the file on all bin paths
49 int i = 0; 39 int i = 0;
50 while (lib_paths[i]) { 40 while (default_lib_paths[i]) {
51 char *p; 41 char *p;
52 if (asprintf(&p, "%s/%s", lib_paths[i], fname) == -1) 42 if (asprintf(&p, "%s/%s", default_lib_paths[i], fname) == -1)
53 errExit("asprintf"); 43 errExit("asprintf");
54 fs_logger2("clone", p); 44 fs_logger2("clone", p);
55 free(p); 45 free(p);
@@ -194,19 +184,24 @@ static char *valid_file(const char *lib) {
194 184
195 // find the library 185 // find the library
196 int i; 186 int i;
197 for (i = 0; lib_paths[i]; i++) { 187 for (i = 0; default_lib_paths[i]; i++) {
198 char *fname; 188 char *fname;
199 if (asprintf(&fname, "%s/%s", lib_paths[i], lib) == -1) 189 if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1)
200 errExit("asprintf"); 190 errExit("asprintf");
201 191
202 // existing file owned by root, read access 192 // existing file owned by root, read access
203 struct stat s; 193 struct stat s;
204 if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) { 194 if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) {
205 return fname; 195 if (is_dir(fname))
196 return fname;
197 // for regular libraries check if it is 64bit
198 if (is_lib_64(fname))
199 return fname;
200 // if not 64bit, continue searching
206 } 201 }
207 free(fname); 202 free(fname);
208 } 203 }
209 204printf("not found %s\n", lib);
210 fwarning("%s library not found, skipping...\n", lib); 205 fwarning("%s library not found, skipping...\n", lib);
211 return NULL; 206 return NULL;
212} 207}
@@ -268,25 +263,33 @@ void fs_private_lib(void) {
268 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); 263 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0);
269 264
270 // install standard C libraries 265 // install standard C libraries
266 if (arg_debug || arg_debug_private_lib)
267 printf("*** Installing standard C library\n");
271 fslib_install_stdc(); 268 fslib_install_stdc();
272 269
270 // start timetrace
273 timetrace_start(); 271 timetrace_start();
274 272
275 // copy the libs in the new lib directory for the main exe 273 // copy the libs in the new lib directory for the main exe
276 if (cfg.original_program_index > 0) 274 if (cfg.original_program_index > 0) {
275 if (arg_debug || arg_debug_private_lib)
276 printf("*** Installing sandboxed program libraries\n");
277 fslib_copy_libs(cfg.original_argv[cfg.original_program_index]); 277 fslib_copy_libs(cfg.original_argv[cfg.original_program_index]);
278 }
278 279
279 // for the shell 280 // for the shell
280 if (!arg_shell_none) { 281 if (!arg_shell_none) {
282 if (arg_debug || arg_debug_private_lib)
283 printf("*** Installing shell libraries\n");
281 fslib_copy_libs(cfg.shell); 284 fslib_copy_libs(cfg.shell);
282 // a shell is useless without ls command 285 // a shell is useless without ls command
283 fslib_copy_libs("/bin/ls"); 286 fslib_copy_libs("/bin/ls");
284 } 287 }
285 288
286 // for the listed libs 289 // for the listed libs and directories
287 if (private_list && *private_list != '\0') { 290 if (private_list && *private_list != '\0') {
288 if (arg_debug || arg_debug_private_lib) 291 if (arg_debug || arg_debug_private_lib)
289 printf("Copying extra files (%s) in the new lib directory\n", private_list); 292 printf("*** Processing private-lib files (%s)\n", private_list);
290 293
291 char *dlist = strdup(private_list); 294 char *dlist = strdup(private_list);
292 if (!dlist) 295 if (!dlist)
@@ -322,6 +325,8 @@ void fs_private_lib(void) {
322 325
323 // for private-bin files 326 // for private-bin files
324 if (arg_private_bin) { 327 if (arg_private_bin) {
328 if (arg_debug || arg_debug_private_lib)
329 printf("*** Processing private-bin files\n");
325 FILE *fp = fopen(RUN_LIB_BIN, "r"); 330 FILE *fp = fopen(RUN_LIB_BIN, "r");
326 if (fp) { 331 if (fp) {
327 char buf[MAXBUF]; 332 char buf[MAXBUF];
@@ -368,6 +373,8 @@ void fs_private_lib(void) {
368 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end()); 373 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end());
369 374
370 // install the reset of the system libraries 375 // install the reset of the system libraries
376 if (arg_debug || arg_debug_private_lib)
377 printf("*** Installing system libraries\n");
371 fslib_install_system(); 378 fslib_install_system();
372 379
373 fmessage("Installed %d libraries and %d directories\n", lib_cnt, dir_cnt); 380 fmessage("Installed %d libraries and %d directories\n", lib_cnt, dir_cnt);
diff --git a/src/fldd/Makefile.in b/src/fldd/Makefile.in
index 7369c835b..e2bf4b787 100644
--- a/src/fldd/Makefile.in
+++ b/src/fldd/Makefile.in
@@ -33,11 +33,11 @@ BINOBJS = $(foreach file, $(OBJS), $file)
33CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 33CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
34LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread 34LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
35 35
36%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 36%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h ../include/ldd_utils.h
37 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 37 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
38 38
39fldd: $(OBJS) 39fldd: $(OBJS) ../lib/ldd_utils.o
40 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 40 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS)
41 41
42clean:; rm -f *.o fldd *.gcov *.gcda *.gcno 42clean:; rm -f *.o fldd *.gcov *.gcda *.gcno
43 43
diff --git a/src/fldd/main.c b/src/fldd/main.c
index a0530c235..be4500d2a 100644
--- a/src/fldd/main.c
+++ b/src/fldd/main.c
@@ -19,8 +19,8 @@
19*/ 19*/
20 20
21#include "../include/common.h" 21#include "../include/common.h"
22#include "../include/ldd_utils.h"
22 23
23#include <elf.h>
24#include <fcntl.h> 24#include <fcntl.h>
25#include <sys/mman.h> 25#include <sys/mman.h>
26#include <sys/mount.h> 26#include <sys/mount.h>
@@ -29,36 +29,10 @@
29#include <unistd.h> 29#include <unistd.h>
30#include <dirent.h> 30#include <dirent.h>
31 31
32#ifdef __LP64__
33#define Elf_Ehdr Elf64_Ehdr
34#define Elf_Phdr Elf64_Phdr
35#define Elf_Shdr Elf64_Shdr
36#define Elf_Dyn Elf64_Dyn
37#else
38#define Elf_Ehdr Elf32_Ehdr
39#define Elf_Phdr Elf32_Phdr
40#define Elf_Shdr Elf32_Shdr
41#define Elf_Dyn Elf32_Dyn
42#endif
43 32
44static int arg_quiet = 0; 33static int arg_quiet = 0;
45static void copy_libs_for_lib(const char *lib); 34static void copy_libs_for_lib(const char *lib);
46 35
47static const char * const default_lib_paths[] = {
48 "/lib",
49 "/lib/x86_64-linux-gnu",
50 "/lib64",
51 "/usr/lib",
52 "/usr/lib/x86_64-linux-gnu",
53 LIBDIR,
54 "/usr/local/lib",
55 "/usr/lib/x86_64-linux-gnu/mesa", // libGL.so is sometimes a symlink into this directory
56 "/usr/lib/x86_64-linux-gnu/mesa-egl", // libGL.so is sometimes a symlink into this directory
57// "/usr/lib/x86_64-linux-gnu/plasma-discover",
58 NULL
59};
60
61
62typedef struct storage_t { 36typedef struct storage_t {
63 struct storage_t *next; 37 struct storage_t *next;
64 const char *name; 38 const char *name;
@@ -107,7 +81,8 @@ static bool ptr_ok(const void *ptr, const void *base, const void *end, const cha
107 return r; 81 return r;
108} 82}
109 83
110static void copy_libs_for_exe(const char *exe) { 84
85static void parse_elf(const char *exe) {
111 int f; 86 int f;
112 f = open(exe, O_RDONLY); 87 f = open(exe, O_RDONLY);
113 if (f < 0) { 88 if (f < 0) {
@@ -132,6 +107,12 @@ static void copy_libs_for_exe(const char *exe) {
132 fprintf(stderr, "Warning fldd: %s is not an ELF executable or library\n", exe); 107 fprintf(stderr, "Warning fldd: %s is not an ELF executable or library\n", exe);
133 goto close; 108 goto close;
134 } 109 }
110//unsigned char elfclass = ebuf->e_ident[EI_CLASS];
111//if (elfclass == ELFCLASS32)
112//printf("%s 32bit\n", exe);
113//else if (elfclass == ELFCLASS64)
114//printf("%s 64bit\n", exe);
115
135 116
136 Elf_Phdr *pbuf = (Elf_Phdr *)(base + sizeof(*ebuf)); 117 Elf_Phdr *pbuf = (Elf_Phdr *)(base + sizeof(*ebuf));
137 while (ebuf->e_phnum-- > 0 && ptr_ok(pbuf, base, end, "pbuf")) { 118 while (ebuf->e_phnum-- > 0 && ptr_ok(pbuf, base, end, "pbuf")) {
@@ -227,11 +208,11 @@ static void copy_libs_for_lib(const char *lib) {
227 char *fname; 208 char *fname;
228 if (asprintf(&fname, "%s/%s", lib_path->name, lib) == -1) 209 if (asprintf(&fname, "%s/%s", lib_path->name, lib) == -1)
229 errExit("asprintf"); 210 errExit("asprintf");
230 if (access(fname, R_OK) == 0) { 211 if (access(fname, R_OK) == 0 && is_lib_64(fname)) {
231 if (!storage_find(libs, fname)) { 212 if (!storage_find(libs, fname)) {
232 storage_add(&libs, fname); 213 storage_add(&libs, fname);
233 // libs may need other libs 214 // libs may need other libs
234 copy_libs_for_exe(fname); 215 parse_elf(fname);
235 } 216 }
236 free(fname); 217 free(fname);
237 return; 218 return;
@@ -270,9 +251,9 @@ static void walk_directory(const char *dirname) {
270 251
271 // check regular so library 252 // check regular so library
272 char *ptr = strstr(entry->d_name, ".so"); 253 char *ptr = strstr(entry->d_name, ".so");
273 if (ptr) { 254 if (ptr && is_lib_64(path)) {
274 if (*(ptr + 3) == '\0' || *(ptr + 3) == '.') { 255 if (*(ptr + 3) == '\0' || *(ptr + 3) == '.') {
275 copy_libs_for_exe(path); 256 parse_elf(path);
276 free(path); 257 free(path);
277 continue; 258 continue;
278 } 259 }
@@ -356,8 +337,14 @@ printf("\n");
356 errExit("stat"); 337 errExit("stat");
357 if (S_ISDIR(s.st_mode)) 338 if (S_ISDIR(s.st_mode))
358 walk_directory(argv[1]); 339 walk_directory(argv[1]);
359 else 340 else {
360 copy_libs_for_exe(argv[1]); 341 if (is_lib_64(argv[1]))
342 parse_elf(argv[1]);
343 else {
344 fprintf(stderr, "Error fldd: %s is not a 64bit program/library\n", argv[1]);
345 exit(1);
346 }
347 }
361 348
362 349
363 // print libraries and exit 350 // print libraries and exit
diff --git a/src/include/ldd_utils.h b/src/include/ldd_utils.h
new file mode 100644
index 000000000..28f5be7bf
--- /dev/null
+++ b/src/include/ldd_utils.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2014-2018 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#ifndef LDD_UTILS_H
22#define LDD_UTILS_H
23
24#include "../include/common.h"
25#include <elf.h>
26
27#ifdef __LP64__
28#define Elf_Ehdr Elf64_Ehdr
29#define Elf_Phdr Elf64_Phdr
30#define Elf_Shdr Elf64_Shdr
31#define Elf_Dyn Elf64_Dyn
32#else
33#define Elf_Ehdr Elf32_Ehdr
34#define Elf_Phdr Elf32_Phdr
35#define Elf_Shdr Elf32_Shdr
36#define Elf_Dyn Elf32_Dyn
37#endif
38
39extern const char * const default_lib_paths[];
40
41// return 1 if this is a 64 bit program/library
42int is_lib_64(const char *exe);
43
44
45
46#endif \ No newline at end of file
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 63b0ad56d..a49e56ad2 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -10,7 +10,7 @@ H_FILE_LIST = $(sort $(wildcard *.[h]))
10C_FILE_LIST = $(sort $(wildcard *.c)) 10C_FILE_LIST = $(sort $(wildcard *.c))
11OBJS = $(C_FILE_LIST:.c=.o) 11OBJS = $(C_FILE_LIST:.c=.o)
12BINOBJS = $(foreach file, $(OBJS), $file) 12BINOBJS = $(foreach file, $(OBJS), $file)
13CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security 13CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DLIBDIR='"$(libdir)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security
14LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now 14LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now
15 15
16all: $(OBJS) 16all: $(OBJS)
diff --git a/src/lib/ldd_utils.c b/src/lib/ldd_utils.c
new file mode 100644
index 000000000..556fb02eb
--- /dev/null
+++ b/src/lib/ldd_utils.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2014-2018 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "../include/ldd_utils.h"
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <fcntl.h>
25
26const char * const default_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 "/usr/lib/x86_64-linux-gnu/mesa", // libGL.so is sometimes a symlink into this directory
35 "/usr/lib/x86_64-linux-gnu/mesa-egl", // libGL.so is sometimes a symlink into this directory
36// "/usr/lib/x86_64-linux-gnu/plasma-discover",
37 NULL
38};
39
40// return 1 if this is a 64 bit program/library
41int is_lib_64(const char *exe) {
42 int retval = 0;
43 int fd = open(exe, O_RDONLY);
44 if (fd < 0)
45 return 0;
46
47 unsigned char buf[EI_NIDENT];
48 ssize_t len = 0;
49 while (len < EI_NIDENT) {
50 ssize_t sz = read(fd, buf, EI_NIDENT);
51 if (sz <= 0)
52 goto doexit;
53 len += sz;
54 }
55
56 if (buf[EI_CLASS] == ELFCLASS64)
57 retval = 1;
58
59doexit:
60 close(fd);
61 return retval;
62}