aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtracelog/libtracelog.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2015-12-03 08:45:52 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2015-12-03 08:45:52 -0500
commitf9021ef8714fee5d4eb30a2329f80eeebaeaf244 (patch)
treedd8152456b311b5539f6a8d4fb1b2a092737c1bb /src/libtracelog/libtracelog.c
parenttesting (diff)
downloadfirejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.gz
firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.tar.zst
firejail-f9021ef8714fee5d4eb30a2329f80eeebaeaf244.zip
--tracelog
Diffstat (limited to 'src/libtracelog/libtracelog.c')
-rw-r--r--src/libtracelog/libtracelog.c494
1 files changed, 494 insertions, 0 deletions
diff --git a/src/libtracelog/libtracelog.c b/src/libtracelog/libtracelog.c
new file mode 100644
index 000000000..c3bbc132b
--- /dev/null
+++ b/src/libtracelog/libtracelog.c
@@ -0,0 +1,494 @@
1/*
2 * Copyright (C) 2014, 2015 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#define _GNU_SOURCE
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <dlfcn.h>
25#include <sys/types.h>
26#include <unistd.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <sys/un.h>
31#include <sys/stat.h>
32#include <syslog.h>
33#include <dirent.h>
34
35
36
37// break recursivity on fopen call
38typedef FILE *(*orig_fopen_t)(const char *pathname, const char *mode);
39static orig_fopen_t orig_fopen = NULL;
40typedef FILE *(*orig_fopen64_t)(const char *pathname, const char *mode);
41static orig_fopen64_t orig_fopen64 = NULL;
42
43//
44// blacklist storage
45//
46typedef struct list_elem_t {
47 struct list_elem_t *next;
48 char *path;
49} ListElem;
50
51static ListElem *storage;
52
53static storage_add(const char *str) {
54 ListElem *ptr = malloc(sizeof(ListElem));
55 if (!ptr) {
56 fprintf(stderr, "Error: cannot allocate memory\n");
57 return;
58 }
59 ptr->path = strdup(str);
60 if (!ptr->path) {
61 fprintf(stderr, "Error: cannot allocate memory\n");
62 return;
63 }
64 ptr->next = storage;
65 storage = ptr;
66}
67
68static char *storage_find(const char *str) {
69 const char *tofind = str;
70 int allocated = 0;
71
72 if (strstr(str, "..") || strstr(str, "/./")) {
73 tofind = realpath(str, NULL);
74 allocated = 1;
75 }
76
77 ListElem *ptr = storage;
78 while (ptr) {
79 if (strcmp(tofind, ptr->path) == 0) {
80 if (allocated)
81 free((char *) tofind);
82 return ptr->path;
83 }
84 ptr = ptr->next;
85 }
86
87 if (allocated)
88 free((char *) tofind);
89 return NULL;
90}
91
92//
93// load blacklistst form /run/firejail/mnt/fslogger
94//
95#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
96#define MAXBUF 4096
97static int blacklist_loaded = 0;
98static char *sandbox_pid_str = 0;
99static char *sandbox_name_str = NULL;
100void load_blacklist(void) {
101 if (blacklist_loaded)
102 return;
103
104 // open filesystem log
105 if (!orig_fopen)
106 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
107 FILE *fp = orig_fopen(RUN_FSLOGGER_FILE, "r");
108 if (!fp)
109 return;
110
111 // extract blacklists
112 char buf[MAXBUF];
113 int cnt = 0;
114 while (fgets(buf, MAXBUF, fp)) {
115 if (strncmp(buf, "sandbox pid: ", 13) == 0) {
116 char *ptr = strchr(buf, '\n');
117 if (ptr)
118 *ptr = '\0';
119 sandbox_pid_str = strdup(buf + 13);
120 }
121 else if (strncmp(buf, "sandbox name: ", 14) == 0) {
122 char *ptr = strchr(buf, '\n');
123 if (ptr)
124 *ptr = '\0';
125 sandbox_name_str = strdup(buf + 14);
126 }
127 else if (strncmp(buf, "blacklist ", 10) == 0) {
128 char *ptr = strchr(buf, '\n');
129 if (ptr)
130 *ptr = '\0';
131 storage_add(buf + 10);
132 cnt++;
133 }
134 }
135 fclose(fp);
136 blacklist_loaded = 1;
137 printf("Monitoring %d blacklists\n", cnt);
138}
139
140
141static void sendlog(const char *name, const char *call, const char *path) {
142 openlog ("firejail", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
143 if (sandbox_pid_str && sandbox_name_str)
144 syslog (LOG_INFO, "blacklist violation - sandbox %s, name %s, exe %s, syscall %s, path %s",
145 sandbox_pid_str, sandbox_name_str, name, call, path);
146 else if (sandbox_pid_str)
147 syslog (LOG_INFO, "blacklist violation - sandbox %s, exe %s, syscall %s, path %s",
148 sandbox_pid_str, name, call, path);
149 else
150 syslog (LOG_INFO, "blacklist violation - exe %s, syscall %s, path %s",
151 name, call, path);
152 closelog ();
153}
154
155
156//
157// pid
158//
159static pid_t mypid = 0;
160static inline pid_t pid(void) {
161 if (!mypid)
162 mypid = getpid();
163 return mypid;
164}
165
166//
167// process name
168//
169#define MAXNAME 16
170static char myname[MAXNAME];
171static int nameinit = 0;
172static char *name(void) {
173 if (!nameinit) {
174
175 // initialize the name of the process based on /proc/PID/comm
176 memset(myname, 0, MAXNAME);
177
178 pid_t p = pid();
179 char *fname;
180 if (asprintf(&fname, "/proc/%u/comm", p) == -1)
181 return "unknown";
182
183 // read file
184 if (!orig_fopen)
185 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
186 FILE *fp = orig_fopen(fname, "r");
187 if (!fp)
188 return "unknown";
189 if (fgets(myname, MAXNAME, fp) == NULL) {
190 fclose(fp);
191 free(fname);
192 return "unknown";
193 }
194
195 // clean '\n'
196 char *ptr = strchr(myname, '\n');
197 if (ptr)
198 *ptr = '\0';
199
200 fclose(fp);
201 free(fname);
202 nameinit = 1;
203 }
204
205 return myname;
206}
207
208//
209// syscalls
210//
211
212// open
213typedef int (*orig_open_t)(const char *pathname, int flags, mode_t mode);
214static orig_open_t orig_open = NULL;
215int open(const char *pathname, int flags, mode_t mode) {
216 if (!orig_open)
217 orig_open = (orig_open_t)dlsym(RTLD_NEXT, "open");
218
219 if (!storage)
220 load_blacklist();
221
222 int rv = orig_open(pathname, flags, mode);
223 if (storage_find(pathname))
224 sendlog(name(), __FUNCTION__, pathname);
225 return rv;
226}
227
228typedef int (*orig_open64_t)(const char *pathname, int flags, mode_t mode);
229static orig_open64_t orig_open64 = NULL;
230int open64(const char *pathname, int flags, mode_t mode) {
231 if (!orig_open64)
232 orig_open64 = (orig_open64_t)dlsym(RTLD_NEXT, "open64");
233 if (!storage)
234 load_blacklist();
235
236 int rv = orig_open64(pathname, flags, mode);
237 if (storage_find(pathname))
238 sendlog(name(), __FUNCTION__, pathname);
239 return rv;
240}
241
242// openat
243typedef int (*orig_openat_t)(int dirfd, const char *pathname, int flags, mode_t mode);
244static orig_openat_t orig_openat = NULL;
245int openat(int dirfd, const char *pathname, int flags, mode_t mode) {
246 if (!orig_openat)
247 orig_openat = (orig_openat_t)dlsym(RTLD_NEXT, "openat");
248 if (!storage)
249 load_blacklist();
250
251 int rv = orig_openat(dirfd, pathname, flags, mode);
252 if (storage_find(pathname))
253 sendlog(name(), __FUNCTION__, pathname);
254 return rv;
255}
256
257typedef int (*orig_openat64_t)(int dirfd, const char *pathname, int flags, mode_t mode);
258static orig_openat64_t orig_openat64 = NULL;
259int openat64(int dirfd, const char *pathname, int flags, mode_t mode) {
260 if (!orig_openat64)
261 orig_openat64 = (orig_openat64_t)dlsym(RTLD_NEXT, "openat64");
262 if (!storage)
263 load_blacklist();
264
265 int rv = orig_openat64(dirfd, pathname, flags, mode);
266 if (storage_find(pathname))
267 sendlog(name(), __FUNCTION__, pathname);
268 return rv;
269}
270
271
272// fopen
273FILE *fopen(const char *pathname, const char *mode) {
274 if (!orig_fopen)
275 orig_fopen = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen");
276 if (!storage)
277 load_blacklist();
278
279 FILE *rv = orig_fopen(pathname, mode);
280 if (storage_find(pathname))
281 sendlog(name(), __FUNCTION__, pathname);
282 return rv;
283}
284
285#ifdef __GLIBC__
286FILE *fopen64(const char *pathname, const char *mode) {
287 if (!orig_fopen64)
288 orig_fopen64 = (orig_fopen_t)dlsym(RTLD_NEXT, "fopen64");
289 if (!storage)
290 load_blacklist();
291
292 FILE *rv = orig_fopen64(pathname, mode);
293 if (storage_find(pathname))
294 sendlog(name(), __FUNCTION__, pathname);
295 return rv;
296}
297#endif /* __GLIBC__ */
298
299
300// freopen
301typedef FILE *(*orig_freopen_t)(const char *pathname, const char *mode, FILE *stream);
302static orig_freopen_t orig_freopen = NULL;
303FILE *freopen(const char *pathname, const char *mode, FILE *stream) {
304 if (!orig_freopen)
305 orig_freopen = (orig_freopen_t)dlsym(RTLD_NEXT, "freopen");
306 if (!storage)
307 load_blacklist();
308
309 FILE *rv = orig_freopen(pathname, mode, stream);
310 if (storage_find(pathname))
311 sendlog(name(), __FUNCTION__, pathname);
312 return rv;
313}
314
315#ifdef __GLIBC__
316typedef FILE *(*orig_freopen64_t)(const char *pathname, const char *mode, FILE *stream);
317static orig_freopen64_t orig_freopen64 = NULL;
318FILE *freopen64(const char *pathname, const char *mode, FILE *stream) {
319 if (!orig_freopen64)
320 orig_freopen64 = (orig_freopen64_t)dlsym(RTLD_NEXT, "freopen64");
321 if (!storage)
322 load_blacklist();
323
324 FILE *rv = orig_freopen64(pathname, mode, stream);
325 if (storage_find(pathname))
326 sendlog(name(), __FUNCTION__, pathname);
327 return rv;
328}
329#endif /* __GLIBC__ */
330
331// unlink
332typedef int (*orig_unlink_t)(const char *pathname);
333static orig_unlink_t orig_unlink = NULL;
334int unlink(const char *pathname) {
335 if (!orig_unlink)
336 orig_unlink = (orig_unlink_t)dlsym(RTLD_NEXT, "unlink");
337 if (!storage)
338 load_blacklist();
339
340 int rv = orig_unlink(pathname);
341 if (storage_find(pathname))
342 sendlog(name(), __FUNCTION__, pathname);
343 return rv;
344}
345
346typedef int (*orig_unlinkat_t)(int dirfd, const char *pathname, int flags);
347static orig_unlinkat_t orig_unlinkat = NULL;
348int unlinkat(int dirfd, const char *pathname, int flags) {
349 if (!orig_unlinkat)
350 orig_unlinkat = (orig_unlinkat_t)dlsym(RTLD_NEXT, "unlinkat");
351 if (!storage)
352 load_blacklist();
353
354 int rv = orig_unlinkat(dirfd, pathname, flags);
355 if (storage_find(pathname))
356 sendlog(name(), __FUNCTION__, pathname);
357 return rv;
358}
359
360// mkdir/mkdirat/rmdir
361typedef int (*orig_mkdir_t)(const char *pathname, mode_t mode);
362static orig_mkdir_t orig_mkdir = NULL;
363int mkdir(const char *pathname, mode_t mode) {
364 if (!orig_mkdir)
365 orig_mkdir = (orig_mkdir_t)dlsym(RTLD_NEXT, "mkdir");
366 if (!storage)
367 load_blacklist();
368
369 int rv = orig_mkdir(pathname, mode);
370 if (storage_find(pathname))
371 sendlog(name(), __FUNCTION__, pathname);
372 return rv;
373}
374
375typedef int (*orig_mkdirat_t)(int dirfd, const char *pathname, mode_t mode);
376static orig_mkdirat_t orig_mkdirat = NULL;
377int mkdirat(int dirfd, const char *pathname, mode_t mode) {
378 if (!orig_mkdirat)
379 orig_mkdirat = (orig_mkdirat_t)dlsym(RTLD_NEXT, "mkdirat");
380 if (!storage)
381 load_blacklist();
382
383 int rv = orig_mkdirat(dirfd, pathname, mode);
384 if (storage_find(pathname))
385 sendlog(name(), __FUNCTION__, pathname);
386 return rv;
387}
388
389typedef int (*orig_rmdir_t)(const char *pathname);
390static orig_rmdir_t orig_rmdir = NULL;
391int rmdir(const char *pathname) {
392 if (!orig_rmdir)
393 orig_rmdir = (orig_rmdir_t)dlsym(RTLD_NEXT, "rmdir");
394 if (!storage)
395 load_blacklist();
396
397 int rv = orig_rmdir(pathname);
398 if (storage_find(pathname))
399 sendlog(name(), __FUNCTION__, pathname);
400 return rv;
401}
402
403// stat
404typedef int (*orig_stat_t)(const char *pathname, struct stat *buf);
405static orig_stat_t orig_stat = NULL;
406int stat(const char *pathname, struct stat *buf) {
407 if (!orig_stat)
408 orig_stat = (orig_stat_t)dlsym(RTLD_NEXT, "stat");
409 if (!storage)
410 load_blacklist();
411
412 int rv = orig_stat(pathname, buf);
413 if (storage_find(pathname))
414 sendlog(name(), __FUNCTION__, pathname);
415 return rv;
416}
417
418#ifdef __GLIBC__
419typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf);
420static orig_stat64_t orig_stat64 = NULL;
421int stat64(const char *pathname, struct stat64 *buf) {
422 if (!orig_stat)
423 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
424 if (!storage)
425 load_blacklist();
426
427 int rv = orig_stat64(pathname, buf);
428 if (storage_find(pathname))
429 sendlog(name(), __FUNCTION__, pathname);
430 return rv;
431}
432#endif /* __GLIBC__ */
433
434typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf);
435static orig_lstat_t orig_lstat = NULL;
436int lstat(const char *pathname, struct stat *buf) {
437 if (!orig_lstat)
438 orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat");
439 if (!storage)
440 load_blacklist();
441
442 int rv = orig_lstat(pathname, buf);
443 if (storage_find(pathname))
444 sendlog(name(), __FUNCTION__, pathname);
445 return rv;
446}
447
448#ifdef __GLIBC__
449typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf);
450static orig_lstat64_t orig_lstat64 = NULL;
451int lstat64(const char *pathname, struct stat64 *buf) {
452 if (!orig_lstat)
453 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64");
454 if (!storage)
455 load_blacklist();
456
457 int rv = orig_lstat64(pathname, buf);
458 if (storage_find(pathname))
459 sendlog(name(), __FUNCTION__, pathname);
460 return rv;
461}
462#endif /* __GLIBC__ */
463
464// access
465typedef int (*orig_access_t)(const char *pathname, int mode);
466static orig_access_t orig_access = NULL;
467int access(const char *pathname, int mode) {
468 if (!orig_access)
469 orig_access = (orig_access_t)dlsym(RTLD_NEXT, "access");
470 if (!storage)
471 load_blacklist();
472
473 int rv = orig_access(pathname, mode);
474 if (storage_find(pathname))
475 sendlog(name(), __FUNCTION__, pathname);
476 return rv;
477}
478
479// opendir
480typedef DIR *(*orig_opendir_t)(const char *pathname);
481static orig_opendir_t orig_opendir = NULL;
482DIR *opendir(const char *pathname) {
483 if (!orig_opendir)
484 orig_opendir = (orig_opendir_t)dlsym(RTLD_NEXT, "opendir");
485 if (!storage)
486 load_blacklist();
487
488 DIR *rv = orig_opendir(pathname);
489 if (storage_find(pathname))
490 sendlog(name(), __FUNCTION__, pathname);
491 return rv;
492}
493
494