diff options
-rw-r--r-- | src/firejail/fs.c | 7 | ||||
-rw-r--r-- | src/firejail/main.c | 340 | ||||
-rw-r--r-- | todo | 26 |
3 files changed, 193 insertions, 180 deletions
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index cec170521..6beac3227 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -605,13 +605,6 @@ void fs_overlayfs(void) { | |||
605 | 605 | ||
606 | char *basedir = MNT_DIR; | 606 | char *basedir = MNT_DIR; |
607 | if (arg_overlay_keep) { | 607 | if (arg_overlay_keep) { |
608 | // check the directory exists | ||
609 | struct stat s; | ||
610 | if (stat("/myoverlay", &s) == -1) { | ||
611 | fprintf(stderr, "Error: overlay directory should already exist\n"); | ||
612 | exit(1); | ||
613 | } | ||
614 | |||
615 | // set base for working and diff directories | 608 | // set base for working and diff directories |
616 | basedir = cfg.overlay_dir; | 609 | basedir = cfg.overlay_dir; |
617 | if (mkdir(basedir, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { | 610 | if (mkdir(basedir, S_IRWXU | S_IRWXG | S_IRWXO) != 0) { |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 5d895c4a0..2a56d1725 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -232,6 +232,163 @@ void check_user_namespace(void) { | |||
232 | } | 232 | } |
233 | } | 233 | } |
234 | 234 | ||
235 | // exit commands | ||
236 | static void run_cmd_and_exit(int i, int argc, char **argv) { | ||
237 | //************************************* | ||
238 | // basic arguments | ||
239 | //************************************* | ||
240 | if (strcmp(argv[i], "--help") == 0 || | ||
241 | strcmp(argv[i], "-?") == 0) { | ||
242 | usage(); | ||
243 | exit(0); | ||
244 | } | ||
245 | else if (strcmp(argv[i], "--version") == 0) { | ||
246 | printf("firejail version %s\n", VERSION); | ||
247 | exit(0); | ||
248 | } | ||
249 | else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { | ||
250 | logargs(argc, argv); | ||
251 | |||
252 | // extract the command | ||
253 | if ((i + 1) == argc) { | ||
254 | fprintf(stderr, "Error: command expected after --bandwidth option\n"); | ||
255 | exit(1); | ||
256 | } | ||
257 | char *cmd = argv[i + 1]; | ||
258 | if (strcmp(cmd, "status") && strcmp(cmd, "clear") && strcmp(cmd, "set")) { | ||
259 | fprintf(stderr, "Error: invalid --bandwidth command\n"); | ||
260 | exit(1); | ||
261 | } | ||
262 | |||
263 | // extract network name | ||
264 | char *dev = NULL; | ||
265 | int down = 0; | ||
266 | int up = 0; | ||
267 | if (strcmp(cmd, "set") == 0 || strcmp(cmd, "clear") == 0) { | ||
268 | // extract device name | ||
269 | if ((i + 2) == argc) { | ||
270 | fprintf(stderr, "Error: network name expected after --bandwidth %s option\n", cmd); | ||
271 | exit(1); | ||
272 | } | ||
273 | dev = argv[i + 2]; | ||
274 | |||
275 | // check device name | ||
276 | if (if_nametoindex(dev) == 0) { | ||
277 | fprintf(stderr, "Error: network device %s not found\n", dev); | ||
278 | exit(1); | ||
279 | } | ||
280 | |||
281 | // extract bandwidth | ||
282 | if (strcmp(cmd, "set") == 0) { | ||
283 | if ((i + 4) >= argc) { | ||
284 | fprintf(stderr, "Error: invalid --bandwidth set command\n"); | ||
285 | exit(1); | ||
286 | } | ||
287 | |||
288 | down = atoi(argv[i + 3]); | ||
289 | if (down < 0) { | ||
290 | fprintf(stderr, "Error: invalid download speed\n"); | ||
291 | exit(1); | ||
292 | } | ||
293 | up = atoi(argv[i + 4]); | ||
294 | if (up < 0) { | ||
295 | fprintf(stderr, "Error: invalid upload speed\n"); | ||
296 | exit(1); | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | |||
301 | // extract pid or sandbox name | ||
302 | pid_t pid; | ||
303 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
304 | bandwidth_pid(pid, cmd, dev, down, up); | ||
305 | else | ||
306 | bandwidth_name(argv[i] + 12, cmd, dev, down, up); | ||
307 | exit(0); | ||
308 | } | ||
309 | |||
310 | //************************************* | ||
311 | // independent commands - the program will exit! | ||
312 | //************************************* | ||
313 | #ifdef HAVE_SECCOMP | ||
314 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { | ||
315 | syscall_print(); | ||
316 | exit(0); | ||
317 | } | ||
318 | else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { | ||
319 | // join sandbox by pid or by name | ||
320 | pid_t pid; | ||
321 | if (read_pid(argv[i] + 16, &pid) == 0) | ||
322 | seccomp_print_filter(pid); | ||
323 | else | ||
324 | seccomp_print_filter_name(argv[i] + 16); | ||
325 | exit(0); | ||
326 | } | ||
327 | #endif | ||
328 | else if (strncmp(argv[i], "--caps.print=", 13) == 0) { | ||
329 | // join sandbox by pid or by name | ||
330 | pid_t pid; | ||
331 | if (read_pid(argv[i] + 13, &pid) == 0) | ||
332 | caps_print_filter(pid); | ||
333 | else | ||
334 | caps_print_filter_name(argv[i] + 13); | ||
335 | exit(0); | ||
336 | } | ||
337 | |||
338 | else if (strncmp(argv[i], "--dns.print=", 12) == 0) { | ||
339 | // join sandbox by pid or by name | ||
340 | pid_t pid; | ||
341 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
342 | net_dns_print(pid); | ||
343 | else | ||
344 | net_dns_print_name(argv[i] + 12); | ||
345 | exit(0); | ||
346 | } | ||
347 | else if (strcmp(argv[i], "--debug-caps") == 0) { | ||
348 | caps_print(); | ||
349 | exit(0); | ||
350 | } | ||
351 | else if (strcmp(argv[i], "--list") == 0) { | ||
352 | list(); | ||
353 | exit(0); | ||
354 | } | ||
355 | else if (strcmp(argv[i], "--tree") == 0) { | ||
356 | tree(); | ||
357 | exit(0); | ||
358 | } | ||
359 | else if (strcmp(argv[i], "--top") == 0) { | ||
360 | top(); | ||
361 | exit(0); | ||
362 | } | ||
363 | else if (strcmp(argv[i], "--netstats") == 0) { | ||
364 | netstats(); | ||
365 | exit(0); | ||
366 | } | ||
367 | else if (strncmp(argv[i], "--join=", 7) == 0) { | ||
368 | logargs(argc, argv); | ||
369 | |||
370 | // join sandbox by pid or by name | ||
371 | pid_t pid; | ||
372 | if (read_pid(argv[i] + 7, &pid) == 0) | ||
373 | join(pid, cfg.homedir, argc, argv, i + 1); | ||
374 | else | ||
375 | join_name(argv[i] + 7, cfg.homedir, argc, argv, i + 1); | ||
376 | exit(0); | ||
377 | } | ||
378 | else if (strncmp(argv[i], "--shutdown=", 11) == 0) { | ||
379 | logargs(argc, argv); | ||
380 | |||
381 | // shutdown sandbox by pid or by name | ||
382 | pid_t pid; | ||
383 | if (read_pid(argv[i] + 11, &pid) == 0) | ||
384 | shut(pid); | ||
385 | else | ||
386 | shut_name(argv[i] + 11); | ||
387 | exit(0); | ||
388 | } | ||
389 | |||
390 | } | ||
391 | |||
235 | //******************************************* | 392 | //******************************************* |
236 | // Main program | 393 | // Main program |
237 | //******************************************* | 394 | //******************************************* |
@@ -243,13 +400,6 @@ int main(int argc, char **argv) { | |||
243 | int arg_cgroup = 0; | 400 | int arg_cgroup = 0; |
244 | int custom_profile = 0; // custom profile loaded | 401 | int custom_profile = 0; // custom profile loaded |
245 | 402 | ||
246 | // if a sandbox is already running, start the program directly without sandboxing | ||
247 | if (check_kernel_procs() == 0) { | ||
248 | run_no_sandbox(argc, argv); | ||
249 | // it will never get here! | ||
250 | assert(0); | ||
251 | } | ||
252 | |||
253 | // initialize globals | 403 | // initialize globals |
254 | init_cfg(); | 404 | init_cfg(); |
255 | cfg.original_argv = argv; | 405 | cfg.original_argv = argv; |
@@ -285,173 +435,10 @@ int main(int argc, char **argv) { | |||
285 | 435 | ||
286 | // parse arguments | 436 | // parse arguments |
287 | for (i = 1; i < argc; i++) { | 437 | for (i = 1; i < argc; i++) { |
288 | //************************************* | 438 | run_cmd_and_exit(i, argc, argv); // will exit if the command is recognized |
289 | // basic arguments | 439 | |
290 | //************************************* | 440 | if (strcmp(argv[i], "--debug") == 0) |
291 | if (strcmp(argv[i], "--help") == 0 || | ||
292 | strcmp(argv[i], "-?") == 0) { | ||
293 | usage(); | ||
294 | exit(0); | ||
295 | } | ||
296 | else if (strcmp(argv[i], "--version") == 0) { | ||
297 | printf("firejail version %s\n", VERSION); | ||
298 | exit(0); | ||
299 | } | ||
300 | else if (strcmp(argv[i], "--debug") == 0) | ||
301 | arg_debug = 1; | 441 | arg_debug = 1; |
302 | |||
303 | else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { | ||
304 | logargs(argc, argv); | ||
305 | |||
306 | // extract the command | ||
307 | if ((i + 1) == argc) { | ||
308 | fprintf(stderr, "Error: command expected after --bandwidth option\n"); | ||
309 | exit(1); | ||
310 | } | ||
311 | char *cmd = argv[i + 1]; | ||
312 | if (strcmp(cmd, "status") && strcmp(cmd, "clear") && strcmp(cmd, "set")) { | ||
313 | fprintf(stderr, "Error: invalid --bandwidth command\n"); | ||
314 | exit(1); | ||
315 | } | ||
316 | |||
317 | // extract network name | ||
318 | char *dev = NULL; | ||
319 | int down = 0; | ||
320 | int up = 0; | ||
321 | if (strcmp(cmd, "set") == 0 || strcmp(cmd, "clear") == 0) { | ||
322 | // extract device name | ||
323 | if ((i + 2) == argc) { | ||
324 | fprintf(stderr, "Error: network name expected after --bandwidth %s option\n", cmd); | ||
325 | exit(1); | ||
326 | } | ||
327 | dev = argv[i + 2]; | ||
328 | |||
329 | // check device name | ||
330 | if (if_nametoindex(dev) == 0) { | ||
331 | fprintf(stderr, "Error: network device %s not found\n", dev); | ||
332 | exit(1); | ||
333 | } | ||
334 | |||
335 | // extract bandwidth | ||
336 | if (strcmp(cmd, "set") == 0) { | ||
337 | if ((i + 4) >= argc) { | ||
338 | fprintf(stderr, "Error: invalid --bandwidth set command\n"); | ||
339 | exit(1); | ||
340 | } | ||
341 | |||
342 | down = atoi(argv[i + 3]); | ||
343 | if (down < 0) { | ||
344 | fprintf(stderr, "Error: invalid download speed\n"); | ||
345 | exit(1); | ||
346 | } | ||
347 | up = atoi(argv[i + 4]); | ||
348 | if (up < 0) { | ||
349 | fprintf(stderr, "Error: invalid upload speed\n"); | ||
350 | exit(1); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
355 | // extract pid or sandbox name | ||
356 | pid_t pid; | ||
357 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
358 | bandwidth_pid(pid, cmd, dev, down, up); | ||
359 | else | ||
360 | bandwidth_name(argv[i] + 12, cmd, dev, down, up); | ||
361 | |||
362 | // it will never get here | ||
363 | exit(0); | ||
364 | } | ||
365 | |||
366 | //************************************* | ||
367 | // independent commands - the program will exit! | ||
368 | //************************************* | ||
369 | #ifdef HAVE_SECCOMP | ||
370 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { | ||
371 | syscall_print(); | ||
372 | exit(0); | ||
373 | } | ||
374 | else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { | ||
375 | // join sandbox by pid or by name | ||
376 | pid_t pid; | ||
377 | if (read_pid(argv[i] + 16, &pid) == 0) | ||
378 | seccomp_print_filter(pid); | ||
379 | else | ||
380 | seccomp_print_filter_name(argv[i] + 16); | ||
381 | |||
382 | // it will never get here!!! | ||
383 | exit(0); | ||
384 | } | ||
385 | #endif | ||
386 | else if (strncmp(argv[i], "--caps.print=", 13) == 0) { | ||
387 | // join sandbox by pid or by name | ||
388 | pid_t pid; | ||
389 | if (read_pid(argv[i] + 13, &pid) == 0) | ||
390 | caps_print_filter(pid); | ||
391 | else | ||
392 | caps_print_filter_name(argv[i] + 13); | ||
393 | |||
394 | // it will never get here!!! | ||
395 | exit(0); | ||
396 | } | ||
397 | |||
398 | else if (strncmp(argv[i], "--dns.print=", 12) == 0) { | ||
399 | // join sandbox by pid or by name | ||
400 | pid_t pid; | ||
401 | if (read_pid(argv[i] + 12, &pid) == 0) | ||
402 | net_dns_print(pid); | ||
403 | else | ||
404 | net_dns_print_name(argv[i] + 12); | ||
405 | |||
406 | // it will never get here!!! | ||
407 | exit(0); | ||
408 | } | ||
409 | else if (strcmp(argv[i], "--debug-caps") == 0) { | ||
410 | caps_print(); | ||
411 | exit(0); | ||
412 | } | ||
413 | else if (strcmp(argv[i], "--list") == 0) { | ||
414 | list(); | ||
415 | exit(0); | ||
416 | } | ||
417 | else if (strcmp(argv[i], "--tree") == 0) { | ||
418 | tree(); | ||
419 | exit(0); | ||
420 | } | ||
421 | else if (strcmp(argv[i], "--top") == 0) { | ||
422 | top(); | ||
423 | exit(0); | ||
424 | } | ||
425 | else if (strcmp(argv[i], "--netstats") == 0) { | ||
426 | netstats(); | ||
427 | exit(0); | ||
428 | } | ||
429 | else if (strncmp(argv[i], "--join=", 7) == 0) { | ||
430 | logargs(argc, argv); | ||
431 | |||
432 | // join sandbox by pid or by name | ||
433 | pid_t pid; | ||
434 | if (read_pid(argv[i] + 7, &pid) == 0) | ||
435 | join(pid, cfg.homedir, argc, argv, i + 1); | ||
436 | else | ||
437 | join_name(argv[i] + 7, cfg.homedir, argc, argv, i + 1); | ||
438 | |||
439 | // it will never get here!!! | ||
440 | exit(0); | ||
441 | } | ||
442 | else if (strncmp(argv[i], "--shutdown=", 11) == 0) { | ||
443 | logargs(argc, argv); | ||
444 | |||
445 | // shutdown sandbox by pid or by name | ||
446 | pid_t pid; | ||
447 | if (read_pid(argv[i] + 11, &pid) == 0) | ||
448 | shut(pid); | ||
449 | else | ||
450 | shut_name(argv[i] + 11); | ||
451 | |||
452 | // it will never get here!!! | ||
453 | exit(0); | ||
454 | } | ||
455 | 442 | ||
456 | //************************************* | 443 | //************************************* |
457 | // filtering | 444 | // filtering |
@@ -998,6 +985,13 @@ int main(int argc, char **argv) { | |||
998 | } | 985 | } |
999 | } | 986 | } |
1000 | 987 | ||
988 | // if a sandbox is already running, start the program directly without sandboxing | ||
989 | if (check_kernel_procs() == 0) { | ||
990 | run_no_sandbox(argc, argv); | ||
991 | // it will never get here! | ||
992 | assert(0); | ||
993 | } | ||
994 | |||
1001 | // check network configuration options - it will exit if anything went wrong | 995 | // check network configuration options - it will exit if anything went wrong |
1002 | net_check_cfg(); | 996 | net_check_cfg(); |
1003 | 997 | ||
@@ -1,2 +1,28 @@ | |||
1 | 1. Deal with .purple directory. It holds the confiig files for pidgin | 1 | 1. Deal with .purple directory. It holds the confiig files for pidgin |
2 | 2 | ||
3 | 2. Startup warnings on Arch Linux: | ||
4 | |||
5 | (all fine here) | ||
6 | $ ./firejail | ||
7 | Parent pid 2495, child pid 2496 | ||
8 | Child process initialized | ||
9 | $ | ||
10 | |||
11 | (warnings) | ||
12 | $ ./firejail --overlay | ||
13 | Parent pid 2500, child pid 2501 | ||
14 | OverlayFS configured in /home/ablive/.firejail/2500 directory | ||
15 | Warning: /var/lock not mounted | ||
16 | Warning: cannot find /var/run/utmp | ||
17 | Warning: failed to unmount /sys | ||
18 | Child process initialized | ||
19 | $ | ||
20 | |||
21 | (warnings) | ||
22 | $ ./firejail --chroot=/media/mylinux | ||
23 | Parent pid 2503, child pid 2504 | ||
24 | Warning: cannot find /var/run/utmp | ||
25 | Dropping all Linux capabilities and enforcing default seccomp filter | ||
26 | Warning: failed to unmount /sys | ||
27 | Child process initialized | ||
28 | $ \ No newline at end of file | ||