aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in3
-rw-r--r--README3
-rwxr-xr-xconfigure17
-rw-r--r--configure.ac2
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_lib.c156
6 files changed, 55 insertions, 128 deletions
diff --git a/Makefile.in b/Makefile.in
index 34a9eb856..6d8bf5f72 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
1all: apps man filters 1all: apps man filters
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/fnet src/fseccomp src/fcopy 3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/fnet src/fseccomp src/fcopy src/fldd
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
5SECCOMP_FILTERS = seccomp seccomp.i386 seccomp.amd64 5SECCOMP_FILTERS = seccomp seccomp.i386 seccomp.amd64
6 6
@@ -96,6 +96,7 @@ endif
96 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/. 96 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
97 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/. 97 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
98 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/. 98 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/.
99 install -c -m 0755 src/fldd/fldd $(DESTDIR)/$(libdir)/firejail/.
99ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP) 100ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
100 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/. 101 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/.
101 install -c -m 0644 seccomp $(DESTDIR)/$(libdir)/firejail/. 102 install -c -m 0644 seccomp $(DESTDIR)/$(libdir)/firejail/.
diff --git a/README b/README
index 13692aed7..45b4c1833 100644
--- a/README
+++ b/README
@@ -36,6 +36,7 @@ Committers
36- Fred-Barclay (https://github.com/Fred-Barclay) 36- Fred-Barclay (https://github.com/Fred-Barclay)
37- Reiner Herrmann (https://github.com/reinerh) 37- Reiner Herrmann (https://github.com/reinerh)
38- startx2017 (https://github.com/startx2017) - 0.9.38-LTS and *bugfixes branches maintainer 38- startx2017 (https://github.com/startx2017) - 0.9.38-LTS and *bugfixes branches maintainer
39- Topi Miettinen (https://github.com/topimiettinen)
39- netblue30 (netblue30@yahoo.com) 40- netblue30 (netblue30@yahoo.com)
40 41
41 42
@@ -462,6 +463,8 @@ Topi Miettinen (https://github.com/topimiettinen)
462 - improve mount handling, fix /run/user handling 463 - improve mount handling, fix /run/user handling
463 - /proc/sys can be nosuid,noexec,nodev 464 - /proc/sys can be nosuid,noexec,nodev
464 - seccomp default list update 465 - seccomp default list update
466 - improve loading of seccomp filter and memory-deny-write-execute feature
467 - private-lib feature
465valoq (https://github.com/valoq) 468valoq (https://github.com/valoq)
466 - lots of profile fixes 469 - lots of profile fixes
467 - added support for /srv in --whitelist feature 470 - added support for /srv in --whitelist feature
diff --git a/configure b/configure
index f8a606f88..3dda0918e 100755
--- a/configure
+++ b/configure
@@ -676,6 +676,7 @@ infodir
676docdir 676docdir
677oldincludedir 677oldincludedir
678includedir 678includedir
679runstatedir
679localstatedir 680localstatedir
680sharedstatedir 681sharedstatedir
681sysconfdir 682sysconfdir
@@ -763,6 +764,7 @@ datadir='${datarootdir}'
763sysconfdir='${prefix}/etc' 764sysconfdir='${prefix}/etc'
764sharedstatedir='${prefix}/com' 765sharedstatedir='${prefix}/com'
765localstatedir='${prefix}/var' 766localstatedir='${prefix}/var'
767runstatedir='${localstatedir}/run'
766includedir='${prefix}/include' 768includedir='${prefix}/include'
767oldincludedir='/usr/include' 769oldincludedir='/usr/include'
768docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' 770docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1015,6 +1017,15 @@ do
1015 | -silent | --silent | --silen | --sile | --sil) 1017 | -silent | --silent | --silen | --sile | --sil)
1016 silent=yes ;; 1018 silent=yes ;;
1017 1019
1020 -runstatedir | --runstatedir | --runstatedi | --runstated \
1021 | --runstate | --runstat | --runsta | --runst | --runs \
1022 | --run | --ru | --r)
1023 ac_prev=runstatedir ;;
1024 -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
1025 | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
1026 | --run=* | --ru=* | --r=*)
1027 runstatedir=$ac_optarg ;;
1028
1018 -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) 1029 -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
1019 ac_prev=sbindir ;; 1030 ac_prev=sbindir ;;
1020 -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ 1031 -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1152,7 +1163,7 @@ fi
1152for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ 1163for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
1153 datadir sysconfdir sharedstatedir localstatedir includedir \ 1164 datadir sysconfdir sharedstatedir localstatedir includedir \
1154 oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ 1165 oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
1155 libdir localedir mandir 1166 libdir localedir mandir runstatedir
1156do 1167do
1157 eval ac_val=\$$ac_var 1168 eval ac_val=\$$ac_var
1158 # Remove trailing slashes. 1169 # Remove trailing slashes.
@@ -1305,6 +1316,7 @@ Fine tuning of the installation directories:
1305 --sysconfdir=DIR read-only single-machine data [PREFIX/etc] 1316 --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
1306 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] 1317 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
1307 --localstatedir=DIR modifiable single-machine data [PREFIX/var] 1318 --localstatedir=DIR modifiable single-machine data [PREFIX/var]
1319 --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
1308 --libdir=DIR object code libraries [EPREFIX/lib] 1320 --libdir=DIR object code libraries [EPREFIX/lib]
1309 --includedir=DIR C header files [PREFIX/include] 1321 --includedir=DIR C header files [PREFIX/include]
1310 --oldincludedir=DIR C header files for non-gcc [/usr/include] 1322 --oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -3811,7 +3823,7 @@ if test "$prefix" = /usr; then
3811 sysconfdir="/etc" 3823 sysconfdir="/etc"
3812fi 3824fi
3813 3825
3814ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile" 3826ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile src/fldd/Makefile"
3815 3827
3816cat >confcache <<\_ACEOF 3828cat >confcache <<\_ACEOF
3817# This file is a shell script that caches the results of configure 3829# This file is a shell script that caches the results of configure
@@ -4532,6 +4544,7 @@ do
4532 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4544 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4533 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;; 4545 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;;
4534 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;; 4546 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;;
4547 "src/fldd/Makefile") CONFIG_FILES="$CONFIG_FILES src/fldd/Makefile" ;;
4535 4548
4536 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 4549 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
4537 esac 4550 esac
diff --git a/configure.ac b/configure.ac
index 7f9b12d97..09fc3f587 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,7 +177,7 @@ fi
177 177
178AC_OUTPUT(Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile \ 178AC_OUTPUT(Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile \
179src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile \ 179src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile \
180src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile) 180src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile src/fldd/Makefile)
181 181
182echo 182echo
183echo "Configuration options:" 183echo "Configuration options:"
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index dc903962b..19edb40a0 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -49,6 +49,7 @@
49#define RUN_BIN_DIR "/run/firejail/mnt/bin" 49#define RUN_BIN_DIR "/run/firejail/mnt/bin"
50#define RUN_PULSE_DIR "/run/firejail/mnt/pulse" 50#define RUN_PULSE_DIR "/run/firejail/mnt/pulse"
51#define RUN_LIB_DIR "/run/firejail/mnt/lib" 51#define RUN_LIB_DIR "/run/firejail/mnt/lib"
52#define RUN_LIB_FILE "/run/firejail/mnt/libfiles"
52 53
53#define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter 54#define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter
54#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter 55#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter
@@ -739,6 +740,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc,
739#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") 740#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
740#define PATH_FCOPY (LIBDIR "/firejail/fcopy") 741#define PATH_FCOPY (LIBDIR "/firejail/fcopy")
741#define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin" 742#define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin"
743#define PATH_FLDD (LIBDIR "/firejail/fldd")
742 744
743// bitmapped filters for sbox_run 745// bitmapped filters for sbox_run
744#define SBOX_ROOT (1 << 0) // run the sandbox as root 746#define SBOX_ROOT (1 << 0) // run the sandbox as root
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index d86588792..576b4a0df 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -18,156 +18,60 @@
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 <elf.h>
22#include <fcntl.h>
23#include <sys/mman.h>
24#include <sys/mount.h> 21#include <sys/mount.h>
25#include <sys/stat.h> 22#include <sys/stat.h>
26#include <sys/types.h> 23#include <sys/types.h>
27#include <unistd.h> 24#include <unistd.h>
28 25
29#ifdef __LP64__
30#define Elf_Ehdr Elf64_Ehdr
31#define Elf_Phdr Elf64_Phdr
32#define Elf_Shdr Elf64_Shdr
33#define Elf_Dyn Elf64_Dyn
34#else
35#define Elf_Ehdr Elf32_Ehdr
36#define Elf_Phdr Elf32_Phdr
37#define Elf_Shdr Elf32_Shdr
38#define Elf_Dyn Elf32_Dyn
39#endif
40
41static const char * const lib_paths[] = {
42 "/lib",
43 "/lib/x86_64-linux-gnu",
44 "/lib64",
45 "/usr/lib",
46 "/usr/lib/x86_64-linux-gnu",
47 LIBDIR,
48 "/usr/local/lib",
49 NULL
50};
51
52static void copy_libs_for_lib(const char *lib, const char *private_run_dir);
53
54static void duplicate(const char *fname, const char *private_run_dir) { 26static void duplicate(const char *fname, const char *private_run_dir) {
55 if (arg_debug) 27 if (arg_debug)
56 printf("copying %s to private %s\n", fname, private_run_dir); 28 printf("copying %s to private %s\n", fname, private_run_dir);
57 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir); 29 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir);
58} 30}
59 31
60static void copy_libs_for_exe(const char *exe, const char *private_run_dir) { 32static void copy_libs(const char *exe, const char *dir, const char *file) {
61 if (arg_debug) 33 // create an empty RUN_LIB_FILE and allow the user to write to it
62 printf("copy libs for %s\n", exe); 34 unlink(file); // in case is there
63 int f; 35 create_empty_file_as_root(file, 0644);
64 f = open(exe, O_RDONLY); 36 if (chown(file, getuid(), getgid()))
65 if (f < 0) 37 errExit("chown");
66 return; 38
67 struct stat s; 39 // run fldd to extact the list of file
68 char *base = NULL; 40 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, exe, file);
69 if (fstat(f, &s) == -1) 41
70 goto error_close; 42 // open the list of libraries and install them on by one
71 base = mmap(0, s.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, f, 0); 43 FILE *fp = fopen(file, "r");
72 if (base == MAP_FAILED) 44 if (!fp)
73 goto error_close; 45 errExit("fopen");
74 46
75 Elf_Ehdr *ebuf = (Elf_Ehdr *)base; 47#define MAXBUF 4096
76 if (strncmp((const char *)ebuf->e_ident, ELFMAG, SELFMAG) != 0) 48 char buf[MAXBUF];
77 goto close; 49 while (fgets(buf, MAXBUF, fp)) {
78 50 // remove \n
79 Elf_Phdr *pbuf = (Elf_Phdr *)(base + sizeof(*ebuf)); 51 char *ptr = strchr(buf, '\n');
80 while (ebuf->e_phnum-- > 0) { 52 if (ptr)
81 switch (pbuf->p_type) { 53 *ptr = '\0';
82 case PT_INTERP: 54 duplicate(buf, dir);
83 // dynamic loader ld-linux.so
84 duplicate(base + pbuf->p_offset, private_run_dir);
85 break;
86 }
87 pbuf++;
88 }
89
90 Elf_Shdr *sbuf = (Elf_Shdr *)(base + ebuf->e_shoff);
91
92 // Find strings section
93 char *strbase = NULL;
94 int sections = ebuf->e_shnum;
95 while (sections-- > 0) {
96 if (sbuf->sh_type == SHT_STRTAB) {
97 strbase = base + sbuf->sh_offset;
98 break;
99 }
100 sbuf++;
101 } 55 }
102 if (strbase == NULL) 56 fclose(fp);
103 goto error_close;
104
105 // Find dynamic section
106 sections = ebuf->e_shnum;
107 while (sections-- > 0) {
108 if (sbuf->sh_type == SHT_DYNAMIC) {
109 // Find DT_NEEDED tags
110 Elf_Dyn *dbuf = (Elf_Dyn *)(base + sbuf->sh_offset);
111 while (sbuf->sh_size >= sizeof(*dbuf)) {
112 if (dbuf->d_tag == DT_NEEDED) {
113 const char *lib = strbase + dbuf->d_un.d_ptr;
114 copy_libs_for_lib(lib, private_run_dir);
115 }
116 sbuf->sh_size -= sizeof(*dbuf);
117 dbuf++;
118 }
119 }
120 sbuf++;
121 }
122 goto close;
123
124 error_close:
125 perror("copy libs");
126 close:
127 if (base)
128 munmap(base, s.st_size);
129 close(f);
130} 57}
131 58
132static void copy_libs_for_lib(const char *lib, const char *private_run_dir) {
133 int i;
134 for (i = 0; lib_paths[i]; i++) {
135 char *fname;
136 if (asprintf(&fname, "%s/%s", lib_paths[i], lib) == -1)
137 errExit("asprintf");
138 if (access(fname, R_OK) == 0) {
139 char *dst;
140 if (asprintf(&dst, "%s/%s", private_run_dir, lib) == -1)
141 errExit("asprintf");
142
143 if (access(dst, R_OK) != 0) {
144 duplicate(fname, private_run_dir);
145 // libs may need other libs
146 copy_libs_for_exe(fname, private_run_dir);
147 }
148 free(dst);
149 free(fname);
150 return;
151 }
152 free(fname);
153 }
154 errExit("library not found");
155}
156 59
157void fs_private_lib(void) { 60void fs_private_lib(void) {
158 char *private_list = cfg.lib_private_keep; 61// char *private_list = cfg.lib_private_keep;
159 62
160 // create /run/firejail/mnt/lib directory 63 // create /run/firejail/mnt/lib directory
161 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); 64 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0);
162 65
163 // copy the libs in the new lib directory for the main exe 66 // copy the libs in the new lib directory for the main exe
164 if (cfg.original_program_index > 0) 67 if (cfg.original_program_index > 0)
165 copy_libs_for_exe(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR); 68 copy_libs(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE);
166 69
167 // for the shell 70 // for the shell
168 if (!arg_shell_none) 71 if (!arg_shell_none)
169 copy_libs_for_exe(cfg.shell, RUN_LIB_DIR); 72 copy_libs(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE);
170 73
74#if 0 // TODO - work in progress
171 // for the listed libs 75 // for the listed libs
172 if (private_list && *private_list != '\0') { 76 if (private_list && *private_list != '\0') {
173 if (arg_debug) 77 if (arg_debug)
@@ -185,6 +89,7 @@ void fs_private_lib(void) {
185 free(dlist); 89 free(dlist);
186 fs_logger_print(); 90 fs_logger_print();
187 } 91 }
92#endif
188 93
189 // for our trace and tracelog libs 94 // for our trace and tracelog libs
190 if (arg_trace) 95 if (arg_trace)
@@ -194,14 +99,17 @@ void fs_private_lib(void) {
194 99
195 if (arg_debug) 100 if (arg_debug)
196 printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR); 101 printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR);
102
197 if (mount(RUN_LIB_DIR, "/lib", NULL, MS_BIND|MS_REC, NULL) < 0 || 103 if (mount(RUN_LIB_DIR, "/lib", NULL, MS_BIND|MS_REC, NULL) < 0 ||
198 mount(NULL, "/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) 104 mount(NULL, "/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
199 errExit("mount bind"); 105 errExit("mount bind");
200 fs_logger("mount /lib"); 106 fs_logger("mount /lib");
107
201 if (mount(RUN_LIB_DIR, "/lib64", NULL, MS_BIND|MS_REC, NULL) < 0 || 108 if (mount(RUN_LIB_DIR, "/lib64", NULL, MS_BIND|MS_REC, NULL) < 0 ||
202 mount(NULL, "/lib64", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) 109 mount(NULL, "/lib64", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
203 errExit("mount bind"); 110 errExit("mount bind");
204 fs_logger("mount /lib64"); 111 fs_logger("mount /lib64");
112
205 if (mount(RUN_LIB_DIR, "/usr/lib", NULL, MS_BIND|MS_REC, NULL) < 0 || 113 if (mount(RUN_LIB_DIR, "/usr/lib", NULL, MS_BIND|MS_REC, NULL) < 0 ||
206 mount(NULL, "/usr/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) 114 mount(NULL, "/usr/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
207 errExit("mount bind"); 115 errExit("mount bind");