diff options
-rw-r--r-- | Makefile.in | 8 | ||||
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/firejail/fs_trace.c | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 9 | ||||
-rw-r--r-- | src/firejail/output.c | 109 | ||||
-rw-r--r-- | src/firejail/profile.c | 2 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 5 | ||||
-rw-r--r-- | src/ftee/Makefile.in | 14 | ||||
-rw-r--r-- | src/ftee/ftee.h | 24 | ||||
-rw-r--r-- | src/ftee/main.c | 245 | ||||
-rw-r--r-- | src/libtrace/Makefile.in | 26 | ||||
-rw-r--r-- | src/libtrace/libtrace.c | 692 | ||||
-rw-r--r-- | src/libtracelog/Makefile.in | 26 | ||||
-rw-r--r-- | src/libtracelog/libtracelog.c | 704 | ||||
-rw-r--r-- | status | 5 |
16 files changed, 24 insertions, 1856 deletions
diff --git a/Makefile.in b/Makefile.in index 7067bea22..03dba1f61 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,6 +1,6 @@ | |||
1 | all: apps man filters | 1 | all: apps man filters |
2 | MYLIBS = src/lib | 2 | MYLIBS = src/lib |
3 | APPS = src/firejail src/firemon src/fsec-print src/fsec-optimize src/firecfg src/fnetfilter src/libtrace src/libtracelog src/ftee src/fnet src/fseccomp src/libpostexecseccomp | 3 | APPS = src/firejail src/firemon src/fsec-print src/fsec-optimize src/firecfg src/fnetfilter src/fnet src/fseccomp src/libpostexecseccomp |
4 | MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5 | 4 | MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5 |
5 | SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx | 5 | SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx |
6 | 6 | ||
@@ -86,10 +86,7 @@ endif | |||
86 | install -c -m 0755 src/firecfg/firecfg $(DESTDIR)/$(bindir)/. | 86 | install -c -m 0755 src/firecfg/firecfg $(DESTDIR)/$(bindir)/. |
87 | # libraries and plugins | 87 | # libraries and plugins |
88 | install -m 0755 -d $(DESTDIR)/$(libdir)/firejail | 88 | install -m 0755 -d $(DESTDIR)/$(libdir)/firejail |
89 | install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/. | ||
90 | install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/. | ||
91 | install -c -m 0644 src/libpostexecseccomp/libpostexecseccomp.so $(DESTDIR)/$(libdir)/firejail/. | 89 | install -c -m 0644 src/libpostexecseccomp/libpostexecseccomp.so $(DESTDIR)/$(libdir)/firejail/. |
92 | install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/. | ||
93 | install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. | 90 | install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. |
94 | 91 | ||
95 | install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. | 92 | install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. |
@@ -150,10 +147,7 @@ install-strip: all | |||
150 | strip src/firejail/firejail | 147 | strip src/firejail/firejail |
151 | strip src/firemon/firemon | 148 | strip src/firemon/firemon |
152 | strip src/firecfg/firecfg | 149 | strip src/firecfg/firecfg |
153 | strip src/libtrace/libtrace.so | ||
154 | strip src/libtracelog/libtracelog.so | ||
155 | strip src/libpostexecseccomp/libpostexecseccomp.so | 150 | strip src/libpostexecseccomp/libpostexecseccomp.so |
156 | strip src/ftee/ftee | ||
157 | strip src/fnet/fnet | 151 | strip src/fnet/fnet |
158 | strip src/fnetfilter/fnetfilter | 152 | strip src/fnetfilter/fnetfilter |
159 | strip src/fseccomp/fseccomp | 153 | strip src/fseccomp/fseccomp |
@@ -3837,7 +3837,7 @@ if test "$prefix" = /usr; then | |||
3837 | sysconfdir="/etc" | 3837 | sysconfdir="/etc" |
3838 | fi | 3838 | fi |
3839 | 3839 | ||
3840 | ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile" | 3840 | ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/firecfg/Makefile src/fsec-print/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile" |
3841 | 3841 | ||
3842 | cat >confcache <<\_ACEOF | 3842 | cat >confcache <<\_ACEOF |
3843 | # This file is a shell script that caches the results of configure | 3843 | # This file is a shell script that caches the results of configure |
@@ -4553,11 +4553,8 @@ do | |||
4553 | "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; | 4553 | "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; |
4554 | "src/fnetfilter/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnetfilter/Makefile" ;; | 4554 | "src/fnetfilter/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnetfilter/Makefile" ;; |
4555 | "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; | 4555 | "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; |
4556 | "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; | ||
4557 | "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;; | ||
4558 | "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;; | 4556 | "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;; |
4559 | "src/fsec-print/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-print/Makefile" ;; | 4557 | "src/fsec-print/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-print/Makefile" ;; |
4560 | "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; | ||
4561 | "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;; | 4558 | "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;; |
4562 | "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;; | 4559 | "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;; |
4563 | "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;; | 4560 | "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;; |
diff --git a/configure.ac b/configure.ac index 124b3526d..6408609fd 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -190,8 +190,8 @@ if test "$prefix" = /usr; then | |||
190 | fi | 190 | fi |
191 | 191 | ||
192 | AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ | 192 | AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ |
193 | src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fsec-print/Makefile \ | 193 | src/firemon/Makefile src/firecfg/Makefile src/fsec-print/Makefile \ |
194 | src/ftee/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile) | 194 | src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile) |
195 | 195 | ||
196 | echo | 196 | echo |
197 | echo "Configuration options:" | 197 | echo "Configuration options:" |
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c index 38ab7e2f8..e1320433c 100644 --- a/src/firejail/fs_trace.c +++ b/src/firejail/fs_trace.c | |||
@@ -53,6 +53,7 @@ void fs_trace(void) { | |||
53 | errExit("fopen"); | 53 | errExit("fopen"); |
54 | const char *prefix = LIBDIR "/firejail"; | 54 | const char *prefix = LIBDIR "/firejail"; |
55 | 55 | ||
56 | #ifndef LTS | ||
56 | if (arg_trace) { | 57 | if (arg_trace) { |
57 | fprintf(fp, "%s/libtrace.so\n", prefix); | 58 | fprintf(fp, "%s/libtrace.so\n", prefix); |
58 | } | 59 | } |
@@ -60,6 +61,7 @@ void fs_trace(void) { | |||
60 | fprintf(fp, "%s/libtracelog.so\n", prefix); | 61 | fprintf(fp, "%s/libtracelog.so\n", prefix); |
61 | fmessage("Blacklist violations are logged to syslog\n"); | 62 | fmessage("Blacklist violations are logged to syslog\n"); |
62 | } | 63 | } |
64 | #endif | ||
63 | if (arg_seccomp_postexec) { | 65 | if (arg_seccomp_postexec) { |
64 | fprintf(fp, "%s/libpostexecseccomp.so\n", prefix); | 66 | fprintf(fp, "%s/libpostexecseccomp.so\n", prefix); |
65 | fmessage("Post-exec seccomp protector enabled\n"); | 67 | fmessage("Post-exec seccomp protector enabled\n"); |
diff --git a/src/firejail/main.c b/src/firejail/main.c index d1f3c47c2..9b406b4b9 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -66,8 +66,10 @@ int arg_caps_drop_all = 0; // drop all capabilities | |||
66 | int arg_caps_keep = 0; // keep list | 66 | 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 | #ifndef LTS | ||
69 | int arg_trace = 0; // syscall tracing support | 70 | int arg_trace = 0; // syscall tracing support |
70 | int arg_tracelog = 0; // blacklist tracing support | 71 | int arg_tracelog = 0; // blacklist tracing support |
72 | #endif | ||
71 | int arg_rlimit_cpu = 0; // rlimit max cpu time | 73 | int arg_rlimit_cpu = 0; // rlimit max cpu time |
72 | int arg_rlimit_nofile = 0; // rlimit nofile | 74 | int arg_rlimit_nofile = 0; // rlimit nofile |
73 | int arg_rlimit_nproc = 0; // rlimit nproc | 75 | int arg_rlimit_nproc = 0; // rlimit nproc |
@@ -1062,10 +1064,12 @@ int main(int argc, char **argv) { | |||
1062 | #endif | 1064 | #endif |
1063 | } | 1065 | } |
1064 | } | 1066 | } |
1067 | #ifndef LTS | ||
1065 | else { | 1068 | else { |
1066 | // check --output option and execute it; | 1069 | // check --output option and execute it; |
1067 | check_output(argc, argv); // the function will not return if --output or --output-stderr option was found | 1070 | check_output(argc, argv); // the function will not return if --output or --output-stderr option was found |
1068 | } | 1071 | } |
1072 | #endif | ||
1069 | EUID_ASSERT(); | 1073 | EUID_ASSERT(); |
1070 | 1074 | ||
1071 | 1075 | ||
@@ -1212,11 +1216,11 @@ int main(int argc, char **argv) { | |||
1212 | } | 1216 | } |
1213 | 1217 | ||
1214 | 1218 | ||
1219 | #ifndef LTS | ||
1215 | else if (strcmp(argv[i], "--trace") == 0) | 1220 | else if (strcmp(argv[i], "--trace") == 0) |
1216 | arg_trace = 1; | 1221 | arg_trace = 1; |
1217 | else if (strcmp(argv[i], "--tracelog") == 0) | 1222 | else if (strcmp(argv[i], "--tracelog") == 0) |
1218 | arg_tracelog = 1; | 1223 | arg_tracelog = 1; |
1219 | #ifndef LTS | ||
1220 | else if (strncmp(argv[i], "--rlimit-cpu=", 13) == 0) { | 1224 | else if (strncmp(argv[i], "--rlimit-cpu=", 13) == 0) { |
1221 | check_unsigned(argv[i] + 13, "Error: invalid rlimit"); | 1225 | check_unsigned(argv[i] + 13, "Error: invalid rlimit"); |
1222 | sscanf(argv[i] + 13, "%llu", &cfg.rlimit_cpu); | 1226 | sscanf(argv[i] + 13, "%llu", &cfg.rlimit_cpu); |
@@ -2243,11 +2247,12 @@ int main(int argc, char **argv) { | |||
2243 | exit(1); | 2247 | exit(1); |
2244 | } | 2248 | } |
2245 | 2249 | ||
2250 | #ifndef LTS | ||
2246 | // check trace configuration | 2251 | // check trace configuration |
2247 | if (arg_trace && arg_tracelog) { | 2252 | if (arg_trace && arg_tracelog) { |
2248 | fwarning("--trace and --tracelog are mutually exclusive; --tracelog disabled\n"); | 2253 | fwarning("--trace and --tracelog are mutually exclusive; --tracelog disabled\n"); |
2249 | } | 2254 | } |
2250 | 2255 | #endif | |
2251 | // check user namespace (--noroot) options | 2256 | // check user namespace (--noroot) options |
2252 | if (arg_noroot) { | 2257 | if (arg_noroot) { |
2253 | if (arg_overlay) { | 2258 | if (arg_overlay) { |
diff --git a/src/firejail/output.c b/src/firejail/output.c deleted file mode 100644 index 61c89992d..000000000 --- a/src/firejail/output.c +++ /dev/null | |||
@@ -1,109 +0,0 @@ | |||
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 | #include "firejail.h" | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <unistd.h> | ||
24 | |||
25 | void check_output(int argc, char **argv) { | ||
26 | EUID_ASSERT(); | ||
27 | |||
28 | int i; | ||
29 | int outindex = 0; | ||
30 | int enable_stderr = 0; | ||
31 | |||
32 | for (i = 1; i < argc; i++) { | ||
33 | if (strncmp(argv[i], "--output=", 9) == 0) { | ||
34 | outindex = i; | ||
35 | break; | ||
36 | } | ||
37 | if (strncmp(argv[i], "--output-stderr=", 16) == 0) { | ||
38 | outindex = i; | ||
39 | enable_stderr = 1; | ||
40 | break; | ||
41 | } | ||
42 | } | ||
43 | if (!outindex) | ||
44 | return; | ||
45 | |||
46 | |||
47 | // check filename | ||
48 | drop_privs(0); | ||
49 | char *outfile = argv[outindex]; | ||
50 | outfile += (enable_stderr)? 16:9; | ||
51 | invalid_filename(outfile, 0); // no globbing | ||
52 | |||
53 | // do not accept directories, links, and files with ".." | ||
54 | if (strstr(outfile, "..") || is_link(outfile) || is_dir(outfile)) { | ||
55 | fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); | ||
56 | exit(1); | ||
57 | } | ||
58 | |||
59 | struct stat s; | ||
60 | if (stat(outfile, &s) == 0) { | ||
61 | // check permissions | ||
62 | if (s.st_uid != getuid() || s.st_gid != getgid()) { | ||
63 | fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | // check hard links | ||
68 | if (s.st_nlink != 1) { | ||
69 | fprintf(stderr, "Error: no hard links allowed.\n"); | ||
70 | exit(1); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | // build the new command line | ||
75 | int len = 0; | ||
76 | for (i = 0; i < argc; i++) { | ||
77 | len += strlen(argv[i]) + 1; // + ' ' | ||
78 | } | ||
79 | len += 100 + strlen(LIBDIR) + strlen(outfile); // tee command | ||
80 | |||
81 | char *cmd = malloc(len + 1); // + '\0' | ||
82 | if (!cmd) | ||
83 | errExit("malloc"); | ||
84 | |||
85 | char *ptr = cmd; | ||
86 | for (i = 0; i < argc; i++) { | ||
87 | if (strncmp(argv[i], "--output=", 9) == 0) | ||
88 | continue; | ||
89 | if (strncmp(argv[i], "--output-stderr=", 16) == 0) | ||
90 | continue; | ||
91 | ptr += sprintf(ptr, "%s ", argv[i]); | ||
92 | } | ||
93 | |||
94 | if (enable_stderr) | ||
95 | sprintf(ptr, "2>&1 | %s/firejail/ftee %s", LIBDIR, outfile); | ||
96 | else | ||
97 | sprintf(ptr, " | %s/firejail/ftee %s", LIBDIR, outfile); | ||
98 | |||
99 | // run command | ||
100 | char *a[4]; | ||
101 | a[0] = "/bin/bash"; | ||
102 | a[1] = "-c"; | ||
103 | a[2] = cmd; | ||
104 | a[3] = NULL; | ||
105 | execvp(a[0], a); | ||
106 | |||
107 | perror("execvp"); | ||
108 | exit(1); | ||
109 | } | ||
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index fb1beacd5..79fc36fb5 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -197,10 +197,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
197 | arg_shell_none = 1; | 197 | arg_shell_none = 1; |
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | #ifndef LTS | ||
200 | else if (strcmp(ptr, "tracelog") == 0) { | 201 | else if (strcmp(ptr, "tracelog") == 0) { |
201 | arg_tracelog = 1; | 202 | arg_tracelog = 1; |
202 | return 0; | 203 | return 0; |
203 | } | 204 | } |
205 | #endif | ||
204 | else if (strcmp(ptr, "private") == 0) { | 206 | else if (strcmp(ptr, "private") == 0) { |
205 | arg_private = 1; | 207 | arg_private = 1; |
206 | return 0; | 208 | return 0; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index deb37d700..b0a792277 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -719,8 +719,11 @@ int sandbox(void* sandbox_arg) { | |||
719 | #endif | 719 | #endif |
720 | 720 | ||
721 | // need ld.so.preload if tracing or seccomp with any non-default lists | 721 | // need ld.so.preload if tracing or seccomp with any non-default lists |
722 | #ifndef LTS | ||
722 | bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec; | 723 | bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec; |
723 | 724 | #else | |
725 | bool need_preload = arg_seccomp_postexec; | ||
726 | #endif | ||
724 | // trace pre-install | 727 | // trace pre-install |
725 | if (need_preload) | 728 | if (need_preload) |
726 | fs_trace_preload(); | 729 | fs_trace_preload(); |
diff --git a/src/ftee/Makefile.in b/src/ftee/Makefile.in deleted file mode 100644 index d3b92362c..000000000 --- a/src/ftee/Makefile.in +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | all: ftee | ||
2 | |||
3 | include ../common.mk | ||
4 | |||
5 | %.o : %.c $(H_FILE_LIST) | ||
6 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ | ||
7 | |||
8 | ftee: $(OBJS) | ||
9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) | ||
10 | |||
11 | clean:; rm -f *.o ftee *.gcov *.gcda *.gcno | ||
12 | |||
13 | distclean: clean | ||
14 | rm -fr Makefile | ||
diff --git a/src/ftee/ftee.h b/src/ftee/ftee.h deleted file mode 100644 index 68c4201c7..000000000 --- a/src/ftee/ftee.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
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 | #ifndef FTEE_H | ||
21 | #define FTEE_H | ||
22 | #include "../include/common.h" | ||
23 | |||
24 | #endif | ||
diff --git a/src/ftee/main.c b/src/ftee/main.c deleted file mode 100644 index 0e37f0b72..000000000 --- a/src/ftee/main.c +++ /dev/null | |||
@@ -1,245 +0,0 @@ | |||
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 | #include "ftee.h" | ||
21 | #include <errno.h> | ||
22 | #include <sys/types.h> | ||
23 | #include <sys/stat.h> | ||
24 | #include <unistd.h> | ||
25 | #define MAXBUF 512 | ||
26 | |||
27 | static unsigned char buf[MAXBUF]; | ||
28 | |||
29 | static FILE *out_fp = NULL; | ||
30 | static int out_cnt = 0; | ||
31 | static int out_max = 500 * 1024; | ||
32 | |||
33 | static void log_close(void) { | ||
34 | if (out_fp) { | ||
35 | fclose(out_fp); | ||
36 | out_fp = NULL; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static void log_rotate(const char *fname) { | ||
41 | struct stat s; | ||
42 | int index = strlen(fname); | ||
43 | char *name1 = malloc(index + 2 + 1); | ||
44 | char *name2 = malloc(index + 2 + 1); | ||
45 | if (!name1 || !name2) | ||
46 | errExit("malloc"); | ||
47 | strcpy(name1, fname); | ||
48 | strcpy(name2, fname); | ||
49 | fflush(0); | ||
50 | |||
51 | // delete filename.5 | ||
52 | sprintf(name1 + index, ".5"); | ||
53 | if (stat(name1, &s) == 0) { | ||
54 | int rv = unlink(name1); | ||
55 | if (rv == -1) | ||
56 | perror("unlink"); | ||
57 | } | ||
58 | |||
59 | // move files 1 to 4 down one position | ||
60 | sprintf(name2 + index, ".4"); | ||
61 | if (stat(name2, &s) == 0) { | ||
62 | int rv = rename(name2, name1); | ||
63 | if (rv == -1) | ||
64 | perror("rename"); | ||
65 | } | ||
66 | |||
67 | sprintf(name1 + index, ".3"); | ||
68 | if (stat(name1, &s) == 0) { | ||
69 | int rv = rename(name1, name2); | ||
70 | if (rv == -1) | ||
71 | perror("rename"); | ||
72 | } | ||
73 | |||
74 | sprintf(name2 + index, ".2"); | ||
75 | if (stat(name2, &s) == 0) { | ||
76 | /* coverity[toctou] */ | ||
77 | int rv = rename(name2, name1); | ||
78 | if (rv == -1) | ||
79 | perror("rename"); | ||
80 | } | ||
81 | |||
82 | sprintf(name1 + index, ".1"); | ||
83 | if (stat(name1, &s) == 0) { | ||
84 | int rv = rename(name1, name2); | ||
85 | if (rv == -1) | ||
86 | perror("rename"); | ||
87 | } | ||
88 | |||
89 | // move the first file | ||
90 | if (out_fp) | ||
91 | fclose(out_fp); | ||
92 | |||
93 | out_fp = NULL; | ||
94 | if (stat(fname, &s) == 0) { | ||
95 | int rv = rename(fname, name1); | ||
96 | if (rv == -1) | ||
97 | perror("rename"); | ||
98 | } | ||
99 | |||
100 | free(name1); | ||
101 | free(name2); | ||
102 | } | ||
103 | |||
104 | static void log_write(const unsigned char *str, int len, const char *fname) { | ||
105 | assert(fname); | ||
106 | |||
107 | if (out_fp == NULL) { | ||
108 | out_fp = fopen(fname, "w"); | ||
109 | if (!out_fp) { | ||
110 | fprintf(stderr, "Error: cannot open log file %s\n", fname); | ||
111 | exit(1); | ||
112 | } | ||
113 | out_cnt = 0; | ||
114 | } | ||
115 | |||
116 | // rotate files | ||
117 | out_cnt += len; | ||
118 | if (out_cnt >= out_max) { | ||
119 | log_rotate(fname); | ||
120 | |||
121 | // reopen the first file | ||
122 | if (out_fp) | ||
123 | fclose(out_fp); | ||
124 | out_fp = fopen(fname, "w"); | ||
125 | if (!out_fp) { | ||
126 | fprintf(stderr, "Error: cannot open log file %s\n", fname); | ||
127 | exit(1); | ||
128 | } | ||
129 | out_cnt = len; | ||
130 | } | ||
131 | |||
132 | int rv = fwrite(str, len, 1, out_fp); | ||
133 | (void) rv; | ||
134 | fflush(0); | ||
135 | } | ||
136 | |||
137 | |||
138 | // return 1 if the file is a directory | ||
139 | static int is_dir(const char *fname) { | ||
140 | assert(fname); | ||
141 | if (*fname == '\0') | ||
142 | return 0; | ||
143 | |||
144 | // if fname doesn't end in '/', add one | ||
145 | int rv; | ||
146 | struct stat s; | ||
147 | if (fname[strlen(fname) - 1] == '/') | ||
148 | rv = stat(fname, &s); | ||
149 | else { | ||
150 | char *tmp; | ||
151 | if (asprintf(&tmp, "%s/", fname) == -1) { | ||
152 | fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); | ||
153 | exit(1); | ||
154 | } | ||
155 | rv = stat(tmp, &s); | ||
156 | free(tmp); | ||
157 | } | ||
158 | |||
159 | if (rv == -1) | ||
160 | return 0; | ||
161 | |||
162 | if (S_ISDIR(s.st_mode)) | ||
163 | return 1; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | // return 1 if the file is a link | ||
169 | static int is_link(const char *fname) { | ||
170 | assert(fname); | ||
171 | if (*fname == '\0') | ||
172 | return 0; | ||
173 | |||
174 | struct stat s; | ||
175 | if (lstat(fname, &s) == 0) { | ||
176 | if (S_ISLNK(s.st_mode)) | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static void usage(void) { | ||
184 | printf("Usage: ftee filename\n"); | ||
185 | } | ||
186 | |||
187 | int main(int argc, char **argv) { | ||
188 | if (argc < 2) { | ||
189 | fprintf(stderr, "Error: please provide a filename to store the program output\n"); | ||
190 | usage(); | ||
191 | exit(1); | ||
192 | } | ||
193 | if (strcmp(argv[1], "--help") == 0) { | ||
194 | usage(); | ||
195 | return 0; | ||
196 | } | ||
197 | char *fname = argv[1]; | ||
198 | |||
199 | |||
200 | // do not accept directories, links, and files with ".." | ||
201 | if (strstr(fname, "..") || is_link(fname) || is_dir(fname)) | ||
202 | goto errexit; | ||
203 | |||
204 | struct stat s; | ||
205 | if (stat(fname, &s) == 0) { | ||
206 | // check permissions | ||
207 | if (s.st_uid != getuid() || s.st_gid != getgid()) | ||
208 | goto errexit; | ||
209 | |||
210 | // check hard links | ||
211 | if (s.st_nlink != 1) | ||
212 | goto errexit; | ||
213 | } | ||
214 | |||
215 | // check if we can append to this file | ||
216 | /* coverity[toctou] */ | ||
217 | FILE *fp = fopen(fname, "a"); | ||
218 | if (!fp) | ||
219 | goto errexit; | ||
220 | fclose(fp); | ||
221 | |||
222 | |||
223 | // preserve the last log file | ||
224 | log_rotate(fname); | ||
225 | |||
226 | setvbuf (stdout, NULL, _IONBF, 0); | ||
227 | while(1) { | ||
228 | int n = read(0, buf, sizeof(buf)); | ||
229 | if (n < 0 && errno == EINTR) | ||
230 | continue; | ||
231 | if (n <= 0) | ||
232 | break; | ||
233 | |||
234 | int rv = fwrite(buf, n, 1, stdout); | ||
235 | (void) rv; | ||
236 | log_write(buf, n, fname); | ||
237 | } | ||
238 | |||
239 | log_close(); | ||
240 | return 0; | ||
241 | |||
242 | errexit: | ||
243 | fprintf(stderr, "Error ftee: invalid output file.\n"); | ||
244 | return 1; | ||
245 | } | ||
diff --git a/src/libtrace/Makefile.in b/src/libtrace/Makefile.in deleted file mode 100644 index 6ae078f46..000000000 --- a/src/libtrace/Makefile.in +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | CC=@CC@ | ||
2 | PREFIX=@prefix@ | ||
3 | VERSION=@PACKAGE_VERSION@ | ||
4 | NAME=@PACKAGE_NAME@ | ||
5 | HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ | ||
6 | |||
7 | H_FILE_LIST = $(sort $(wildcard *.[h])) | ||
8 | C_FILE_LIST = $(sort $(wildcard *.c)) | ||
9 | OBJS = $(C_FILE_LIST:.c=.o) | ||
10 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
11 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security | ||
12 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now | ||
13 | |||
14 | all: libtrace.so | ||
15 | |||
16 | %.o : %.c $(H_FILE_LIST) | ||
17 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
18 | |||
19 | libtrace.so: $(OBJS) | ||
20 | $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl | ||
21 | |||
22 | |||
23 | clean:; rm -f $(OBJS) libtrace.so | ||
24 | |||
25 | distclean: clean | ||
26 | rm -fr Makefile | ||
diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c deleted file mode 100644 index c41bafb68..000000000 --- a/src/libtrace/libtrace.c +++ /dev/null | |||
@@ -1,692 +0,0 @@ | |||
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 | #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 <limits.h> | ||
27 | #include <unistd.h> | ||
28 | #include <sys/socket.h> | ||
29 | #include <netinet/in.h> | ||
30 | #include <arpa/inet.h> | ||
31 | #include <sys/un.h> | ||
32 | #include <sys/stat.h> | ||
33 | #include <syslog.h> | ||
34 | #include <dirent.h> | ||
35 | #include <limits.h> | ||
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 | // pid | ||
45 | // | ||
46 | static pid_t mypid = 0; | ||
47 | static inline pid_t pid(void) { | ||
48 | if (!mypid) | ||
49 | mypid = getpid(); | ||
50 | return mypid; | ||
51 | } | ||
52 | |||
53 | // | ||
54 | // process name | ||
55 | // | ||
56 | #define MAXNAME 16 | ||
57 | static char myname[MAXNAME]; | ||
58 | static int nameinit = 0; | ||
59 | static char *name(void) { | ||
60 | if (!nameinit) { | ||
61 | // initialize the name of the process based on /proc/PID/comm | ||
62 | memset(myname, 0, MAXNAME); | ||
63 | |||
64 | pid_t p = pid(); | ||
65 | char *fname; | ||
66 | if (asprintf(&fname, "/proc/%u/comm", p) == -1) | ||
67 | return "unknown"; | ||
68 | |||
69 | // read file | ||
70 | if (!orig_fopen) | ||
71 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
72 | FILE *fp = orig_fopen(fname, "r"); | ||
73 | if (!fp) | ||
74 | return "unknown"; | ||
75 | if (fgets(myname, MAXNAME, fp) == NULL) { | ||
76 | fclose(fp); | ||
77 | free(fname); | ||
78 | return "unknown"; | ||
79 | } | ||
80 | |||
81 | // clean '\n' | ||
82 | char *ptr = strchr(myname, '\n'); | ||
83 | if (ptr) | ||
84 | *ptr = '\0'; | ||
85 | |||
86 | fclose(fp); | ||
87 | free(fname); | ||
88 | nameinit = 1; | ||
89 | } | ||
90 | |||
91 | return myname; | ||
92 | } | ||
93 | |||
94 | // | ||
95 | // network | ||
96 | // | ||
97 | typedef struct { | ||
98 | int val; | ||
99 | char *name; | ||
100 | } XTable; | ||
101 | |||
102 | static XTable socket_type[] = { | ||
103 | #ifdef SOCK_STREAM | ||
104 | { SOCK_STREAM, "SOCK_STREAM" }, | ||
105 | #endif | ||
106 | #ifdef SOCK_DGRAM | ||
107 | { SOCK_DGRAM, "SOCK_DGRAM" }, | ||
108 | #endif | ||
109 | #ifdef SOCK_RAW | ||
110 | { SOCK_RAW, "SOCK_RAW" }, | ||
111 | #endif | ||
112 | #ifdef SOCK_RDM | ||
113 | { SOCK_RDM, "SOCK_RDM" }, | ||
114 | #endif | ||
115 | #ifdef SOCK_SEQPACKET | ||
116 | { SOCK_SEQPACKET, "SOCK_SEQPACKET" }, | ||
117 | #endif | ||
118 | #ifdef SOCK_DCCP | ||
119 | { SOCK_DCCP, "SOCK_DCCP" }, | ||
120 | #endif | ||
121 | { 0, NULL} // NULL terminated | ||
122 | }; | ||
123 | |||
124 | static XTable socket_domain[] = { | ||
125 | #ifdef AF_INET | ||
126 | { AF_INET, "AF_INET" }, | ||
127 | #endif | ||
128 | #ifdef AF_INET6 | ||
129 | { AF_INET6, "AF_INET6" }, | ||
130 | #endif | ||
131 | #ifdef AF_LOCAL | ||
132 | { AF_LOCAL, "AF_LOCAL" }, | ||
133 | #endif | ||
134 | #ifdef AF_PACKET | ||
135 | { AF_PACKET, "AF_PACKET" }, | ||
136 | #endif | ||
137 | #ifdef AF_IPX | ||
138 | { AF_IPX, "AF_IPX" }, | ||
139 | #endif | ||
140 | #ifdef AF_NETLINK | ||
141 | { AF_NETLINK, "AF_NETLINK" }, | ||
142 | #endif | ||
143 | #ifdef AF_X25 | ||
144 | { AF_X25, "AF_X25" }, | ||
145 | #endif | ||
146 | #ifdef AF_AX25 | ||
147 | { AF_AX25, "AF_AX25" }, | ||
148 | #endif | ||
149 | #ifdef AF_ATMPVC | ||
150 | { AF_ATMPVC, "AF_ATMPVC" }, | ||
151 | #endif | ||
152 | #ifdef AF_APPLETALK | ||
153 | { AF_APPLETALK, "AF_APPLETALK" }, | ||
154 | #endif | ||
155 | { 0, NULL} // NULL terminated | ||
156 | }; | ||
157 | |||
158 | static XTable socket_protocol[] = { | ||
159 | #ifdef IPPROTO_IP | ||
160 | { IPPROTO_IP, "IPPROTO_IP" }, | ||
161 | #endif | ||
162 | #ifdef IPPROTO_ICMP | ||
163 | { IPPROTO_ICMP, "IPPROTO_ICMP" }, | ||
164 | #endif | ||
165 | #ifdef IPPROTO_IGMP | ||
166 | { IPPROTO_IGMP, "IPPROTO_IGMP" }, | ||
167 | #endif | ||
168 | #ifdef IPPROTO_IPIP | ||
169 | { IPPROTO_IPIP, "IPPROTO_IPIP" }, | ||
170 | #endif | ||
171 | #ifdef IPPROTO_TCP | ||
172 | { IPPROTO_TCP, "IPPROTO_TCP" }, | ||
173 | #endif | ||
174 | #ifdef IPPROTO_EGP | ||
175 | { IPPROTO_EGP, "IPPROTO_EGP" }, | ||
176 | #endif | ||
177 | #ifdef IPPROTO_PUP | ||
178 | { IPPROTO_PUP, "IPPROTO_PUP" }, | ||
179 | #endif | ||
180 | #ifdef IPPROTO_UDP | ||
181 | { IPPROTO_UDP, "IPPROTO_UDP" }, | ||
182 | #endif | ||
183 | #ifdef IPPROTO_IDP | ||
184 | { IPPROTO_IDP, "IPPROTO_IDP" }, | ||
185 | #endif | ||
186 | #ifdef IPPROTO_DCCP | ||
187 | { IPPROTO_DCCP, "IPPROTO_DCCP" }, | ||
188 | #endif | ||
189 | #ifdef IPPROTO_RSVP | ||
190 | { IPPROTO_RSVP, "IPPROTO_RSVP" }, | ||
191 | #endif | ||
192 | #ifdef IPPROTO_GRE | ||
193 | { IPPROTO_GRE, "IPPROTO_GRE" }, | ||
194 | #endif | ||
195 | #ifdef IPPROTO_IPV6 | ||
196 | { IPPROTO_IPV6, "IPPROTO_IPV6" }, | ||
197 | #endif | ||
198 | #ifdef IPPROTO_ESP | ||
199 | { IPPROTO_ESP, "IPPROTO_ESP" }, | ||
200 | #endif | ||
201 | #ifdef IPPROTO_AH | ||
202 | { IPPROTO_AH, "IPPROTO_AH" }, | ||
203 | #endif | ||
204 | #ifdef IPPROTO_BEETPH | ||
205 | { IPPROTO_BEETPH, "IPPROTO_BEETPH" }, | ||
206 | #endif | ||
207 | #ifdef IPPROTO_PIM | ||
208 | { IPPROTO_PIM, "IPPROTO_PIM" }, | ||
209 | #endif | ||
210 | #ifdef IPPROTO_COMP | ||
211 | { IPPROTO_COMP, "IPPROTO_COMP" }, | ||
212 | #endif | ||
213 | #ifdef IPPROTO_SCTP | ||
214 | { IPPROTO_SCTP, "IPPROTO_SCTP" }, | ||
215 | #endif | ||
216 | #ifdef IPPROTO_UDPLITE | ||
217 | { IPPROTO_UDPLITE, "IPPROTO_UDPLITE" }, | ||
218 | #endif | ||
219 | #ifdef IPPROTO_RAW | ||
220 | { IPPROTO_RAW, "IPPROTO_RAW" }, | ||
221 | #endif | ||
222 | { 0, NULL} // NULL terminated | ||
223 | }; | ||
224 | |||
225 | static char *translate(XTable *table, int val) { | ||
226 | while (table->name != NULL) { | ||
227 | if (val == table->val) | ||
228 | return table->name; | ||
229 | table++; | ||
230 | } | ||
231 | |||
232 | return NULL; | ||
233 | } | ||
234 | |||
235 | static void print_sockaddr(int sockfd, const char *call, const struct sockaddr *addr, int rv) { | ||
236 | if (addr->sa_family == AF_INET) { | ||
237 | struct sockaddr_in *a = (struct sockaddr_in *) addr; | ||
238 | printf("%u:%s:%s %d %s port %u:%d\n", pid(), name(), call, sockfd, inet_ntoa(a->sin_addr), ntohs(a->sin_port), rv); | ||
239 | } | ||
240 | else if (addr->sa_family == AF_INET6) { | ||
241 | struct sockaddr_in6 *a = (struct sockaddr_in6 *) addr; | ||
242 | char str[INET6_ADDRSTRLEN]; | ||
243 | inet_ntop(AF_INET6, &(a->sin6_addr), str, INET6_ADDRSTRLEN); | ||
244 | printf("%u:%s:%s %d %s:%d\n", pid(), name(), call, sockfd, str, rv); | ||
245 | } | ||
246 | else if (addr->sa_family == AF_UNIX) { | ||
247 | struct sockaddr_un *a = (struct sockaddr_un *) addr; | ||
248 | if (a->sun_path[0]) | ||
249 | printf("%u:%s:%s %d %s:%d\n", pid(), name(), call, sockfd, a->sun_path, rv); | ||
250 | else | ||
251 | printf("%u:%s:%s %d @%s:%d\n", pid(), name(), call, sockfd, a->sun_path + 1, rv); | ||
252 | } | ||
253 | else { | ||
254 | printf("%u:%s:%s %d family %d:%d\n", pid(), name(), call, sockfd, addr->sa_family, rv); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | // | ||
259 | // syscalls | ||
260 | // | ||
261 | |||
262 | // open | ||
263 | typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode); | ||
264 | static orig_open_t orig_open = NULL; | ||
265 | int open(const char *pathname, int flags, mode_t mode) { | ||
266 | if (!orig_open) | ||
267 | orig_open = (orig_open_t)dlsym(RTLD_NEXT, "open"); | ||
268 | |||
269 | int rv = orig_open(pathname, flags, mode); | ||
270 | printf("%u:%s:open %s:%d\n", pid(), name(), pathname, rv); | ||
271 | return rv; | ||
272 | } | ||
273 | |||
274 | typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode); | ||
275 | static orig_open64_t orig_open64 = NULL; | ||
276 | int open64(const char *pathname, int flags, mode_t mode) { | ||
277 | if (!orig_open64) | ||
278 | orig_open64 = (orig_open64_t)dlsym(RTLD_NEXT, "open64"); | ||
279 | |||
280 | int rv = orig_open64(pathname, flags, mode); | ||
281 | printf("%u:%s:open64 %s:%d\n", pid(), name(), pathname, rv); | ||
282 | return rv; | ||
283 | } | ||
284 | |||
285 | // openat | ||
286 | typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
287 | static orig_openat_t orig_openat = NULL; | ||
288 | int openat(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
289 | if (!orig_openat) | ||
290 | orig_openat = (orig_openat_t)dlsym(RTLD_NEXT, "openat"); | ||
291 | |||
292 | int rv = orig_openat(dirfd, pathname, flags, mode); | ||
293 | printf("%u:%s:openat %s:%d\n", pid(), name(), pathname, rv); | ||
294 | return rv; | ||
295 | } | ||
296 | |||
297 | typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
298 | static orig_openat64_t orig_openat64 = NULL; | ||
299 | int openat64(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
300 | if (!orig_openat64) | ||
301 | orig_openat64 = (orig_openat64_t)dlsym(RTLD_NEXT, "openat64"); | ||
302 | |||
303 | int rv = orig_openat64(dirfd, pathname, flags, mode); | ||
304 | printf("%u:%s:openat64 %s:%d\n", pid(), name(), pathname, rv); | ||
305 | return rv; | ||
306 | } | ||
307 | |||
308 | |||
309 | // fopen | ||
310 | FILE *fopen(const char *pathname, const char *mode) { | ||
311 | if (!orig_fopen) | ||
312 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
313 | |||
314 | FILE *rv = orig_fopen(pathname, mode); | ||
315 | printf("%u:%s:fopen %s:%p\n", pid(), name(), pathname, rv); | ||
316 | return rv; | ||
317 | } | ||
318 | |||
319 | #ifdef __GLIBC__ | ||
320 | FILE *fopen64(const char *pathname, const char *mode) { | ||
321 | if (!orig_fopen64) | ||
322 | orig_fopen64 = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen64"); | ||
323 | |||
324 | FILE *rv = orig_fopen64(pathname, mode); | ||
325 | printf("%u:%s:fopen64 %s:%p\n", pid(), name(), pathname, rv); | ||
326 | return rv; | ||
327 | } | ||
328 | #endif /* __GLIBC__ */ | ||
329 | |||
330 | |||
331 | // freopen | ||
332 | typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream); | ||
333 | static orig_freopen_t orig_freopen = NULL; | ||
334 | FILE *freopen(const char *pathname, const char *mode, FILE *stream) { | ||
335 | if (!orig_freopen) | ||
336 | orig_freopen = (orig_freopen_t)dlsym(RTLD_NEXT, "freopen"); | ||
337 | |||
338 | FILE *rv = orig_freopen(pathname, mode, stream); | ||
339 | printf("%u:%s:freopen %s:%p\n", pid(), name(), pathname, rv); | ||
340 | return rv; | ||
341 | } | ||
342 | |||
343 | #ifdef __GLIBC__ | ||
344 | typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream); | ||
345 | static orig_freopen64_t orig_freopen64 = NULL; | ||
346 | FILE *freopen64(const char *pathname, const char *mode, FILE *stream) { | ||
347 | if (!orig_freopen64) | ||
348 | orig_freopen64 = (orig_freopen64_t)dlsym(RTLD_NEXT, "freopen64"); | ||
349 | |||
350 | FILE *rv = orig_freopen64(pathname, mode, stream); | ||
351 | printf("%u:%s:freopen64 %s:%p\n", pid(), name(), pathname, rv); | ||
352 | return rv; | ||
353 | } | ||
354 | #endif /* __GLIBC__ */ | ||
355 | |||
356 | // unlink | ||
357 | typedef int (*orig_unlink_t)(const char *pathname); | ||
358 | static orig_unlink_t orig_unlink = NULL; | ||
359 | int unlink(const char *pathname) { | ||
360 | if (!orig_unlink) | ||
361 | orig_unlink = (orig_unlink_t)dlsym(RTLD_NEXT, "unlink"); | ||
362 | |||
363 | int rv = orig_unlink(pathname); | ||
364 | printf("%u:%s:unlink %s:%d\n", pid(), name(), pathname, rv); | ||
365 | return rv; | ||
366 | } | ||
367 | |||
368 | typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags); | ||
369 | static orig_unlinkat_t orig_unlinkat = NULL; | ||
370 | int unlinkat(int dirfd, const char *pathname, int flags) { | ||
371 | if (!orig_unlinkat) | ||
372 | orig_unlinkat = (orig_unlinkat_t)dlsym(RTLD_NEXT, "unlinkat"); | ||
373 | |||
374 | int rv = orig_unlinkat(dirfd, pathname, flags); | ||
375 | printf("%u:%s:unlinkat %s:%d\n", pid(), name(), pathname, rv); | ||
376 | return rv; | ||
377 | } | ||
378 | |||
379 | // mkdir/mkdirat/rmdir | ||
380 | typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode); | ||
381 | static orig_mkdir_t orig_mkdir = NULL; | ||
382 | int mkdir(const char *pathname, mode_t mode) { | ||
383 | if (!orig_mkdir) | ||
384 | orig_mkdir = (orig_mkdir_t)dlsym(RTLD_NEXT, "mkdir"); | ||
385 | |||
386 | int rv = orig_mkdir(pathname, mode); | ||
387 | printf("%u:%s:mkdir %s:%d\n", pid(), name(), pathname, rv); | ||
388 | return rv; | ||
389 | } | ||
390 | |||
391 | typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode); | ||
392 | static orig_mkdirat_t orig_mkdirat = NULL; | ||
393 | int mkdirat(int dirfd, const char *pathname, mode_t mode) { | ||
394 | if (!orig_mkdirat) | ||
395 | orig_mkdirat = (orig_mkdirat_t)dlsym(RTLD_NEXT, "mkdirat"); | ||
396 | |||
397 | int rv = orig_mkdirat(dirfd, pathname, mode); | ||
398 | printf("%u:%s:mkdirat %s:%d\n", pid(), name(), pathname, rv); | ||
399 | return rv; | ||
400 | } | ||
401 | |||
402 | typedef int (*orig_rmdir_t)(const char *pathname); | ||
403 | static orig_rmdir_t orig_rmdir = NULL; | ||
404 | int rmdir(const char *pathname) { | ||
405 | if (!orig_rmdir) | ||
406 | orig_rmdir = (orig_rmdir_t)dlsym(RTLD_NEXT, "rmdir"); | ||
407 | |||
408 | int rv = orig_rmdir(pathname); | ||
409 | printf("%u:%s:rmdir %s:%d\n", pid(), name(), pathname, rv); | ||
410 | return rv; | ||
411 | } | ||
412 | |||
413 | // stat | ||
414 | typedef int (*orig_stat_t)(const char *pathname, struct stat *buf); | ||
415 | static orig_stat_t orig_stat = NULL; | ||
416 | int stat(const char *pathname, struct stat *buf) { | ||
417 | if (!orig_stat) | ||
418 | orig_stat = (orig_stat_t)dlsym(RTLD_NEXT, "stat"); | ||
419 | |||
420 | int rv = orig_stat(pathname, buf); | ||
421 | printf("%u:%s:stat %s:%d\n", pid(), name(), pathname, rv); | ||
422 | return rv; | ||
423 | } | ||
424 | |||
425 | #ifdef __GLIBC__ | ||
426 | typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); | ||
427 | static orig_stat64_t orig_stat64 = NULL; | ||
428 | int stat64(const char *pathname, struct stat64 *buf) { | ||
429 | if (!orig_stat64) | ||
430 | orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); | ||
431 | |||
432 | int rv = orig_stat64(pathname, buf); | ||
433 | printf("%u:%s:stat64 %s:%d\n", pid(), name(), pathname, rv); | ||
434 | return rv; | ||
435 | } | ||
436 | #endif /* __GLIBC__ */ | ||
437 | |||
438 | // lstat | ||
439 | typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf); | ||
440 | static orig_lstat_t orig_lstat = NULL; | ||
441 | int lstat(const char *pathname, struct stat *buf) { | ||
442 | if (!orig_lstat) | ||
443 | orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat"); | ||
444 | |||
445 | int rv = orig_lstat(pathname, buf); | ||
446 | printf("%u:%s:lstat %s:%d\n", pid(), name(), pathname, rv); | ||
447 | return rv; | ||
448 | } | ||
449 | |||
450 | #ifdef __GLIBC__ | ||
451 | typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf); | ||
452 | static orig_lstat64_t orig_lstat64 = NULL; | ||
453 | int lstat64(const char *pathname, struct stat64 *buf) { | ||
454 | if (!orig_lstat64) | ||
455 | orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); | ||
456 | |||
457 | int rv = orig_lstat64(pathname, buf); | ||
458 | printf("%u:%s:lstat64 %s:%d\n", pid(), name(), pathname, rv); | ||
459 | return rv; | ||
460 | } | ||
461 | #endif /* __GLIBC__ */ | ||
462 | |||
463 | // opendir | ||
464 | typedef DIR *(*orig_opendir_t)(const char *pathname); | ||
465 | static orig_opendir_t orig_opendir = NULL; | ||
466 | DIR *opendir(const char *pathname) { | ||
467 | if (!orig_opendir) | ||
468 | orig_opendir = (orig_opendir_t)dlsym(RTLD_NEXT, "opendir"); | ||
469 | |||
470 | DIR *rv = orig_opendir(pathname); | ||
471 | printf("%u:%s:opendir %s:%p\n", pid(), name(), pathname, rv); | ||
472 | return rv; | ||
473 | } | ||
474 | |||
475 | // access | ||
476 | typedef int (*orig_access_t)(const char *pathname, int mode); | ||
477 | static orig_access_t orig_access = NULL; | ||
478 | int access(const char *pathname, int mode) { | ||
479 | if (!orig_access) | ||
480 | orig_access = (orig_access_t)dlsym(RTLD_NEXT, "access"); | ||
481 | |||
482 | int rv = orig_access(pathname, mode); | ||
483 | printf("%u:%s:access %s:%d\n", pid(), name(), pathname, rv); | ||
484 | return rv; | ||
485 | } | ||
486 | |||
487 | |||
488 | // connect | ||
489 | typedef int (*orig_connect_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
490 | static orig_connect_t orig_connect = NULL; | ||
491 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { | ||
492 | if (!orig_connect) | ||
493 | orig_connect = (orig_connect_t)dlsym(RTLD_NEXT, "connect"); | ||
494 | |||
495 | int rv = orig_connect(sockfd, addr, addrlen); | ||
496 | print_sockaddr(sockfd, "connect", addr, rv); | ||
497 | |||
498 | return rv; | ||
499 | } | ||
500 | |||
501 | // socket | ||
502 | typedef int (*orig_socket_t)(int domain, int type, int protocol); | ||
503 | static orig_socket_t orig_socket = NULL; | ||
504 | static char buf[1024]; | ||
505 | int socket(int domain, int type, int protocol) { | ||
506 | if (!orig_socket) | ||
507 | orig_socket = (orig_socket_t)dlsym(RTLD_NEXT, "socket"); | ||
508 | |||
509 | int rv = orig_socket(domain, type, protocol); | ||
510 | char *ptr = buf; | ||
511 | ptr += sprintf(ptr, "%u:%s:socket ", pid(), name()); | ||
512 | char *str = translate(socket_domain, domain); | ||
513 | if (str == NULL) | ||
514 | ptr += sprintf(ptr, "%d ", domain); | ||
515 | else | ||
516 | ptr += sprintf(ptr, "%s ", str); | ||
517 | |||
518 | int t = type; // glibc uses higher bits for various other purposes | ||
519 | #ifdef SOCK_CLOEXEC | ||
520 | t &= ~SOCK_CLOEXEC; | ||
521 | #endif | ||
522 | #ifdef SOCK_NONBLOCK | ||
523 | t &= ~SOCK_NONBLOCK; | ||
524 | #endif | ||
525 | str = translate(socket_type, t); | ||
526 | if (str == NULL) | ||
527 | ptr += sprintf(ptr, "%d ", type); | ||
528 | else | ||
529 | ptr += sprintf(ptr, "%s ", str); | ||
530 | |||
531 | if (domain == AF_LOCAL) | ||
532 | sprintf(ptr, "0"); | ||
533 | else { | ||
534 | str = translate(socket_protocol, protocol); | ||
535 | if (str == NULL) | ||
536 | sprintf(ptr, "%d", protocol); | ||
537 | else | ||
538 | sprintf(ptr, "%s", str); | ||
539 | } | ||
540 | |||
541 | printf("%s:%d\n", buf, rv); | ||
542 | return rv; | ||
543 | } | ||
544 | |||
545 | // bind | ||
546 | typedef int (*orig_bind_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
547 | static orig_bind_t orig_bind = NULL; | ||
548 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { | ||
549 | if (!orig_bind) | ||
550 | orig_bind = (orig_bind_t)dlsym(RTLD_NEXT, "bind"); | ||
551 | |||
552 | int rv = orig_bind(sockfd, addr, addrlen); | ||
553 | print_sockaddr(sockfd, "bind", addr, rv); | ||
554 | |||
555 | return rv; | ||
556 | } | ||
557 | |||
558 | #if 0 | ||
559 | typedef int (*orig_accept_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); | ||
560 | static orig_accept_t orig_accept = NULL; | ||
561 | int accept(int sockfd, struct sockaddr *addr, socklen_t addrlen) { | ||
562 | if (!orig_accept) | ||
563 | orig_accept = (orig_accept_t)dlsym(RTLD_NEXT, "accept"); | ||
564 | |||
565 | int rv = orig_accept(sockfd, addr, addrlen); | ||
566 | print_sockaddr(sockfd, "accept", addr, rv); | ||
567 | |||
568 | return rv; | ||
569 | } | ||
570 | #endif | ||
571 | |||
572 | typedef int (*orig_system_t)(const char *command); | ||
573 | static orig_system_t orig_system = NULL; | ||
574 | int system(const char *command) { | ||
575 | if (!orig_system) | ||
576 | orig_system = (orig_system_t)dlsym(RTLD_NEXT, "system"); | ||
577 | |||
578 | int rv = orig_system(command); | ||
579 | printf("%u:%s:system %s:%d\n", pid(), name(), command, rv); | ||
580 | |||
581 | return rv; | ||
582 | } | ||
583 | |||
584 | typedef int (*orig_setuid_t)(uid_t uid); | ||
585 | static orig_setuid_t orig_setuid = NULL; | ||
586 | int setuid(uid_t uid) { | ||
587 | if (!orig_setuid) | ||
588 | orig_setuid = (orig_setuid_t)dlsym(RTLD_NEXT, "setuid"); | ||
589 | |||
590 | int rv = orig_setuid(uid); | ||
591 | printf("%u:%s:setuid %d:%d\n", pid(), name(), uid, rv); | ||
592 | |||
593 | return rv; | ||
594 | } | ||
595 | |||
596 | typedef int (*orig_setgid_t)(gid_t gid); | ||
597 | static orig_setgid_t orig_setgid = NULL; | ||
598 | int setgid(gid_t gid) { | ||
599 | if (!orig_setgid) | ||
600 | orig_setgid = (orig_setgid_t)dlsym(RTLD_NEXT, "setgid"); | ||
601 | |||
602 | int rv = orig_setgid(gid); | ||
603 | printf("%u:%s:setgid %d:%d\n", pid(), name(), gid, rv); | ||
604 | |||
605 | return rv; | ||
606 | } | ||
607 | |||
608 | typedef int (*orig_setfsuid_t)(uid_t uid); | ||
609 | static orig_setfsuid_t orig_setfsuid = NULL; | ||
610 | int setfsuid(uid_t uid) { | ||
611 | if (!orig_setfsuid) | ||
612 | orig_setfsuid = (orig_setfsuid_t)dlsym(RTLD_NEXT, "setfsuid"); | ||
613 | |||
614 | int rv = orig_setfsuid(uid); | ||
615 | printf("%u:%s:setfsuid %d:%d\n", pid(), name(), uid, rv); | ||
616 | |||
617 | return rv; | ||
618 | } | ||
619 | |||
620 | typedef int (*orig_setfsgid_t)(gid_t gid); | ||
621 | static orig_setfsgid_t orig_setfsgid = NULL; | ||
622 | int setfsgid(gid_t gid) { | ||
623 | if (!orig_setfsgid) | ||
624 | orig_setfsgid = (orig_setfsgid_t)dlsym(RTLD_NEXT, "setfsgid"); | ||
625 | |||
626 | int rv = orig_setfsgid(gid); | ||
627 | printf("%u:%s:setfsgid %d:%d\n", pid(), name(), gid, rv); | ||
628 | |||
629 | return rv; | ||
630 | } | ||
631 | |||
632 | typedef int (*orig_setreuid_t)(uid_t ruid, uid_t euid); | ||
633 | static orig_setreuid_t orig_setreuid = NULL; | ||
634 | int setreuid(uid_t ruid, uid_t euid) { | ||
635 | if (!orig_setreuid) | ||
636 | orig_setreuid = (orig_setreuid_t)dlsym(RTLD_NEXT, "setreuid"); | ||
637 | |||
638 | int rv = orig_setreuid(ruid, euid); | ||
639 | printf("%u:%s:setreuid %d %d:%d\n", pid(), name(), ruid, euid, rv); | ||
640 | |||
641 | return rv; | ||
642 | } | ||
643 | |||
644 | typedef int (*orig_setregid_t)(gid_t rgid, gid_t egid); | ||
645 | static orig_setregid_t orig_setregid = NULL; | ||
646 | int setregid(gid_t rgid, gid_t egid) { | ||
647 | if (!orig_setregid) | ||
648 | orig_setregid = (orig_setregid_t)dlsym(RTLD_NEXT, "setregid"); | ||
649 | |||
650 | int rv = orig_setregid(rgid, egid); | ||
651 | printf("%u:%s:setregid %d %d:%d\n", pid(), name(), rgid, egid, rv); | ||
652 | |||
653 | return rv; | ||
654 | } | ||
655 | |||
656 | typedef int (*orig_setresuid_t)(uid_t ruid, uid_t euid, uid_t suid); | ||
657 | static orig_setresuid_t orig_setresuid = NULL; | ||
658 | int setresuid(uid_t ruid, uid_t euid, uid_t suid) { | ||
659 | if (!orig_setresuid) | ||
660 | orig_setresuid = (orig_setresuid_t)dlsym(RTLD_NEXT, "setresuid"); | ||
661 | |||
662 | int rv = orig_setresuid(ruid, euid, suid); | ||
663 | printf("%u:%s:setresuid %d %d %d:%d\n", pid(), name(), ruid, euid, suid, rv); | ||
664 | |||
665 | return rv; | ||
666 | } | ||
667 | |||
668 | typedef int (*orig_setresgid_t)(gid_t rgid, gid_t egid, gid_t sgid); | ||
669 | static orig_setresgid_t orig_setresgid = NULL; | ||
670 | int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { | ||
671 | if (!orig_setresgid) | ||
672 | orig_setresgid = (orig_setresgid_t)dlsym(RTLD_NEXT, "setresgid"); | ||
673 | |||
674 | int rv = orig_setresgid(rgid, egid, sgid); | ||
675 | printf("%u:%s:setresgid %d %d %d:%d\n", pid(), name(), rgid, egid, sgid, rv); | ||
676 | |||
677 | return rv; | ||
678 | } | ||
679 | |||
680 | // every time a new process is started, this gets called | ||
681 | // it can be used to build things like private-bin | ||
682 | __attribute__((constructor)) | ||
683 | static void log_exec(int argc, char** argv) { | ||
684 | (void) argc; | ||
685 | (void) argv; | ||
686 | static char buf[PATH_MAX + 1]; | ||
687 | int rv = readlink("/proc/self/exe", buf, PATH_MAX); | ||
688 | if (rv != -1) { | ||
689 | buf[rv] = '\0'; // readlink does not add a '\0' at the end | ||
690 | printf("%u:%s:exec %s:0\n", pid(), name(), buf); | ||
691 | } | ||
692 | } | ||
diff --git a/src/libtracelog/Makefile.in b/src/libtracelog/Makefile.in deleted file mode 100644 index 3927c762a..000000000 --- a/src/libtracelog/Makefile.in +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | CC=@CC@ | ||
2 | PREFIX=@prefix@ | ||
3 | VERSION=@PACKAGE_VERSION@ | ||
4 | NAME=@PACKAGE_NAME@ | ||
5 | HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ | ||
6 | |||
7 | H_FILE_LIST = $(sort $(wildcard *.[h])) | ||
8 | C_FILE_LIST = $(sort $(wildcard *.c)) | ||
9 | OBJS = $(C_FILE_LIST:.c=.o) | ||
10 | BINOBJS = $(foreach file, $(OBJS), $file) | ||
11 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security | ||
12 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now | ||
13 | |||
14 | all: libtracelog.so | ||
15 | |||
16 | %.o : %.c $(H_FILE_LIST) | ||
17 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | ||
18 | |||
19 | libtracelog.so: $(OBJS) | ||
20 | $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl | ||
21 | |||
22 | |||
23 | clean:; rm -f $(OBJS) libtracelog.so | ||
24 | |||
25 | distclean: clean | ||
26 | rm -fr Makefile | ||
diff --git a/src/libtracelog/libtracelog.c b/src/libtracelog/libtracelog.c deleted file mode 100644 index 0f8d5a00d..000000000 --- a/src/libtracelog/libtracelog.c +++ /dev/null | |||
@@ -1,704 +0,0 @@ | |||
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 | #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 | #include <limits.h> | ||
35 | |||
36 | //#define DEBUG | ||
37 | |||
38 | // break recursivity on fopen call | ||
39 | typedef FILE *(*orig_fopen_t)(const char *pathname, const char *mode); | ||
40 | static orig_fopen_t orig_fopen = NULL; | ||
41 | typedef FILE *(*orig_fopen64_t)(const char *pathname, const char *mode); | ||
42 | static orig_fopen64_t orig_fopen64 = NULL; | ||
43 | |||
44 | // | ||
45 | // blacklist storage | ||
46 | // | ||
47 | typedef struct list_elem_t { | ||
48 | struct list_elem_t *next; | ||
49 | char *path; | ||
50 | } ListElem; | ||
51 | |||
52 | #define HMASK 0x0ff | ||
53 | ListElem *storage[HMASK + 1]; | ||
54 | |||
55 | // djb2 | ||
56 | static inline uint32_t hash(const char *str) { | ||
57 | uint32_t hash = 5381; | ||
58 | int c; | ||
59 | |||
60 | while ((c = *str++) != '\0') | ||
61 | hash = ((hash << 5) + hash) + c; // hash * 33 + c; another variant would be hash * 33 ^ c | ||
62 | |||
63 | return hash & HMASK; | ||
64 | } | ||
65 | |||
66 | static void storage_add(const char *str) { | ||
67 | if (!str) { | ||
68 | #ifdef DEBUG | ||
69 | printf("null pointer passed to storage_add\n"); | ||
70 | #endif | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | #ifdef DEBUG | ||
75 | printf("add %s\n", str); | ||
76 | #endif | ||
77 | |||
78 | ListElem *ptr = malloc(sizeof(ListElem)); | ||
79 | if (!ptr) { | ||
80 | fprintf(stderr, "Error: cannot allocate memory\n"); | ||
81 | return; | ||
82 | } | ||
83 | ptr->path = strdup(str); | ||
84 | if (!ptr->path) { | ||
85 | fprintf(stderr, "Error: cannot allocate memory\n"); | ||
86 | free(ptr); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | // insert it into the hash table | ||
91 | uint32_t h = hash(ptr->path); | ||
92 | ptr->next = storage[h]; | ||
93 | storage[h] = ptr; | ||
94 | } | ||
95 | |||
96 | // global variable to keep current working directory | ||
97 | static char* cwd = NULL; | ||
98 | |||
99 | static char *storage_find(const char *str) { | ||
100 | if (!str) { | ||
101 | #ifdef DEBUG | ||
102 | printf("null pointer passed to storage_find\n"); | ||
103 | #endif | ||
104 | return NULL; | ||
105 | } | ||
106 | |||
107 | #ifdef DEBUG | ||
108 | printf("storage find %s\n", str); | ||
109 | #endif | ||
110 | |||
111 | const char *tofind = str; | ||
112 | int allocated = 0; | ||
113 | |||
114 | if (strstr(str, "..") || strstr(str, "/./") || strstr(str, "//") || str[0] != '/') { | ||
115 | if (cwd != NULL && str[0] != '/') { | ||
116 | char *fullpath=malloc(PATH_MAX); | ||
117 | if (!fullpath) { | ||
118 | fprintf(stderr, "Error: cannot allocate memory\n"); | ||
119 | return NULL; | ||
120 | } | ||
121 | if (snprintf(fullpath, PATH_MAX, "%s/%s", cwd, str)<3) { | ||
122 | fprintf(stderr, "Error: snprintf failed\n"); | ||
123 | free(fullpath); | ||
124 | return NULL; | ||
125 | } | ||
126 | tofind = realpath(fullpath, NULL); | ||
127 | free(fullpath); | ||
128 | } else { | ||
129 | tofind = realpath(str, NULL); | ||
130 | } | ||
131 | if (!tofind) { | ||
132 | #ifdef DEBUG | ||
133 | printf("realpath failed\n"); | ||
134 | #endif | ||
135 | return NULL; | ||
136 | } | ||
137 | allocated = 1; | ||
138 | } | ||
139 | |||
140 | uint32_t h = hash(tofind); | ||
141 | ListElem *ptr = storage[h]; | ||
142 | while (ptr) { | ||
143 | if (strcmp(tofind, ptr->path) == 0) { | ||
144 | if (allocated) | ||
145 | free((char *) tofind); | ||
146 | #ifdef DEBUG | ||
147 | printf("storage found\n"); | ||
148 | #endif | ||
149 | return ptr->path; | ||
150 | } | ||
151 | ptr = ptr->next; | ||
152 | } | ||
153 | |||
154 | if (allocated) | ||
155 | free((char *) tofind); | ||
156 | #ifdef DEBUG | ||
157 | printf("storage not found\n"); | ||
158 | #endif | ||
159 | return NULL; | ||
160 | } | ||
161 | |||
162 | |||
163 | // | ||
164 | // load blacklist form /run/firejail/mnt/fslogger | ||
165 | // | ||
166 | #define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger" | ||
167 | #define MAXBUF 4096 | ||
168 | static int blacklist_loaded = 0; | ||
169 | static char *sandbox_pid_str = NULL; | ||
170 | static char *sandbox_name_str = NULL; | ||
171 | static void load_blacklist(void) { | ||
172 | if (blacklist_loaded) | ||
173 | return; | ||
174 | |||
175 | // open filesystem log | ||
176 | if (!orig_fopen) | ||
177 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
178 | FILE *fp = orig_fopen(RUN_FSLOGGER_FILE, "r"); | ||
179 | if (!fp) | ||
180 | return; | ||
181 | |||
182 | // extract blacklists | ||
183 | char buf[MAXBUF]; | ||
184 | int cnt = 0; | ||
185 | while (fgets(buf, MAXBUF, fp)) { | ||
186 | if (strncmp(buf, "sandbox pid: ", 13) == 0) { | ||
187 | char *ptr = strchr(buf, '\n'); | ||
188 | if (ptr) | ||
189 | *ptr = '\0'; | ||
190 | if (sandbox_pid_str == NULL) | ||
191 | sandbox_pid_str = strdup(buf + 13); | ||
192 | } | ||
193 | else if (strncmp(buf, "sandbox name: ", 14) == 0) { | ||
194 | char *ptr = strchr(buf, '\n'); | ||
195 | if (ptr) | ||
196 | *ptr = '\0'; | ||
197 | if (sandbox_name_str == NULL) | ||
198 | sandbox_name_str = strdup(buf + 14); | ||
199 | } | ||
200 | else if (strncmp(buf, "blacklist ", 10) == 0) { | ||
201 | char *ptr = strchr(buf, '\n'); | ||
202 | if (ptr) | ||
203 | *ptr = '\0'; | ||
204 | storage_add(buf + 10); | ||
205 | cnt++; | ||
206 | } | ||
207 | } | ||
208 | fclose(fp); | ||
209 | blacklist_loaded = 1; | ||
210 | #ifdef DEBUG | ||
211 | printf("Monitoring %d blacklists\n", cnt); | ||
212 | { | ||
213 | int i; | ||
214 | for (i = 0; i <= HMASK; i++) { | ||
215 | int cnt = 0; | ||
216 | ListElem *ptr = storage[i]; | ||
217 | while (ptr) { | ||
218 | cnt++; | ||
219 | ptr = ptr->next; | ||
220 | } | ||
221 | |||
222 | if ((i % 16) == 0) | ||
223 | printf("\n"); | ||
224 | printf("%02d ", cnt); | ||
225 | } | ||
226 | printf("\n"); | ||
227 | } | ||
228 | #endif | ||
229 | } | ||
230 | |||
231 | |||
232 | static void sendlog(const char *name, const char *call, const char *path) { | ||
233 | if (!name || !call || !path) { | ||
234 | #ifdef DEBUG | ||
235 | printf("null pointer passed to sendlog\n"); | ||
236 | #endif | ||
237 | return; | ||
238 | } | ||
239 | |||
240 | openlog ("firejail", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); | ||
241 | if (sandbox_pid_str && sandbox_name_str) | ||
242 | syslog (LOG_INFO, "blacklist violation - sandbox %s, name %s, exe %s, syscall %s, path %s", | ||
243 | sandbox_pid_str, sandbox_name_str, name, call, path); | ||
244 | else if (sandbox_pid_str) | ||
245 | syslog (LOG_INFO, "blacklist violation - sandbox %s, exe %s, syscall %s, path %s", | ||
246 | sandbox_pid_str, name, call, path); | ||
247 | else | ||
248 | syslog (LOG_INFO, "blacklist violation - exe %s, syscall %s, path %s", | ||
249 | name, call, path); | ||
250 | closelog (); | ||
251 | } | ||
252 | |||
253 | |||
254 | // | ||
255 | // pid | ||
256 | // | ||
257 | static pid_t mypid = 0; | ||
258 | static inline pid_t pid(void) { | ||
259 | if (!mypid) | ||
260 | mypid = getpid(); | ||
261 | return mypid; | ||
262 | } | ||
263 | |||
264 | // | ||
265 | // process name | ||
266 | // | ||
267 | #define MAXNAME 16 | ||
268 | static char myname[MAXNAME]; | ||
269 | static int nameinit = 0; | ||
270 | static char *name(void) { | ||
271 | if (!nameinit) { | ||
272 | |||
273 | // initialize the name of the process based on /proc/PID/comm | ||
274 | memset(myname, 0, MAXNAME); | ||
275 | |||
276 | pid_t p = pid(); | ||
277 | char *fname; | ||
278 | if (asprintf(&fname, "/proc/%u/comm", p) == -1) | ||
279 | return "unknown"; | ||
280 | |||
281 | // read file | ||
282 | if (!orig_fopen) | ||
283 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
284 | FILE *fp = orig_fopen(fname, "r"); | ||
285 | if (!fp) | ||
286 | return "unknown"; | ||
287 | if (fgets(myname, MAXNAME, fp) == NULL) { | ||
288 | fclose(fp); | ||
289 | free(fname); | ||
290 | return "unknown"; | ||
291 | } | ||
292 | |||
293 | // clean '\n' | ||
294 | char *ptr = strchr(myname, '\n'); | ||
295 | if (ptr) | ||
296 | *ptr = '\0'; | ||
297 | |||
298 | fclose(fp); | ||
299 | free(fname); | ||
300 | nameinit = 1; | ||
301 | } | ||
302 | |||
303 | return myname; | ||
304 | } | ||
305 | |||
306 | // | ||
307 | // syscalls | ||
308 | // | ||
309 | |||
310 | // open | ||
311 | typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode); | ||
312 | static orig_open_t orig_open = NULL; | ||
313 | int open(const char *pathname, int flags, mode_t mode) { | ||
314 | #ifdef DEBUG | ||
315 | printf("%s %s\n", __FUNCTION__, pathname); | ||
316 | #endif | ||
317 | if (!orig_open) | ||
318 | orig_open = (orig_open_t)dlsym(RTLD_NEXT, "open"); | ||
319 | |||
320 | if (!blacklist_loaded) | ||
321 | load_blacklist(); | ||
322 | |||
323 | if (storage_find(pathname)) | ||
324 | sendlog(name(), __FUNCTION__, pathname); | ||
325 | int rv = orig_open(pathname, flags, mode); | ||
326 | return rv; | ||
327 | } | ||
328 | |||
329 | |||
330 | |||
331 | |||
332 | //#if 0 - todo: fix problems on google-chrome and opera - seems to be crashing when open64 is called | ||
333 | typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode); | ||
334 | static orig_open64_t orig_open64 = NULL; | ||
335 | int open64(const char *pathname, int flags, mode_t mode) { | ||
336 | #ifdef DEBUG | ||
337 | printf("%s %s\n", __FUNCTION__, pathname); | ||
338 | #endif | ||
339 | if (!orig_open64) | ||
340 | orig_open64 = (orig_open64_t)dlsym(RTLD_NEXT, "open64"); | ||
341 | if (!blacklist_loaded) | ||
342 | load_blacklist(); | ||
343 | |||
344 | if (storage_find(pathname)) | ||
345 | sendlog(name(), __FUNCTION__, pathname); | ||
346 | int rv = orig_open64(pathname, flags, mode); | ||
347 | return rv; | ||
348 | } | ||
349 | //#endif | ||
350 | |||
351 | |||
352 | // openat | ||
353 | typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
354 | static orig_openat_t orig_openat = NULL; | ||
355 | int openat(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
356 | #ifdef DEBUG | ||
357 | printf("%s %s\n", __FUNCTION__, pathname); | ||
358 | #endif | ||
359 | if (!orig_openat) | ||
360 | orig_openat = (orig_openat_t)dlsym(RTLD_NEXT, "openat"); | ||
361 | if (!blacklist_loaded) | ||
362 | load_blacklist(); | ||
363 | |||
364 | if (storage_find(pathname)) | ||
365 | sendlog(name(), __FUNCTION__, pathname); | ||
366 | int rv = orig_openat(dirfd, pathname, flags, mode); | ||
367 | return rv; | ||
368 | } | ||
369 | |||
370 | typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode); | ||
371 | static orig_openat64_t orig_openat64 = NULL; | ||
372 | int openat64(int dirfd, const char *pathname, int flags, mode_t mode) { | ||
373 | #ifdef DEBUG | ||
374 | printf("%s %s\n", __FUNCTION__, pathname); | ||
375 | #endif | ||
376 | if (!orig_openat64) | ||
377 | orig_openat64 = (orig_openat64_t)dlsym(RTLD_NEXT, "openat64"); | ||
378 | if (!blacklist_loaded) | ||
379 | load_blacklist(); | ||
380 | |||
381 | if (storage_find(pathname)) | ||
382 | sendlog(name(), __FUNCTION__, pathname); | ||
383 | int rv = orig_openat64(dirfd, pathname, flags, mode); | ||
384 | return rv; | ||
385 | } | ||
386 | |||
387 | |||
388 | // fopen | ||
389 | FILE *fopen(const char *pathname, const char *mode) { | ||
390 | #ifdef DEBUG | ||
391 | printf("%s %s\n", __FUNCTION__, pathname); | ||
392 | #endif | ||
393 | if (!orig_fopen) | ||
394 | orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen"); | ||
395 | if (!blacklist_loaded) | ||
396 | load_blacklist(); | ||
397 | |||
398 | if (storage_find(pathname)) | ||
399 | sendlog(name(), __FUNCTION__, pathname); | ||
400 | FILE *rv = orig_fopen(pathname, mode); | ||
401 | return rv; | ||
402 | } | ||
403 | |||
404 | #ifdef __GLIBC__ | ||
405 | FILE *fopen64(const char *pathname, const char *mode) { | ||
406 | #ifdef DEBUG | ||
407 | printf("%s %s\n", __FUNCTION__, pathname); | ||
408 | #endif | ||
409 | if (!orig_fopen64) | ||
410 | orig_fopen64 = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen64"); | ||
411 | if (!blacklist_loaded) | ||
412 | load_blacklist(); | ||
413 | |||
414 | if (storage_find(pathname)) | ||
415 | sendlog(name(), __FUNCTION__, pathname); | ||
416 | FILE *rv = orig_fopen64(pathname, mode); | ||
417 | return rv; | ||
418 | } | ||
419 | #endif /* __GLIBC__ */ | ||
420 | |||
421 | |||
422 | // freopen | ||
423 | typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream); | ||
424 | static orig_freopen_t orig_freopen = NULL; | ||
425 | FILE *freopen(const char *pathname, const char *mode, FILE *stream) { | ||
426 | #ifdef DEBUG | ||
427 | printf("%s %s\n", __FUNCTION__, pathname); | ||
428 | #endif | ||
429 | if (!orig_freopen) | ||
430 | orig_freopen = (orig_freopen_t)dlsym(RTLD_NEXT, "freopen"); | ||
431 | if (!blacklist_loaded) | ||
432 | load_blacklist(); | ||
433 | |||
434 | if (storage_find(pathname)) | ||
435 | sendlog(name(), __FUNCTION__, pathname); | ||
436 | FILE *rv = orig_freopen(pathname, mode, stream); | ||
437 | return rv; | ||
438 | } | ||
439 | |||
440 | #ifdef __GLIBC__ | ||
441 | typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream); | ||
442 | static orig_freopen64_t orig_freopen64 = NULL; | ||
443 | FILE *freopen64(const char *pathname, const char *mode, FILE *stream) { | ||
444 | #ifdef DEBUG | ||
445 | printf("%s %s\n", __FUNCTION__, pathname); | ||
446 | #endif | ||
447 | if (!orig_freopen64) | ||
448 | orig_freopen64 = (orig_freopen64_t)dlsym(RTLD_NEXT, "freopen64"); | ||
449 | if (!blacklist_loaded) | ||
450 | load_blacklist(); | ||
451 | |||
452 | if (storage_find(pathname)) | ||
453 | sendlog(name(), __FUNCTION__, pathname); | ||
454 | FILE *rv = orig_freopen64(pathname, mode, stream); | ||
455 | return rv; | ||
456 | } | ||
457 | #endif /* __GLIBC__ */ | ||
458 | |||
459 | // unlink | ||
460 | typedef int (*orig_unlink_t)(const char *pathname); | ||
461 | static orig_unlink_t orig_unlink = NULL; | ||
462 | int unlink(const char *pathname) { | ||
463 | #ifdef DEBUG | ||
464 | printf("%s %s\n", __FUNCTION__, pathname); | ||
465 | #endif | ||
466 | if (!orig_unlink) | ||
467 | orig_unlink = (orig_unlink_t)dlsym(RTLD_NEXT, "unlink"); | ||
468 | if (!blacklist_loaded) | ||
469 | load_blacklist(); | ||
470 | |||
471 | if (storage_find(pathname)) | ||
472 | sendlog(name(), __FUNCTION__, pathname); | ||
473 | int rv = orig_unlink(pathname); | ||
474 | return rv; | ||
475 | } | ||
476 | |||
477 | typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags); | ||
478 | static orig_unlinkat_t orig_unlinkat = NULL; | ||
479 | int unlinkat(int dirfd, const char *pathname, int flags) { | ||
480 | #ifdef DEBUG | ||
481 | printf("%s %s\n", __FUNCTION__, pathname); | ||
482 | #endif | ||
483 | if (!orig_unlinkat) | ||
484 | orig_unlinkat = (orig_unlinkat_t)dlsym(RTLD_NEXT, "unlinkat"); | ||
485 | if (!blacklist_loaded) | ||
486 | load_blacklist(); | ||
487 | |||
488 | if (storage_find(pathname)) | ||
489 | sendlog(name(), __FUNCTION__, pathname); | ||
490 | int rv = orig_unlinkat(dirfd, pathname, flags); | ||
491 | return rv; | ||
492 | } | ||
493 | |||
494 | // mkdir/mkdirat/rmdir | ||
495 | typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode); | ||
496 | static orig_mkdir_t orig_mkdir = NULL; | ||
497 | int mkdir(const char *pathname, mode_t mode) { | ||
498 | #ifdef DEBUG | ||
499 | printf("%s %s\n", __FUNCTION__, pathname); | ||
500 | #endif | ||
501 | if (!orig_mkdir) | ||
502 | orig_mkdir = (orig_mkdir_t)dlsym(RTLD_NEXT, "mkdir"); | ||
503 | if (!blacklist_loaded) | ||
504 | load_blacklist(); | ||
505 | |||
506 | if (storage_find(pathname)) | ||
507 | sendlog(name(), __FUNCTION__, pathname); | ||
508 | int rv = orig_mkdir(pathname, mode); | ||
509 | return rv; | ||
510 | } | ||
511 | |||
512 | typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode); | ||
513 | static orig_mkdirat_t orig_mkdirat = NULL; | ||
514 | int mkdirat(int dirfd, const char *pathname, mode_t mode) { | ||
515 | #ifdef DEBUG | ||
516 | printf("%s %s\n", __FUNCTION__, pathname); | ||
517 | #endif | ||
518 | if (!orig_mkdirat) | ||
519 | orig_mkdirat = (orig_mkdirat_t)dlsym(RTLD_NEXT, "mkdirat"); | ||
520 | if (!blacklist_loaded) | ||
521 | load_blacklist(); | ||
522 | |||
523 | if (storage_find(pathname)) | ||
524 | sendlog(name(), __FUNCTION__, pathname); | ||
525 | int rv = orig_mkdirat(dirfd, pathname, mode); | ||
526 | return rv; | ||
527 | } | ||
528 | |||
529 | typedef int (*orig_rmdir_t)(const char *pathname); | ||
530 | static orig_rmdir_t orig_rmdir = NULL; | ||
531 | int rmdir(const char *pathname) { | ||
532 | #ifdef DEBUG | ||
533 | printf("%s %s\n", __FUNCTION__, pathname); | ||
534 | #endif | ||
535 | if (!orig_rmdir) | ||
536 | orig_rmdir = (orig_rmdir_t)dlsym(RTLD_NEXT, "rmdir"); | ||
537 | if (!blacklist_loaded) | ||
538 | load_blacklist(); | ||
539 | |||
540 | if (storage_find(pathname)) | ||
541 | sendlog(name(), __FUNCTION__, pathname); | ||
542 | int rv = orig_rmdir(pathname); | ||
543 | return rv; | ||
544 | } | ||
545 | |||
546 | // stat | ||
547 | typedef int (*orig_stat_t)(const char *pathname, struct stat *buf); | ||
548 | static orig_stat_t orig_stat = NULL; | ||
549 | int stat(const char *pathname, struct stat *buf) { | ||
550 | #ifdef DEBUG | ||
551 | printf("%s %s\n", __FUNCTION__, pathname); | ||
552 | #endif | ||
553 | if (!orig_stat) | ||
554 | orig_stat = (orig_stat_t)dlsym(RTLD_NEXT, "stat"); | ||
555 | if (!blacklist_loaded) | ||
556 | load_blacklist(); | ||
557 | |||
558 | if (storage_find(pathname)) | ||
559 | sendlog(name(), __FUNCTION__, pathname); | ||
560 | int rv = orig_stat(pathname, buf); | ||
561 | return rv; | ||
562 | } | ||
563 | |||
564 | #ifdef __GLIBC__ | ||
565 | typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); | ||
566 | static orig_stat64_t orig_stat64 = NULL; | ||
567 | int stat64(const char *pathname, struct stat64 *buf) { | ||
568 | #ifdef DEBUG | ||
569 | printf("%s %s\n", __FUNCTION__, pathname); | ||
570 | #endif | ||
571 | if (!orig_stat64) | ||
572 | orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); | ||
573 | if (!blacklist_loaded) | ||
574 | load_blacklist(); | ||
575 | |||
576 | if (storage_find(pathname)) | ||
577 | sendlog(name(), __FUNCTION__, pathname); | ||
578 | int rv = orig_stat64(pathname, buf); | ||
579 | return rv; | ||
580 | } | ||
581 | #endif /* __GLIBC__ */ | ||
582 | |||
583 | typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf); | ||
584 | static orig_lstat_t orig_lstat = NULL; | ||
585 | int lstat(const char *pathname, struct stat *buf) { | ||
586 | #ifdef DEBUG | ||
587 | printf("%s %s\n", __FUNCTION__, pathname); | ||
588 | #endif | ||
589 | if (!orig_lstat) | ||
590 | orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat"); | ||
591 | if (!blacklist_loaded) | ||
592 | load_blacklist(); | ||
593 | |||
594 | if (storage_find(pathname)) | ||
595 | sendlog(name(), __FUNCTION__, pathname); | ||
596 | int rv = orig_lstat(pathname, buf); | ||
597 | return rv; | ||
598 | } | ||
599 | |||
600 | #ifdef __GLIBC__ | ||
601 | typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf); | ||
602 | static orig_lstat64_t orig_lstat64 = NULL; | ||
603 | int lstat64(const char *pathname, struct stat64 *buf) { | ||
604 | #ifdef DEBUG | ||
605 | printf("%s %s\n", __FUNCTION__, pathname); | ||
606 | #endif | ||
607 | if (!orig_lstat64) | ||
608 | orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); | ||
609 | if (!blacklist_loaded) | ||
610 | load_blacklist(); | ||
611 | |||
612 | if (storage_find(pathname)) | ||
613 | sendlog(name(), __FUNCTION__, pathname); | ||
614 | int rv = orig_lstat64(pathname, buf); | ||
615 | return rv; | ||
616 | } | ||
617 | #endif /* __GLIBC__ */ | ||
618 | |||
619 | // access | ||
620 | typedef int (*orig_access_t)(const char *pathname, int mode); | ||
621 | static orig_access_t orig_access = NULL; | ||
622 | int access(const char *pathname, int mode) { | ||
623 | #ifdef DEBUG | ||
624 | printf("%s, %s\n", __FUNCTION__, pathname); | ||
625 | #endif | ||
626 | if (!orig_access) | ||
627 | orig_access = (orig_access_t)dlsym(RTLD_NEXT, "access"); | ||
628 | if (!blacklist_loaded) | ||
629 | load_blacklist(); | ||
630 | |||
631 | if (storage_find(pathname)) | ||
632 | sendlog(name(), __FUNCTION__, pathname); | ||
633 | int rv = orig_access(pathname, mode); | ||
634 | return rv; | ||
635 | } | ||
636 | |||
637 | // opendir | ||
638 | typedef DIR *(*orig_opendir_t)(const char *pathname); | ||
639 | static orig_opendir_t orig_opendir = NULL; | ||
640 | DIR *opendir(const char *pathname) { | ||
641 | #ifdef DEBUG | ||
642 | printf("%s %s\n", __FUNCTION__, pathname); | ||
643 | #endif | ||
644 | if (!orig_opendir) | ||
645 | orig_opendir = (orig_opendir_t)dlsym(RTLD_NEXT, "opendir"); | ||
646 | if (!blacklist_loaded) | ||
647 | load_blacklist(); | ||
648 | |||
649 | if (storage_find(pathname)) | ||
650 | sendlog(name(), __FUNCTION__, pathname); | ||
651 | DIR *rv = orig_opendir(pathname); | ||
652 | return rv; | ||
653 | } | ||
654 | |||
655 | // chdir | ||
656 | typedef int (*orig_chdir_t)(const char *pathname); | ||
657 | static orig_chdir_t orig_chdir = NULL; | ||
658 | int chdir(const char *pathname) { | ||
659 | #ifdef DEBUG | ||
660 | printf("%s %s\n", __FUNCTION__, pathname); | ||
661 | #endif | ||
662 | if (!orig_chdir) | ||
663 | orig_chdir = (orig_chdir_t)dlsym(RTLD_NEXT, "chdir"); | ||
664 | if (!blacklist_loaded) | ||
665 | load_blacklist(); | ||
666 | |||
667 | if (storage_find(pathname)) | ||
668 | sendlog(name(), __FUNCTION__, pathname); | ||
669 | |||
670 | free(cwd); | ||
671 | cwd = strdup(pathname); | ||
672 | |||
673 | int rv = orig_chdir(pathname); | ||
674 | return rv; | ||
675 | } | ||
676 | |||
677 | // fchdir | ||
678 | typedef int (*orig_fchdir_t)(int fd); | ||
679 | static orig_fchdir_t orig_fchdir = NULL; | ||
680 | int fchdir(int fd) { | ||
681 | #ifdef DEBUG | ||
682 | printf("%s %d\n", __FUNCTION__, fd); | ||
683 | #endif | ||
684 | if (!orig_fchdir) | ||
685 | orig_fchdir = (orig_fchdir_t)dlsym(RTLD_NEXT, "fchdir"); | ||
686 | |||
687 | free(cwd); | ||
688 | char *pathname=malloc(PATH_MAX); | ||
689 | if (pathname) { | ||
690 | if (snprintf(pathname,PATH_MAX,"/proc/self/fd/%d", fd)>0) { | ||
691 | cwd = realpath(pathname, NULL); | ||
692 | } else { | ||
693 | cwd = NULL; | ||
694 | fprintf(stderr, "Error: snprintf failed\n"); | ||
695 | } | ||
696 | free(pathname); | ||
697 | } else { | ||
698 | fprintf(stderr, "Error: cannot allocate memory\n"); | ||
699 | cwd = NULL; | ||
700 | } | ||
701 | |||
702 | int rv = orig_fchdir(fd); | ||
703 | return rv; | ||
704 | } | ||
@@ -1,3 +1,8 @@ | |||
1 | Phase 2 | ||
2 | - Aug 21 | ||
3 | - remove --output --libtrace --libtracelog | ||
4 | |||
5 | |||
1 | Phase 1 | 6 | Phase 1 |
2 | - starting from main as of Jul 27 | 7 | - starting from main as of Jul 27 |
3 | - removing chroot, overlayfs, x11, private-bin, private-lib | 8 | - removing chroot, overlayfs, x11, private-bin, private-lib |