aboutsummaryrefslogtreecommitdiffstats
path: root/src/fbuilder/build_fs.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-09-16 08:49:05 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-09-16 08:49:05 -0400
commit280f37eba89ebc211d0c02848d3d47d086458b25 (patch)
tree1398c5dfc53c4d286d7b6b528d5a3c1585a67325 /src/fbuilder/build_fs.c
parentMerge pull request #1552 from SpotComms/mf (diff)
downloadfirejail-280f37eba89ebc211d0c02848d3d47d086458b25.tar.gz
firejail-280f37eba89ebc211d0c02848d3d47d086458b25.tar.zst
firejail-280f37eba89ebc211d0c02848d3d47d086458b25.zip
--build
Diffstat (limited to 'src/fbuilder/build_fs.c')
-rw-r--r--src/fbuilder/build_fs.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
new file mode 100644
index 000000000..76281a54d
--- /dev/null
+++ b/src/fbuilder/build_fs.c
@@ -0,0 +1,276 @@
1/*
2 * Copyright (C) 2014-2017 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 "fbuilder.h"
22
23// common file processing function, using the callback for each line in the file
24static void process_file(const char *fname, const char *dir, void (*callback)(char *)) {
25 assert(fname);
26 assert(dir);
27 assert(callback);
28
29 int dir_len = strlen(dir);
30
31 // process trace file
32 FILE *fp = fopen(fname, "r");
33 if (!fp) {
34 fprintf(stderr, "Error: cannot open %s\n", fname);
35 exit(1);
36 }
37
38 char buf[MAX_BUF];
39 while (fgets(buf, MAX_BUF, fp)) {
40 // remove \n
41 char *ptr = strchr(buf, '\n');
42 if (ptr)
43 *ptr = '\0';
44
45 // parse line: 4:galculator:access /etc/fonts/conf.d:0
46 // number followed by :
47 ptr = buf;
48 if (!isdigit(*ptr))
49 continue;
50 while (isdigit(*ptr))
51 ptr++;
52 if (*ptr != ':')
53 continue;
54 ptr++;
55
56 // next :
57 ptr = strchr(ptr, ':');
58 if (!ptr)
59 continue;
60 ptr++;
61 if (strncmp(ptr, "access ", 7) == 0)
62 ptr += 7;
63 else if (strncmp(ptr, "fopen ", 6) == 0)
64 ptr += 6;
65 else if (strncmp(ptr, "fopen64 ", 8) == 0)
66 ptr += 8;
67 else if (strncmp(ptr, "open64 ", 7) == 0)
68 ptr += 7;
69 else if (strncmp(ptr, "open ", 5) == 0)
70 ptr += 5;
71 else
72 continue;
73 if (strncmp(ptr, dir, dir_len) != 0)
74 continue;
75
76 // end of filename
77 char *ptr2 = strchr(ptr, ':');
78 if (!ptr2)
79 continue;
80 *ptr2 = '\0';
81
82 callback(ptr);
83 }
84
85 fclose(fp);
86}
87
88// process fname, fname.1, fname.2, fname.3, fname.4, fname.5
89static void process_files(const char *fname, const char *dir, void (*callback)(char *)) {
90 assert(fname);
91 assert(dir);
92 assert(callback);
93
94 // run fname
95 process_file(fname, dir, callback);
96
97 // run all the rest
98 struct stat s;
99 int i;
100 for (i = 1; i <= 5; i++) {
101 char *newname;
102 if (asprintf(&newname, "%s.%d", fname, i) == -1)
103 errExit("asprintf");
104 if (stat(newname, &s) == 0)
105 process_file(newname, dir, callback);
106 free(newname);
107 }
108}
109
110//*******************************************
111// etc directory
112//*******************************************
113static FileDB *etc_out = NULL;
114
115static void etc_callback(char *ptr) {
116 // skip firejail directory
117 if (strncmp(ptr, "/etc/firejail", 13) == 0)
118 return;
119
120 // add only top files and directories
121 ptr += 5; // skip "/etc/"
122 char *end = strchr(ptr, '/');
123 if (end)
124 *end = '\0';
125 etc_out = filedb_add(etc_out, ptr);
126}
127
128void build_etc(const char *fname) {
129 assert(fname);
130
131 process_files(fname, "/etc", etc_callback);
132
133 printf("private-etc ");
134 if (etc_out == NULL)
135 printf("none\n");
136 else {
137 FileDB *ptr = etc_out;
138 while (ptr) {
139 printf("%s,", ptr->fname);
140 ptr = ptr->next;
141 }
142 printf("\n");
143 }
144}
145
146//*******************************************
147// var directory
148//*******************************************
149static FileDB *var_out = NULL;
150static void var_callback(char *ptr) {
151 if (strncmp(ptr, "/var/lib/menu-xdg", 17) == 0)
152 var_out = filedb_add(var_out, "/var/lib/menu-xdg");
153 else if (strncmp(ptr, "/var/cache/fontconfig", 21) == 0)
154 var_out = filedb_add(var_out, "/var/cache/fontconfig");
155 else
156 var_out = filedb_add(var_out, ptr);
157}
158
159void build_var(const char *fname) {
160 assert(fname);
161
162 process_files(fname, "/var", var_callback);
163
164 if (var_out == NULL)
165 printf("blacklist /var\n");
166 else
167 filedb_print(var_out, "whitelist ");
168}
169
170//*******************************************
171// tmp directory
172//*******************************************
173static FileDB *tmp_out = NULL;
174static void tmp_callback(char *ptr) {
175 filedb_add(tmp_out, ptr);
176}
177
178void build_tmp(const char *fname) {
179 assert(fname);
180
181 process_files(fname, "/tmp", tmp_callback);
182
183 if (tmp_out == NULL)
184 printf("private-tmp\n");
185 else {
186 printf("\n");
187 printf("# private-tmp\n");
188 printf("# File accessed in /tmp directory:\n");
189 printf("# ");
190 FileDB *ptr = tmp_out;
191 while (ptr) {
192 printf("%s,", ptr->fname);
193 ptr = ptr->next;
194 }
195 printf("\n");
196 }
197}
198
199//*******************************************
200// dev directory
201//*******************************************
202static char *dev_skip[] = {
203 "/dev/zero",
204 "/dev/null",
205 "/dev/full",
206 "/dev/random",
207 "/dev/urandom",
208 "/dev/tty",
209 "/dev/snd",
210 "/dev/dri",
211 "/dev/pts",
212 "/dev/nvidia0",
213 "/dev/nvidia1",
214 "/dev/nvidia2",
215 "/dev/nvidia3",
216 "/dev/nvidia4",
217 "/dev/nvidia5",
218 "/dev/nvidia6",
219 "/dev/nvidia7",
220 "/dev/nvidia8",
221 "/dev/nvidia9",
222 "/dev/nvidiactl",
223 "/dev/nvidia-modeset",
224 "/dev/nvidia-uvm",
225 "/dev/video0",
226 "/dev/video1",
227 "/dev/video2",
228 "/dev/video3",
229 "/dev/video4",
230 "/dev/video5",
231 "/dev/video6",
232 "/dev/video7",
233 "/dev/video8",
234 "/dev/video9",
235 "/dev/dvb",
236 "/dev/sr0",
237 NULL
238};
239
240static FileDB *dev_out = NULL;
241static void dev_callback(char *ptr) {
242 // skip private-dev devices
243 int i = 0;
244 int found = 0;
245 while (dev_skip[i]) {
246 if (strcmp(ptr, dev_skip[i]) == 0) {
247 found = 1;
248 break;
249 }
250 i++;
251 }
252 if (!found)
253 filedb_add(dev_out, ptr);
254}
255
256void build_dev(const char *fname) {
257 assert(fname);
258
259 process_files(fname, "/tmp", tmp_callback);
260
261 if (dev_out == NULL)
262 printf("private-dev\n");
263 else {
264 printf("\n");
265 printf("# private-dev\n");
266 printf("# This is the list of devices accessed (on top of regular private-dev devices:\n");
267 printf("# ");
268 FileDB *ptr = dev_out;
269 while (ptr) {
270 printf("%s,", ptr->fname);
271 ptr = ptr->next;
272 }
273 printf("\n");
274 }
275}
276