diff options
Diffstat (limited to 'src/firejail/checkcfg.c')
-rw-r--r-- | src/firejail/checkcfg.c | 234 |
1 files changed, 232 insertions, 2 deletions
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 430b0c5a6..78c0e5c60 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -19,15 +19,17 @@ | |||
19 | */ | 19 | */ |
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/stat.h> | 21 | #include <sys/stat.h> |
22 | #include <linux/loop.h> | ||
22 | 23 | ||
23 | #define MAX_READ 8192 // line buffer for profile files | 24 | #define MAX_READ 8192 // line buffer for profile files |
24 | 25 | ||
25 | static int initialized = 0; | 26 | static int initialized = 0; |
26 | static int cfg_val[CFG_MAX]; | 27 | static int cfg_val[CFG_MAX]; |
27 | char *xephyr_screen = "800x600"; | 28 | char *xephyr_screen = "800x600"; |
29 | char *xephyr_extra_params = ""; | ||
30 | char *netfilter_default = NULL; | ||
28 | 31 | ||
29 | int checkcfg(int val) { | 32 | int checkcfg(int val) { |
30 | EUID_ASSERT(); | ||
31 | assert(val < CFG_MAX); | 33 | assert(val < CFG_MAX); |
32 | int line = 0; | 34 | int line = 0; |
33 | 35 | ||
@@ -37,6 +39,8 @@ int checkcfg(int val) { | |||
37 | for (i = 0; i < CFG_MAX; i++) | 39 | for (i = 0; i < CFG_MAX; i++) |
38 | cfg_val[i] = 1; // most of them are enabled by default | 40 | cfg_val[i] = 1; // most of them are enabled by default |
39 | cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default | 41 | cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default |
42 | cfg_val[CFG_FORCE_NONEWPRIVS] = 0; // disabled by default | ||
43 | cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0; // disabled by default | ||
40 | 44 | ||
41 | // open configuration file | 45 | // open configuration file |
42 | char *fname; | 46 | char *fname; |
@@ -45,10 +49,24 @@ int checkcfg(int val) { | |||
45 | 49 | ||
46 | FILE *fp = fopen(fname, "r"); | 50 | FILE *fp = fopen(fname, "r"); |
47 | if (!fp) { | 51 | if (!fp) { |
52 | #ifdef HAVE_GLOBALCFG | ||
48 | fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname); | 53 | fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname); |
49 | exit(1); | 54 | exit(1); |
55 | #else | ||
56 | initialized = 1; | ||
57 | return cfg_val[val]; | ||
58 | #endif | ||
50 | } | 59 | } |
51 | 60 | ||
61 | // if the file exists, it should be owned by root | ||
62 | struct stat s; | ||
63 | if (stat(fname, &s) == -1) | ||
64 | errExit("stat"); | ||
65 | if (s.st_uid != 0) { | ||
66 | fprintf(stderr, "Error: configuration file should be owned by root\n"); | ||
67 | exit(1); | ||
68 | } | ||
69 | |||
52 | // read configuration file | 70 | // read configuration file |
53 | char buf[MAX_READ]; | 71 | char buf[MAX_READ]; |
54 | while (fgets(buf,MAX_READ, fp)) { | 72 | while (fgets(buf,MAX_READ, fp)) { |
@@ -106,6 +124,15 @@ int checkcfg(int val) { | |||
106 | else | 124 | else |
107 | goto errout; | 125 | goto errout; |
108 | } | 126 | } |
127 | // nonewprivs | ||
128 | else if (strncmp(ptr, "force-nonewprivs ", 17) == 0) { | ||
129 | if (strcmp(ptr + 17, "yes") == 0) | ||
130 | cfg_val[CFG_SECCOMP] = 1; | ||
131 | else if (strcmp(ptr + 17, "no") == 0) | ||
132 | cfg_val[CFG_SECCOMP] = 0; | ||
133 | else | ||
134 | goto errout; | ||
135 | } | ||
109 | // seccomp | 136 | // seccomp |
110 | else if (strncmp(ptr, "seccomp ", 8) == 0) { | 137 | else if (strncmp(ptr, "seccomp ", 8) == 0) { |
111 | if (strcmp(ptr + 8, "yes") == 0) | 138 | if (strcmp(ptr + 8, "yes") == 0) |
@@ -115,6 +142,15 @@ int checkcfg(int val) { | |||
115 | else | 142 | else |
116 | goto errout; | 143 | goto errout; |
117 | } | 144 | } |
145 | // whitelist | ||
146 | else if (strncmp(ptr, "whitelist ", 10) == 0) { | ||
147 | if (strcmp(ptr + 10, "yes") == 0) | ||
148 | cfg_val[CFG_WHITELIST] = 1; | ||
149 | else if (strcmp(ptr + 10, "no") == 0) | ||
150 | cfg_val[CFG_WHITELIST] = 0; | ||
151 | else | ||
152 | goto errout; | ||
153 | } | ||
118 | // network | 154 | // network |
119 | else if (strncmp(ptr, "network ", 8) == 0) { | 155 | else if (strncmp(ptr, "network ", 8) == 0) { |
120 | if (strcmp(ptr + 8, "yes") == 0) | 156 | if (strcmp(ptr + 8, "yes") == 0) |
@@ -133,6 +169,28 @@ int checkcfg(int val) { | |||
133 | else | 169 | else |
134 | goto errout; | 170 | goto errout; |
135 | } | 171 | } |
172 | // netfilter | ||
173 | else if (strncmp(ptr, "netfilter-default ", 18) == 0) { | ||
174 | char *fname = ptr + 18; | ||
175 | while (*fname == ' ' || *fname == '\t') | ||
176 | ptr++; | ||
177 | char *end = strchr(fname, ' '); | ||
178 | if (end) | ||
179 | *end = '\0'; | ||
180 | |||
181 | // is the file present? | ||
182 | struct stat s; | ||
183 | if (stat(fname, &s) == -1) { | ||
184 | fprintf(stderr, "Error: netfilter-default file %s not available\n", fname); | ||
185 | exit(1); | ||
186 | } | ||
187 | |||
188 | netfilter_default = strdup(fname); | ||
189 | if (!netfilter_default) | ||
190 | errExit("strdup"); | ||
191 | if (arg_debug) | ||
192 | printf("netfilter default file %s\n", fname); | ||
193 | } | ||
136 | 194 | ||
137 | // Xephyr screen size | 195 | // Xephyr screen size |
138 | else if (strncmp(ptr, "xephyr-screen ", 14) == 0) { | 196 | else if (strncmp(ptr, "xephyr-screen ", 14) == 0) { |
@@ -145,9 +203,73 @@ int checkcfg(int val) { | |||
145 | if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1) | 203 | if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1) |
146 | errExit("asprintf"); | 204 | errExit("asprintf"); |
147 | } | 205 | } |
206 | |||
207 | // xephyr window title | ||
208 | else if (strncmp(ptr, "xephyr-window-title ", 20) == 0) { | ||
209 | if (strcmp(ptr + 20, "yes") == 0) | ||
210 | cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 1; | ||
211 | else if (strcmp(ptr + 20, "no") == 0) | ||
212 | cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 0; | ||
213 | else | ||
214 | goto errout; | ||
215 | } | ||
216 | |||
217 | // Xephyr command extra parameters | ||
218 | else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) { | ||
219 | xephyr_extra_params = strdup(ptr + 19); | ||
220 | if (!xephyr_extra_params) | ||
221 | errExit("strdup"); | ||
222 | } | ||
223 | |||
224 | // quiet by default | ||
225 | else if (strncmp(ptr, "quiet-by-default ", 17) == 0) { | ||
226 | if (strcmp(ptr + 17, "yes") == 0) | ||
227 | arg_quiet = 1; | ||
228 | } | ||
229 | // remount /proc and /sys | ||
230 | else if (strncmp(ptr, "remount-proc-sys ", 17) == 0) { | ||
231 | if (strcmp(ptr + 17, "yes") == 0) | ||
232 | cfg_val[CFG_REMOUNT_PROC_SYS] = 1; | ||
233 | else if (strcmp(ptr + 17, "no") == 0) | ||
234 | cfg_val[CFG_REMOUNT_PROC_SYS] = 0; | ||
235 | else | ||
236 | goto errout; | ||
237 | } | ||
238 | else if (strncmp(ptr, "overlayfs ", 10) == 0) { | ||
239 | if (strcmp(ptr + 10, "yes") == 0) | ||
240 | cfg_val[CFG_OVERLAYFS] = 1; | ||
241 | else if (strcmp(ptr + 10, "no") == 0) | ||
242 | cfg_val[CFG_OVERLAYFS] = 0; | ||
243 | else | ||
244 | goto errout; | ||
245 | } | ||
246 | else if (strncmp(ptr, "private-home ", 13) == 0) { | ||
247 | if (strcmp(ptr + 13, "yes") == 0) | ||
248 | cfg_val[CFG_PRIVATE_HOME] = 1; | ||
249 | else if (strcmp(ptr + 13, "no") == 0) | ||
250 | cfg_val[CFG_PRIVATE_HOME] = 0; | ||
251 | else | ||
252 | goto errout; | ||
253 | } | ||
254 | else if (strncmp(ptr, "chroot-desktop ", 15) == 0) { | ||
255 | if (strcmp(ptr + 15, "yes") == 0) | ||
256 | cfg_val[CFG_CHROOT_DESKTOP] = 1; | ||
257 | else if (strcmp(ptr + 15, "no") == 0) | ||
258 | cfg_val[CFG_CHROOT_DESKTOP] = 0; | ||
259 | else | ||
260 | goto errout; | ||
261 | } | ||
262 | else if (strncmp(ptr, "private-bin-no-local ", 21) == 0) { | ||
263 | if (strcmp(ptr + 21, "yes") == 0) | ||
264 | cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 1; | ||
265 | else if (strcmp(ptr + 21, "no") == 0) | ||
266 | cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0; | ||
267 | else | ||
268 | goto errout; | ||
269 | } | ||
148 | else | 270 | else |
149 | goto errout; | 271 | goto errout; |
150 | 272 | ||
151 | free(ptr); | 273 | free(ptr); |
152 | } | 274 | } |
153 | 275 | ||
@@ -163,3 +285,111 @@ errout: | |||
163 | exit(1); | 285 | exit(1); |
164 | } | 286 | } |
165 | 287 | ||
288 | |||
289 | void print_compiletime_support(void) { | ||
290 | printf("Compile time support:\n"); | ||
291 | printf("\t- AppArmor support is %s\n", | ||
292 | #ifdef HAVE_APPARMOR | ||
293 | "enabled" | ||
294 | #else | ||
295 | "disabled" | ||
296 | #endif | ||
297 | ); | ||
298 | |||
299 | printf("\t- AppImage support is %s\n", | ||
300 | #ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h | ||
301 | "enabled" | ||
302 | #else | ||
303 | "disabled" | ||
304 | #endif | ||
305 | ); | ||
306 | |||
307 | |||
308 | |||
309 | |||
310 | |||
311 | printf("\t- bind support is %s\n", | ||
312 | #ifdef HAVE_BIND | ||
313 | "enabled" | ||
314 | #else | ||
315 | "disabled" | ||
316 | #endif | ||
317 | ); | ||
318 | |||
319 | printf("\t- chroot support is %s\n", | ||
320 | #ifdef HAVE_CHROOT | ||
321 | "enabled" | ||
322 | #else | ||
323 | "disabled" | ||
324 | #endif | ||
325 | ); | ||
326 | |||
327 | printf("\t- file and directory whitelisting support is %s\n", | ||
328 | #ifdef HAVE_WHITELIST | ||
329 | "enabled" | ||
330 | #else | ||
331 | "disabled" | ||
332 | #endif | ||
333 | ); | ||
334 | |||
335 | printf("\t- file transfer support is %s\n", | ||
336 | #ifdef HAVE_FILE_TRANSFER | ||
337 | "enabled" | ||
338 | #else | ||
339 | "disabled" | ||
340 | #endif | ||
341 | ); | ||
342 | |||
343 | printf("\t- networking support is %s\n", | ||
344 | #ifdef HAVE_NETWORK | ||
345 | "enabled" | ||
346 | #else | ||
347 | "disabled" | ||
348 | #endif | ||
349 | ); | ||
350 | |||
351 | |||
352 | #ifdef HAVE_NETWORK_RESTRICTED | ||
353 | printf("\t- networking features are available only to root user\n"); | ||
354 | #endif | ||
355 | |||
356 | printf("\t- overlayfs support is %s\n", | ||
357 | #ifdef HAVE_OVERLAYFS | ||
358 | "enabled" | ||
359 | #else | ||
360 | "disabled" | ||
361 | #endif | ||
362 | ); | ||
363 | |||
364 | printf("\t- private-home support is %s\n", | ||
365 | #ifdef HAVE_PRIVATE_HOME | ||
366 | "enabled" | ||
367 | #else | ||
368 | "disabled" | ||
369 | #endif | ||
370 | ); | ||
371 | |||
372 | printf("\t- seccomp-bpf support is %s\n", | ||
373 | #ifdef HAVE_SECCOMP | ||
374 | "enabled" | ||
375 | #else | ||
376 | "disabled" | ||
377 | #endif | ||
378 | ); | ||
379 | |||
380 | printf("\t- user namespace support is %s\n", | ||
381 | #ifdef HAVE_USERNS | ||
382 | "enabled" | ||
383 | #else | ||
384 | "disabled" | ||
385 | #endif | ||
386 | ); | ||
387 | |||
388 | printf("\t- X11 sandboxing support is %s\n", | ||
389 | #ifdef HAVE_X11 | ||
390 | "enabled" | ||
391 | #else | ||
392 | "disabled" | ||
393 | #endif | ||
394 | ); | ||
395 | } | ||