aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-08-03 13:52:42 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-08-03 13:52:42 -0400
commit0823eebfb6fc3c972d2a591ddae2ec4e668c95ff (patch)
tree9224fe3a972fe19bf8ba628c709b1f0020c0db0b /src
parentMerge pull request #1426 from VladimirSchowalter20/master (diff)
downloadfirejail-0823eebfb6fc3c972d2a591ddae2ec4e668c95ff.tar.gz
firejail-0823eebfb6fc3c972d2a591ddae2ec4e668c95ff.tar.zst
firejail-0823eebfb6fc3c972d2a591ddae2ec4e668c95ff.zip
private-lib: split fldd as a separate application
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_lib.c156
2 files changed, 34 insertions, 124 deletions
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");