aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2015-12-03 08:45:52 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2015-12-03 08:45:52 -0500
commitf9021ef8714fee5d4eb30a2329f80eeebaeaf244 (patch)
treedd8152456b311b5539f6a8d4fb1b2a092737c1bb
parenttesting (diff)
downloadfirejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.gz
firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.zst
firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.zip
--tracelog
-rw-r--r--Makefile.in4
-rw-r--r--RELNOTES3
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac2
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs.c5
-rw-r--r--src/firejail/fs_logger.c11
-rw-r--r--src/firejail/fs_trace.c8
-rw-r--r--src/firejail/main.c3
-rw-r--r--src/firejail/sandbox.c23
-rw-r--r--src/libtrace/Makefile.in1
-rw-r--r--src/libtrace/libtrace.c2
-rw-r--r--src/libtracelog/Makefile.in25
-rw-r--r--src/libtracelog/libtracelog.c494
14 files changed, 566 insertions, 20 deletions
diff --git a/Makefile.in b/Makefile.in
index b7629a9e5..59fe34f60 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
1all: apps firejail.1 firemon.1 firejail-profile.5 firejail-login.5 1all: apps firejail.1 firemon.1 firejail-profile.5 firejail-login.5
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/libtrace src/ftee 3APPS = src/firejail src/firemon src/libtrace src/libtracelog src/ftee
4 4
5prefix=@prefix@ 5prefix=@prefix@
6exec_prefix=@exec_prefix@ 6exec_prefix=@exec_prefix@
@@ -62,6 +62,7 @@ realinstall:
62 # libraries and plugins 62 # libraries and plugins
63 mkdir -p $(DESTDIR)/$(libdir)/firejail 63 mkdir -p $(DESTDIR)/$(libdir)/firejail
64 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/. 64 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/.
65 install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/.
65 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/. 66 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/.
66 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. 67 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/.
67 # documents 68 # documents
@@ -157,6 +158,7 @@ install-strip: all
157 strip src/firejail/firejail 158 strip src/firejail/firejail
158 strip src/firemon/firemon 159 strip src/firemon/firemon
159 strip src/libtrace/libtrace.so 160 strip src/libtrace/libtrace.so
161 strip src/libtracelog/libtracelog.so
160 strip src/ftee/ftee 162 strip src/ftee/ftee
161 $(MAKE) realinstall 163 $(MAKE) realinstall
162 164
diff --git a/RELNOTES b/RELNOTES
index c6584371d..f3fd16f57 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -9,8 +9,7 @@ firejail (0.9.35) baseline; urgency=low
9 * added opera-beta profile 9 * added opera-beta profile
10 * added --noblacklist option 10 * added --noblacklist option
11 * whitelist command enhancements 11 * whitelist command enhancements
12 * prevent leaking user information by modifying /home directory, 12 * prevent user name enumeration
13 /etc/passwd and /etc/group
14 * added /etc/firejail/nolocal.net network filter 13 * added /etc/firejail/nolocal.net network filter
15 * added /etc/firejail/webserver.net network filter 14 * added /etc/firejail/webserver.net network filter
16 * manipulation of firejail configuration disabled by default 15 * manipulation of firejail configuration disabled by default
diff --git a/configure b/configure
index fe05f2a80..463dc31c4 100755
--- a/configure
+++ b/configure
@@ -3563,7 +3563,7 @@ if test "$prefix" = /usr; then
3563 sysconfdir="/etc" 3563 sysconfdir="/etc"
3564fi 3564fi
3565 3565
3566ac_config_files="$ac_config_files Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/ftee/Makefile" 3566ac_config_files="$ac_config_files Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/ftee/Makefile"
3567 3567
3568cat >confcache <<\_ACEOF 3568cat >confcache <<\_ACEOF
3569# This file is a shell script that caches the results of configure 3569# This file is a shell script that caches the results of configure
@@ -4277,6 +4277,7 @@ do
4277 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; 4277 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;;
4278 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; 4278 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;;
4279 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; 4279 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;;
4280 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;;
4280 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4281 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4281 4282
4282 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 4283 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
diff --git a/configure.ac b/configure.ac
index f7db96ee7..b5b59d1e4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,7 +52,7 @@ if test "$prefix" = /usr; then
52 sysconfdir="/etc" 52 sysconfdir="/etc"
53fi 53fi
54 54
55AC_OUTPUT(Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/ftee/Makefile) 55AC_OUTPUT(Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/ftee/Makefile)
56 56
57echo 57echo
58echo "Configuration options:" 58echo "Configuration options:"
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index b50b4d19e..967eb7e45 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -204,6 +204,7 @@ extern int arg_caps_keep; // keep list
204extern char *arg_caps_list; // optional caps list 204extern char *arg_caps_list; // optional caps list
205 205
206extern int arg_trace; // syscall tracing support 206extern int arg_trace; // syscall tracing support
207extern int arg_tracelog; // blacklist tracing support
207extern int arg_rlimit_nofile; // rlimit nofile 208extern int arg_rlimit_nofile; // rlimit nofile
208extern int arg_rlimit_nproc; // rlimit nproc 209extern int arg_rlimit_nproc; // rlimit nproc
209extern int arg_rlimit_fsize; // rlimit fsize 210extern int arg_rlimit_fsize; // rlimit fsize
@@ -483,6 +484,7 @@ void restrict_users(void);
483// fs_logger.c 484// fs_logger.c
484void fs_logger(const char *msg); 485void fs_logger(const char *msg);
485void fs_logger2(const char *msg1, const char *msg2); 486void fs_logger2(const char *msg1, const char *msg2);
487void fs_logger2int(const char *msg1, int d);
486void fs_logger3(const char *msg1, const char *msg2, const char *msg3); 488void fs_logger3(const char *msg1, const char *msg2, const char *msg3);
487void fs_logger_print(void); 489void fs_logger_print(void);
488void fs_logger_change_owner(void); 490void fs_logger_change_owner(void);
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 1e01ccc71..ebeaf51c7 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -480,8 +480,6 @@ void fs_proc_sys_dev_boot(void) {
480 else 480 else
481 fs_logger("remount /sys"); 481 fs_logger("remount /sys");
482 482
483
484
485 if (stat("/sys/firmware", &s) == 0) { 483 if (stat("/sys/firmware", &s) == 0) {
486 disable_file(BLACKLIST_FILE, "/sys/firmware"); 484 disable_file(BLACKLIST_FILE, "/sys/firmware");
487 } 485 }
@@ -587,11 +585,12 @@ static void disable_firejail_config(void) {
587// build a basic read-only filesystem 585// build a basic read-only filesystem
588void fs_basic_fs(void) { 586void fs_basic_fs(void) {
589 if (arg_debug) 587 if (arg_debug)
590 printf("Mounting read-only /bin, /sbin, /lib, /lib64, /usr, /etc, /var\n"); 588 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr, /etc, /var\n");
591 fs_rdonly("/bin"); 589 fs_rdonly("/bin");
592 fs_rdonly("/sbin"); 590 fs_rdonly("/sbin");
593 fs_rdonly("/lib"); 591 fs_rdonly("/lib");
594 fs_rdonly("/lib64"); 592 fs_rdonly("/lib64");
593 fs_rdonly("/lib32");
595 fs_rdonly("/usr"); 594 fs_rdonly("/usr");
596 fs_rdonly("/etc"); 595 fs_rdonly("/etc");
597 fs_rdonly("/var"); 596 fs_rdonly("/var");
diff --git a/src/firejail/fs_logger.c b/src/firejail/fs_logger.c
index 9f742c5bd..bf7322984 100644
--- a/src/firejail/fs_logger.c
+++ b/src/firejail/fs_logger.c
@@ -70,6 +70,15 @@ void fs_logger2(const char *msg1, const char *msg2) {
70 insertmsg(ptr); 70 insertmsg(ptr);
71} 71}
72 72
73void fs_logger2int(const char *msg1, int d) {
74 FsMsg *ptr = newmsg();
75 char *str;
76 if (asprintf(&str, "%s %d", msg1, d) == -1)
77 errExit("asprintf");
78 ptr->msg = str;
79 insertmsg(ptr);
80}
81
73void fs_logger3(const char *msg1, const char *msg2, const char *msg3) { 82void fs_logger3(const char *msg1, const char *msg2, const char *msg3) {
74 FsMsg *ptr = newmsg(); 83 FsMsg *ptr = newmsg();
75 char *str; 84 char *str;
@@ -91,7 +100,7 @@ void fs_logger_print(void) {
91 100
92 int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid()); 101 int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid());
93 (void) rv; // best effort! 102 (void) rv; // best effort!
94 rv = chmod(RUN_FSLOGGER_FILE, 0600); 103 rv = chmod(RUN_FSLOGGER_FILE, 0644);
95 (void) rv; // best effort! 104 (void) rv; // best effort!
96 105
97 FsMsg *ptr = head; 106 FsMsg *ptr = head;
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index 92e4daed2..f555a6693 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -57,7 +57,13 @@ void fs_trace(void) {
57 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "w"); 57 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "w");
58 if (!fp) 58 if (!fp)
59 errExit("fopen"); 59 errExit("fopen");
60 fprintf(fp, "%s/firejail/libtrace.so\n", LIBDIR); 60 if (arg_trace)
61 fprintf(fp, "%s/firejail/libtrace.so\n", LIBDIR);
62 else if (arg_tracelog)
63 fprintf(fp, "%s/firejail/libtracelog.so\n", LIBDIR);
64 else
65 assert(0);
66
61 fclose(fp); 67 fclose(fp);
62 if (chown(RUN_LDPRELOAD_FILE, 0, 0) < 0) 68 if (chown(RUN_LDPRELOAD_FILE, 0, 0) < 0)
63 errExit("chown"); 69 errExit("chown");
diff --git a/src/firejail/main.c b/src/firejail/main.c
index db9964e98..c1cd9564e 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -67,6 +67,7 @@ int arg_caps_keep = 0; // keep list
67char *arg_caps_list = NULL; // optional caps list 67char *arg_caps_list = NULL; // optional caps list
68 68
69int arg_trace = 0; // syscall tracing support 69int arg_trace = 0; // syscall tracing support
70int arg_tracelog = 0; // blacklist tracing support
70int arg_rlimit_nofile = 0; // rlimit nofile 71int arg_rlimit_nofile = 0; // rlimit nofile
71int arg_rlimit_nproc = 0; // rlimit nproc 72int arg_rlimit_nproc = 0; // rlimit nproc
72int arg_rlimit_fsize = 0; // rlimit fsize 73int arg_rlimit_fsize = 0; // rlimit fsize
@@ -571,6 +572,8 @@ int main(int argc, char **argv) {
571 572
572 else if (strcmp(argv[i], "--trace") == 0) 573 else if (strcmp(argv[i], "--trace") == 0)
573 arg_trace = 1; 574 arg_trace = 1;
575 else if (strcmp(argv[i], "--tracelog") == 0)
576 arg_tracelog = 1;
574 else if (strncmp(argv[i], "--rlimit-nofile=", 16) == 0) { 577 else if (strncmp(argv[i], "--rlimit-nofile=", 16) == 0) {
575 if (not_unsigned(argv[i] + 16)) { 578 if (not_unsigned(argv[i] + 16)) {
576 fprintf(stderr, "Error: invalid rlimt nofile\n"); 579 fprintf(stderr, "Error: invalid rlimt nofile\n");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index af035fe90..39f95a43a 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -265,19 +265,26 @@ int sandbox(void* sandbox_arg) {
265 } 265 }
266 266
267 //**************************** 267 //****************************
268 // mount namespace and log filesystem type 268 // mount namespace
269 //**************************** 269 //****************************
270 // mount events are not forwarded between the host the sandbox 270 // mount events are not forwarded between the host the sandbox
271 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { 271 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
272 chk_chroot(); 272 chk_chroot();
273 } 273 }
274 // log filesystem type 274
275
276 //****************************
277 // log sandbox data
278 //****************************
279 fs_logger2int("sandbox pid:", (int) sandbox_pid);
280 if (cfg.name)
281 fs_logger2("sandbox name:", cfg.name);
275 if (cfg.chrootdir) 282 if (cfg.chrootdir)
276 fs_logger("chroot filesystem"); 283 fs_logger("sandbox filesystem: chroot");
277 else if (arg_overlay) 284 else if (arg_overlay)
278 fs_logger("overlay filesystem"); 285 fs_logger("sandbox filesystem: overlay");
279 else 286 else
280 fs_logger("local filesystem"); 287 fs_logger("sandbox filesystem: local");
281 fs_logger("install mount namespace"); 288 fs_logger("install mount namespace");
282 289
283 //**************************** 290 //****************************
@@ -298,7 +305,7 @@ int sandbox(void* sandbox_arg) {
298 fs_build_cp_command(); 305 fs_build_cp_command();
299 306
300 // trace pre-install 307 // trace pre-install
301 if (arg_trace) 308 if (arg_trace || arg_tracelog)
302 fs_trace_preload(); 309 fs_trace_preload();
303 310
304 //**************************** 311 //****************************
@@ -341,7 +348,7 @@ int sandbox(void* sandbox_arg) {
341 //**************************** 348 //****************************
342 // trace pre-install, this time inside chroot 349 // trace pre-install, this time inside chroot
343 //**************************** 350 //****************************
344 if (arg_trace) 351 if (arg_trace || arg_tracelog)
345 fs_trace_preload(); 352 fs_trace_preload();
346 } 353 }
347 else 354 else
@@ -392,7 +399,7 @@ int sandbox(void* sandbox_arg) {
392 //**************************** 399 //****************************
393 // install trace 400 // install trace
394 //**************************** 401 //****************************
395 if (arg_trace) 402 if (arg_trace || arg_tracelog)
396 fs_trace(); 403 fs_trace();
397 404
398 //**************************** 405 //****************************
diff --git a/src/libtrace/Makefile.in b/src/libtrace/Makefile.in
index 3924bdf3f..6917127b0 100644
--- a/src/libtrace/Makefile.in
+++ b/src/libtrace/Makefile.in
@@ -15,7 +15,6 @@ all: libtrace.so
15%.o : %.c $(H_FILE_LIST) 15%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17 17
18# gcc -shared -fPIC -ldl traceopen.c -o traceopen.so
19libtrace.so: $(OBJS) 18libtrace.so: $(OBJS)
20 $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl 19 $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl
21 20
diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c
index 9dad3859e..3db931de1 100644
--- a/src/libtrace/libtrace.c
+++ b/src/libtrace/libtrace.c
@@ -423,7 +423,7 @@ typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf);
423static orig_stat64_t orig_stat64 = NULL; 423static orig_stat64_t orig_stat64 = NULL;
424int stat64(const char *pathname, struct stat64 *buf) { 424int stat64(const char *pathname, struct stat64 *buf) {
425 if (!orig_stat) 425 if (!orig_stat)
426 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat"); 426 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
427 427
428 int rv = orig_stat64(pathname, buf); 428 int rv = orig_stat64(pathname, buf);
429 printf("%u:%s:stat %s:%d\n", pid(), name(), pathname, rv); 429 printf("%u:%s:stat %s:%d\n", pid(), name(), pathname, rv);
diff --git a/src/libtracelog/Makefile.in b/src/libtracelog/Makefile.in
new file mode 100644
index 000000000..8f6c161ab
--- /dev/null
+++ b/src/libtracelog/Makefile.in
@@ -0,0 +1,25 @@
1PREFIX=@prefix@
2VERSION=@PACKAGE_VERSION@
3NAME=@PACKAGE_NAME@
4HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
5
6H_FILE_LIST = $(wildcard *.[h])
7C_FILE_LIST = $(wildcard *.c)
8OBJS = $(C_FILE_LIST:.c=.o)
9BINOBJS = $(foreach file, $(OBJS), $file)
10CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security
11LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now
12
13all: libtracelog.so
14
15%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17
18libtracelog.so: $(OBJS)
19 $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl
20
21
22clean:; rm -f $(OBJS) libtracelog.so
23
24distclean: clean
25 rm -fr Makefile
diff --git a/src/libtracelog/libtracelog.c b/src/libtracelog/libtracelog.c
new file mode 100644
index 000000000..c3bbc132b
--- /dev/null
+++ b/src/libtracelog/libtracelog.c
@@ -0,0 +1,494 @@
1/*
2 * Copyright (C) 2014, 2015 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#define _GNU_SOURCE
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <dlfcn.h>
25#include <sys/types.h>
26#include <unistd.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <sys/un.h>
31#include <sys/stat.h>
32#include <syslog.h>
33#include <dirent.h>
34
35
36
37// break recursivity on fopen call
38typedef FILE *(*orig_fopen_t)(const char *pathname, const char *mode);
39static orig_fopen_t orig_fopen = NULL;
40typedef FILE *(*orig_fopen64_t)(const char *pathname, const char *mode);
41static orig_fopen64_t orig_fopen64 = NULL;
42
43//
44// blacklist storage
45//
46typedef struct list_elem_t {
47 struct list_elem_t *next;
48 char *path;
49} ListElem;
50
51static ListElem *storage;
52
53static storage_add(const char *str) {
54 ListElem *ptr = malloc(sizeof(ListElem));
55 if (!ptr) {
56 fprintf(stderr, "Error: cannot allocate memory\n");
57 return;
58 }
59 ptr->path = strdup(str);
60 if (!ptr->path) {
61 fprintf(stderr, "Error: cannot allocate memory\n");
62 return;
63 }
64 ptr->next = storage;
65 storage = ptr;
66}
67
68static char *storage_find(const char *str) {
69 const char *tofind = str;
70 int allocated = 0;
71
72 if (strstr(str, "..") || strstr(str, "/./")) {
73 tofind = realpath(str, NULL);
74 allocated = 1;
75 }
76
77 ListElem *ptr = storage;
78 while (ptr) {
79 if (strcmp(tofind, ptr->path) == 0) {
80 if (allocated)
81 free((char *) tofind);
82 return ptr->path;
83 }
84 ptr = ptr->next;
85 }
86
87 if (allocated)
88 free((char *) tofind);
89 return NULL;
90}
91
92//
93// load blacklistst form /run/firejail/mnt/fslogger
94//
95#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
96#define MAXBUF 4096
97static int blacklist_loaded = 0;
98static char *sandbox_pid_str = 0;
99static char *sandbox_name_str = NULL;
100void load_blacklist(void) {
101 if (blacklist_loaded)
102 return;
103
104 // open filesystem log
105 if (!orig_fopen)
106 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
107 FILE *fp = orig_fopen(RUN_FSLOGGER_FILE, "r");
108 if (!fp)
109 return;
110
111 // extract blacklists
112 char buf[MAXBUF];
113 int cnt = 0;
114 while (fgets(buf, MAXBUF, fp)) {
115 if (strncmp(buf, "sandbox pid: ", 13) == 0) {
116 char *ptr = strchr(buf, '\n');
117 if (ptr)
118 *ptr = '\0';
119 sandbox_pid_str = strdup(buf + 13);
120 }
121 else if (strncmp(buf, "sandbox name: ", 14) == 0) {
122 char *ptr = strchr(buf, '\n');
123 if (ptr)
124 *ptr = '\0';
125 sandbox_name_str = strdup(buf + 14);
126 }
127 else if (strncmp(buf, "blacklist ", 10) == 0) {
128 char *ptr = strchr(buf, '\n');
129 if (ptr)
130 *ptr = '\0';
131 storage_add(buf + 10);
132 cnt++;
133 }
134 }
135 fclose(fp);
136 blacklist_loaded = 1;
137 printf("Monitoring %d blacklists\n", cnt);
138}
139
140
141static void sendlog(const char *name, const char *call, const char *path) {
142 openlog ("firejail", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
143 if (sandbox_pid_str && sandbox_name_str)
144 syslog (LOG_INFO, "blacklist violation - sandbox %s, name %s, exe %s, syscall %s, path %s",
145 sandbox_pid_str, sandbox_name_str, name, call, path);
146 else if (sandbox_pid_str)
147 syslog (LOG_INFO, "blacklist violation - sandbox %s, exe %s, syscall %s, path %s",
148 sandbox_pid_str, name, call, path);
149 else
150 syslog (LOG_INFO, "blacklist violation - exe %s, syscall %s, path %s",
151 name, call, path);
152 closelog ();
153}
154
155
156//
157// pid
158//
159static pid_t mypid = 0;
160static inline pid_t pid(void) {
161 if (!mypid)
162 mypid = getpid();
163 return mypid;
164}
165
166//
167// process name
168//
169#define MAXNAME 16
170static char myname[MAXNAME];
171static int nameinit = 0;
172static char *name(void) {
173 if (!nameinit) {
174
175 // initialize the name of the process based on /proc/PID/comm
176 memset(myname, 0, MAXNAME);
177
178 pid_t p = pid();
179 char *fname;
180 if (asprintf(&fname, "/proc/%u/comm", p) == -1)
181 return "unknown";
182
183 // read file
184 if (!orig_fopen)
185 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
186 FILE *fp = orig_fopen(fname, "r");
187 if (!fp)
188 return "unknown";
189 if (fgets(myname, MAXNAME, fp) == NULL) {
190 fclose(fp);
191 free(fname);
192 return "unknown";
193 }
194
195 // clean '\n'
196 char *ptr = strchr(myname, '\n');
197 if (ptr)
198 *ptr = '\0';
199
200 fclose(fp);
201 free(fname);
202 nameinit = 1;
203 }
204
205 return myname;
206}
207
208//
209// syscalls
210//
211
212// open
213typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode);
214static orig_open_t orig_open = NULL;
215int open(const char *pathname, int flags, mode_t mode) {
216 if (!orig_open)
217 orig_open = (orig_open_t)dlsym(RTLD_NEXT, "open");
218
219 if (!storage)
220 load_blacklist();
221
222 int rv = orig_open(pathname, flags, mode);
223 if (storage_find(pathname))
224 sendlog(name(), __FUNCTION__, pathname);
225 return rv;
226}
227
228typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode);
229static orig_open64_t orig_open64 = NULL;
230int open64(const char *pathname, int flags, mode_t mode) {
231 if (!orig_open64)
232 orig_open64 = (orig_open64_t)dlsym(RTLD_NEXT, "open64");
233 if (!storage)
234 load_blacklist();
235
236 int rv = orig_open64(pathname, flags, mode);
237 if (storage_find(pathname))
238 sendlog(name(), __FUNCTION__, pathname);
239 return rv;
240}
241
242// openat
243typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode);
244static orig_openat_t orig_openat = NULL;
245int openat(int dirfd, const char *pathname, int flags, mode_t mode) {
246 if (!orig_openat)
247 orig_openat = (orig_openat_t)dlsym(RTLD_NEXT, "openat");
248 if (!storage)
249 load_blacklist();
250
251 int rv = orig_openat(dirfd, pathname, flags, mode);
252 if (storage_find(pathname))
253 sendlog(name(), __FUNCTION__, pathname);
254 return rv;
255}
256
257typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode);
258static orig_openat64_t orig_openat64 = NULL;
259int openat64(int dirfd, const char *pathname, int flags, mode_t mode) {
260 if (!orig_openat64)
261 orig_openat64 = (orig_openat64_t)dlsym(RTLD_NEXT, "openat64");
262 if (!storage)
263 load_blacklist();
264
265 int rv = orig_openat64(dirfd, pathname, flags, mode);
266 if (storage_find(pathname))
267 sendlog(name(), __FUNCTION__, pathname);
268 return rv;
269}
270
271
272// fopen
273FILE *fopen(const char *pathname, const char *mode) {
274 if (!orig_fopen)
275 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
276 if (!storage)
277 load_blacklist();
278
279 FILE *rv = orig_fopen(pathname, mode);
280 if (storage_find(pathname))
281 sendlog(name(), __FUNCTION__, pathname);
282 return rv;
283}
284
285#ifdef __GLIBC__
286FILE *fopen64(const char *pathname, const char *mode) {
287 if (!orig_fopen64)
288 orig_fopen64 = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen64");
289 if (!storage)
290 load_blacklist();
291
292 FILE *rv = orig_fopen64(pathname, mode);
293 if (storage_find(pathname))
294 sendlog(name(), __FUNCTION__, pathname);
295 return rv;
296}
297#endif /* __GLIBC__ */
298
299
300// freopen
301typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream);
302static orig_freopen_t orig_freopen = NULL;
303FILE *freopen(const char *pathname, const char *mode, FILE *stream) {
304 if (!orig_freopen)
305 orig_freopen = (orig_freopen_t)dlsym(RTLD_NEXT, "freopen");
306 if (!storage)
307 load_blacklist();
308
309 FILE *rv = orig_freopen(pathname, mode, stream);
310 if (storage_find(pathname))
311 sendlog(name(), __FUNCTION__, pathname);
312 return rv;
313}
314
315#ifdef __GLIBC__
316typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream);
317static orig_freopen64_t orig_freopen64 = NULL;
318FILE *freopen64(const char *pathname, const char *mode, FILE *stream) {
319 if (!orig_freopen64)
320 orig_freopen64 = (orig_freopen64_t)dlsym(RTLD_NEXT, "freopen64");
321 if (!storage)
322 load_blacklist();
323
324 FILE *rv = orig_freopen64(pathname, mode, stream);
325 if (storage_find(pathname))
326 sendlog(name(), __FUNCTION__, pathname);
327 return rv;
328}
329#endif /* __GLIBC__ */
330
331// unlink
332typedef int (*orig_unlink_t)(const char *pathname);
333static orig_unlink_t orig_unlink = NULL;
334int unlink(const char *pathname) {
335 if (!orig_unlink)
336 orig_unlink = (orig_unlink_t)dlsym(RTLD_NEXT, "unlink");
337 if (!storage)
338 load_blacklist();
339
340 int rv = orig_unlink(pathname);
341 if (storage_find(pathname))
342 sendlog(name(), __FUNCTION__, pathname);
343 return rv;
344}
345
346typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags);
347static orig_unlinkat_t orig_unlinkat = NULL;
348int unlinkat(int dirfd, const char *pathname, int flags) {
349 if (!orig_unlinkat)
350 orig_unlinkat = (orig_unlinkat_t)dlsym(RTLD_NEXT, "unlinkat");
351 if (!storage)
352 load_blacklist();
353
354 int rv = orig_unlinkat(dirfd, pathname, flags);
355 if (storage_find(pathname))
356 sendlog(name(), __FUNCTION__, pathname);
357 return rv;
358}
359
360// mkdir/mkdirat/rmdir
361typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode);
362static orig_mkdir_t orig_mkdir = NULL;
363int mkdir(const char *pathname, mode_t mode) {
364 if (!orig_mkdir)
365 orig_mkdir = (orig_mkdir_t)dlsym(RTLD_NEXT, "mkdir");
366 if (!storage)
367 load_blacklist();
368
369 int rv = orig_mkdir(pathname, mode);
370 if (storage_find(pathname))
371 sendlog(name(), __FUNCTION__, pathname);
372 return rv;
373}
374
375typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode);
376static orig_mkdirat_t orig_mkdirat = NULL;
377int mkdirat(int dirfd, const char *pathname, mode_t mode) {
378 if (!orig_mkdirat)
379 orig_mkdirat = (orig_mkdirat_t)dlsym(RTLD_NEXT, "mkdirat");
380 if (!storage)
381 load_blacklist();
382
383 int rv = orig_mkdirat(dirfd, pathname, mode);
384 if (storage_find(pathname))
385 sendlog(name(), __FUNCTION__, pathname);
386 return rv;
387}
388
389typedef int (*orig_rmdir_t)(const char *pathname);
390static orig_rmdir_t orig_rmdir = NULL;
391int rmdir(const char *pathname) {
392 if (!orig_rmdir)
393 orig_rmdir = (orig_rmdir_t)dlsym(RTLD_NEXT, "rmdir");
394 if (!storage)
395 load_blacklist();
396
397 int rv = orig_rmdir(pathname);
398 if (storage_find(pathname))
399 sendlog(name(), __FUNCTION__, pathname);
400 return rv;
401}
402
403// stat
404typedef int (*orig_stat_t)(const char *pathname, struct stat *buf);
405static orig_stat_t orig_stat = NULL;
406int stat(const char *pathname, struct stat *buf) {
407 if (!orig_stat)
408 orig_stat = (orig_stat_t)dlsym(RTLD_NEXT, "stat");
409 if (!storage)
410 load_blacklist();
411
412 int rv = orig_stat(pathname, buf);
413 if (storage_find(pathname))
414 sendlog(name(), __FUNCTION__, pathname);
415 return rv;
416}
417
418#ifdef __GLIBC__
419typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf);
420static orig_stat64_t orig_stat64 = NULL;
421int stat64(const char *pathname, struct stat64 *buf) {
422 if (!orig_stat)
423 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
424 if (!storage)
425 load_blacklist();
426
427 int rv = orig_stat64(pathname, buf);
428 if (storage_find(pathname))
429 sendlog(name(), __FUNCTION__, pathname);
430 return rv;
431}
432#endif /* __GLIBC__ */
433
434typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf);
435static orig_lstat_t orig_lstat = NULL;
436int lstat(const char *pathname, struct stat *buf) {
437 if (!orig_lstat)
438 orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat");
439 if (!storage)
440 load_blacklist();
441
442 int rv = orig_lstat(pathname, buf);
443 if (storage_find(pathname))
444 sendlog(name(), __FUNCTION__, pathname);
445 return rv;
446}
447
448#ifdef __GLIBC__
449typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf);
450static orig_lstat64_t orig_lstat64 = NULL;
451int lstat64(const char *pathname, struct stat64 *buf) {
452 if (!orig_lstat)
453 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64");
454 if (!storage)
455 load_blacklist();
456
457 int rv = orig_lstat64(pathname, buf);
458 if (storage_find(pathname))
459 sendlog(name(), __FUNCTION__, pathname);
460 return rv;
461}
462#endif /* __GLIBC__ */
463
464// access
465typedef int (*orig_access_t)(const char *pathname, int mode);
466static orig_access_t orig_access = NULL;
467int access(const char *pathname, int mode) {
468 if (!orig_access)
469 orig_access = (orig_access_t)dlsym(RTLD_NEXT, "access");
470 if (!storage)
471 load_blacklist();
472
473 int rv = orig_access(pathname, mode);
474 if (storage_find(pathname))
475 sendlog(name(), __FUNCTION__, pathname);
476 return rv;
477}
478
479// opendir
480typedef DIR *(*orig_opendir_t)(const char *pathname);
481static orig_opendir_t orig_opendir = NULL;
482DIR *opendir(const char *pathname) {
483 if (!orig_opendir)
484 orig_opendir = (orig_opendir_t)dlsym(RTLD_NEXT, "opendir");
485 if (!storage)
486 load_blacklist();
487
488 DIR *rv = orig_opendir(pathname);
489 if (storage_find(pathname))
490 sendlog(name(), __FUNCTION__, pathname);
491 return rv;
492}
493
494