aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_logger.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2015-11-27 09:11:05 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2015-11-27 09:11:05 -0500
commit769129a7a2d019ee4535f00cef73be0e70998bbb (patch)
tree5d7220123bd356422dfeeab29fc5972bc97315c9 /src/firejail/fs_logger.c
parentimplemented filesystem log (diff)
downloadfirejail-769129a7a2d019ee4535f00cef73be0e70998bbb.tar.gz
firejail-769129a7a2d019ee4535f00cef73be0e70998bbb.tar.zst
firejail-769129a7a2d019ee4535f00cef73be0e70998bbb.zip
filesystem logger
Diffstat (limited to 'src/firejail/fs_logger.c')
-rw-r--r--src/firejail/fs_logger.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/firejail/fs_logger.c b/src/firejail/fs_logger.c
new file mode 100644
index 000000000..4bf24e749
--- /dev/null
+++ b/src/firejail/fs_logger.c
@@ -0,0 +1,179 @@
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
21#include "firejail.h"
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <unistd.h>
25
26#define MAXBUF 4098
27
28typedef struct fs_msg_t {
29 struct fs_msg_t *next;
30 char *msg;
31} FsMsg;
32
33static FsMsg *head = NULL;
34
35static inline FsMsg *newmsg(void) {
36 FsMsg *ptr = malloc(sizeof(FsMsg));
37 if (!ptr)
38 errExit("malloc");
39 memset(ptr, 0, sizeof(FsMsg));
40 return ptr;
41}
42
43static inline void insertmsg(FsMsg *ptr) {
44 static FsMsg *last = NULL;
45 if (head == NULL) {
46 head = ptr;
47 last = ptr;
48 return;
49 }
50
51 assert(last);
52 last->next = ptr;
53 last = ptr;
54}
55
56void fs_logger(const char *msg) {
57 FsMsg *ptr = newmsg();
58 ptr->msg = strdup(msg);
59 if (!ptr->msg)
60 errExit("strdup");
61 insertmsg(ptr);
62}
63
64void fs_logger2(const char *msg1, const char *msg2) {
65 FsMsg *ptr = newmsg();
66 char *str;
67 if (asprintf(&str, "%s %s", msg1, msg2) == -1)
68 errExit("asprintf");
69 ptr->msg = str;
70 insertmsg(ptr);
71}
72
73void fs_logger3(const char *msg1, const char *msg2, const char *msg3) {
74 FsMsg *ptr = newmsg();
75 char *str;
76 if (asprintf(&str, "%s %s %s", msg1, msg2, msg3) == -1)
77 errExit("asprintf");
78 ptr->msg = str;
79 insertmsg(ptr);
80}
81
82void fs_logger_print(void) {
83 if (!head)
84 return;
85
86 FILE *fp = fopen(RUN_FSLOGGER_FILE, "a");
87 if (!fp) {
88 perror("fopen");
89 return;
90 }
91
92 int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid());
93 rv = chmod(RUN_FSLOGGER_FILE, 0600);
94 (void) rv; // best effort!
95
96 FsMsg *ptr = head;
97 while (ptr) {
98 fprintf(fp, "%s\n", ptr->msg);
99 FsMsg *next = ptr->next;
100 // remove message
101 free(ptr->msg);
102 free(ptr);
103 ptr = next;
104 }
105 head = NULL;
106 fclose(fp);
107}
108
109void fs_logger_change_owner(void) {
110 if (chown(RUN_FSLOGGER_FILE, 0, 0) == -1)
111 errExit("chown");
112}
113
114void fs_logger_print_log_name(const char *name) {
115 if (!name || strlen(name) == 0) {
116 fprintf(stderr, "Error: invalid sandbox name\n");
117 exit(1);
118 }
119 pid_t pid;
120 if (name2pid(name, &pid)) {
121 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
122 exit(1);
123 }
124
125 fs_logger_print_log(pid);
126}
127
128void fs_logger_print_log(pid_t pid) {
129 // if the pid is that of a firejail process, use the pid of the first child process
130 char *comm = pid_proc_comm(pid);
131 if (comm) {
132 // remove \n
133 char *ptr = strchr(comm, '\n');
134 if (ptr)
135 *ptr = '\0';
136 if (strcmp(comm, "firejail") == 0) {
137 pid_t child;
138 if (find_child(pid, &child) == 0) {
139 pid = child;
140 }
141 }
142 free(comm);
143 }
144
145 // check privileges for non-root users
146 uid_t uid = getuid();
147 if (uid != 0) {
148 uid_t sandbox_uid = pid_get_uid(pid);
149 if (uid != sandbox_uid) {
150 fprintf(stderr, "Error: permission denied.\n");
151 exit(1);
152 }
153 }
154
155 // print RUN_FSLOGGER_FILE
156 char *fname;
157 if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_FSLOGGER_FILE) == -1)
158 errExit("asprintf");
159
160 struct stat s;
161 if (stat(fname, &s) == -1) {
162 printf("Cannot access filesystem log.\n");
163 exit(1);
164 }
165
166 FILE *fp = fopen(fname, "r");
167 if (!fp) {
168 printf("Cannot open filesystem log.\n");
169 exit(1);
170 }
171
172 char buf[MAXBUF];
173 while (fgets(buf, MAXBUF, fp))
174 printf("%s", buf);
175 fclose(fp);
176 free(fname);
177
178 exit(0);
179}