diff options
author | netblue30 <netblue30@yahoo.com> | 2015-12-03 08:45:52 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-12-03 08:45:52 -0500 |
commit | f9021ef8714fee5d4eb30a2329f80eeebaeaf244 (patch) | |
tree | dd8152456b311b5539f6a8d4fb1b2a092737c1bb /src | |
parent | testing (diff) | |
download | firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.gz firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.zst firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.zip |
--tracelog
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs.c | 5 | ||||
-rw-r--r-- | src/firejail/fs_logger.c | 11 | ||||
-rw-r--r-- | src/firejail/fs_trace.c | 8 | ||||
-rw-r--r-- | src/firejail/main.c | 3 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 23 | ||||
-rw-r--r-- | src/libtrace/Makefile.in | 1 | ||||
-rw-r--r-- | src/libtrace/libtrace.c | 2 | ||||
-rw-r--r-- | src/libtracelog/Makefile.in | 25 | ||||
-rw-r--r-- | src/libtracelog/libtracelog.c | 494 |
10 files changed, 559 insertions, 15 deletions
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 | |||
204 | extern char *arg_caps_list; // optional caps list | 204 | extern char *arg_caps_list; // optional caps list |
205 | 205 | ||
206 | extern int arg_trace; // syscall tracing support | 206 | extern int arg_trace; // syscall tracing support |
207 | extern int arg_tracelog; // blacklist tracing support | ||
207 | extern int arg_rlimit_nofile; // rlimit nofile | 208 | extern int arg_rlimit_nofile; // rlimit nofile |
208 | extern int arg_rlimit_nproc; // rlimit nproc | 209 | extern int arg_rlimit_nproc; // rlimit nproc |
209 | extern int arg_rlimit_fsize; // rlimit fsize | 210 | extern int arg_rlimit_fsize; // rlimit fsize |
@@ -483,6 +484,7 @@ void restrict_users(void); | |||
483 | // fs_logger.c | 484 | // fs_logger.c |
484 | void fs_logger(const char *msg); | 485 | void fs_logger(const char *msg); |
485 | void fs_logger2(const char *msg1, const char *msg2); | 486 | void fs_logger2(const char *msg1, const char *msg2); |
487 | void fs_logger2int(const char *msg1, int d); | ||
486 | void fs_logger3(const char *msg1, const char *msg2, const char *msg3); | 488 | void fs_logger3(const char *msg1, const char *msg2, const char *msg3); |
487 | void fs_logger_print(void); | 489 | void fs_logger_print(void); |
488 | void fs_logger_change_owner(void); | 490 | void 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 |
588 | void fs_basic_fs(void) { | 586 | void 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 | ||
73 | void 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 | |||
73 | void fs_logger3(const char *msg1, const char *msg2, const char *msg3) { | 82 | void 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 | |||
67 | char *arg_caps_list = NULL; // optional caps list | 67 | char *arg_caps_list = NULL; // optional caps list |
68 | 68 | ||
69 | int arg_trace = 0; // syscall tracing support | 69 | int arg_trace = 0; // syscall tracing support |
70 | int arg_tracelog = 0; // blacklist tracing support | ||
70 | int arg_rlimit_nofile = 0; // rlimit nofile | 71 | int arg_rlimit_nofile = 0; // rlimit nofile |
71 | int arg_rlimit_nproc = 0; // rlimit nproc | 72 | int arg_rlimit_nproc = 0; // rlimit nproc |
72 | int arg_rlimit_fsize = 0; // rlimit fsize | 73 | int 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 | ||
19 | libtrace.so: $(OBJS) | 18 | libtrace.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); | |||
423 | static orig_stat64_t orig_stat64 = NULL; | 423 | static orig_stat64_t orig_stat64 = NULL; |
424 | int stat64(const char *pathname, struct stat64 *buf) { | 424 | int 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 @@ | |||
1 | PREFIX=@prefix@ | ||
2 | VERSION=@PACKAGE_VERSION@ | ||
3 | NAME=@PACKAGE_NAME@ | ||
4 | HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ | ||
5 | |||
6 | H_FILE_LIST = $(wildcard *.[h]) | ||
7 | C_FILE_LIST = $(wildcard *.c) | ||
8 | OBJS = $(C_FILE_LIST:.c=.o) | ||
9 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
10 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security | ||
11 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now | ||
12 | |||
13 | all: libtracelog.so | ||
14 | |||
15 | %.o : %.c $(H_FILE_LIST) | ||
16 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
17 | |||
18 | libtracelog.so: $(OBJS) | ||
19 | $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl | ||
20 | |||
21 | |||
22 | clean:; rm -f $(OBJS) libtracelog.so | ||
23 | |||
24 | distclean: 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 | ||
38 | typedef FILE *(*orig_fopen_t)(const char *pathname, const char *mode); | ||
39 | static orig_fopen_t orig_fopen = NULL; | ||
40 | typedef FILE *(*orig_fopen64_t)(const char *pathname, const char *mode); | ||
41 | static orig_fopen64_t orig_fopen64 = NULL; | ||
42 | |||
43 | // | ||
44 | // blacklist storage | ||
45 | // | ||
46 | typedef struct list_elem_t { | ||
47 | struct list_elem_t *next; | ||
48 | char *path; | ||
49 | } ListElem; | ||
50 | |||
51 | static ListElem *storage; | ||
52 | |||
53 | static 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 | |||
68 | static 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 | ||
97 | static int blacklist_loaded = 0; | ||
98 | static char *sandbox_pid_str = 0; | ||
99 | static char *sandbox_name_str = NULL; | ||
100 | void 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 | |||
141 | static 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 | // | ||
159 | static pid_t mypid = 0; | ||
160 | static 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 | ||
170 | static char myname[MAXNAME]; | ||
171 | static int nameinit = 0; | ||
172 | static 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 | ||
213 | typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode); | ||
214 | static orig_open_t orig_open = NULL; | ||
215 | int 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 | |||
228 | typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode); | ||
229 | static orig_open64_t orig_open64 = NULL; | ||
230 | int 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 | ||
243 | typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
244 | static orig_openat_t orig_openat = NULL; | ||
245 | int 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 | |||
257 | typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
258 | static orig_openat64_t orig_openat64 = NULL; | ||
259 | int 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 | ||
273 | FILE *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__ | ||
286 | FILE *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 | ||
301 | typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream); | ||
302 | static orig_freopen_t orig_freopen = NULL; | ||
303 | FILE *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__ | ||
316 | typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream); | ||
317 | static orig_freopen64_t orig_freopen64 = NULL; | ||
318 | FILE *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 | ||
332 | typedef int (*orig_unlink_t)(const char *pathname); | ||
333 | static orig_unlink_t orig_unlink = NULL; | ||
334 | int 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 | |||
346 | typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags); | ||
347 | static orig_unlinkat_t orig_unlinkat = NULL; | ||
348 | int 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 | ||
361 | typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode); | ||
362 | static orig_mkdir_t orig_mkdir = NULL; | ||
363 | int 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 | |||
375 | typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode); | ||
376 | static orig_mkdirat_t orig_mkdirat = NULL; | ||
377 | int 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 | |||
389 | typedef int (*orig_rmdir_t)(const char *pathname); | ||
390 | static orig_rmdir_t orig_rmdir = NULL; | ||
391 | int 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 | ||
404 | typedef int (*orig_stat_t)(const char *pathname, struct stat *buf); | ||
405 | static orig_stat_t orig_stat = NULL; | ||
406 | int 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__ | ||
419 | typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); | ||
420 | static orig_stat64_t orig_stat64 = NULL; | ||
421 | int 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 | |||
434 | typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf); | ||
435 | static orig_lstat_t orig_lstat = NULL; | ||
436 | int 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__ | ||
449 | typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf); | ||
450 | static orig_lstat64_t orig_lstat64 = NULL; | ||
451 | int 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 | ||
465 | typedef int (*orig_access_t)(const char *pathname, int mode); | ||
466 | static orig_access_t orig_access = NULL; | ||
467 | int 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 | ||
480 | typedef DIR *(*orig_opendir_t)(const char *pathname); | ||
481 | static orig_opendir_t orig_opendir = NULL; | ||
482 | DIR *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 | |||