diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/Makefile.in | 2 | ||||
-rw-r--r-- | src/firejail/firejail.h | 12 | ||||
-rw-r--r-- | src/firejail/list.c | 101 | ||||
-rw-r--r-- | src/firejail/main.c | 27 | ||||
-rw-r--r-- | src/firejail/network_main.c | 61 | ||||
-rw-r--r-- | src/firejail/protocol.c | 2 | ||||
-rw-r--r-- | src/firejail/sbox.c | 177 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 2 | ||||
-rw-r--r-- | src/fnet/main.c | 11 | ||||
-rw-r--r-- | src/include/seccomp.h (renamed from src/firejail/seccomp.h) | 0 |
10 files changed, 228 insertions, 167 deletions
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in index 7d4bcb19b..c4c168236 100644 --- a/src/firejail/Makefile.in +++ b/src/firejail/Makefile.in | |||
@@ -30,7 +30,7 @@ BINOBJS = $(foreach file, $(OBJS), $file) | |||
30 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security | 30 | CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security |
31 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread | 31 | LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread |
32 | 32 | ||
33 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h | 33 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h |
34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ | 34 | $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ |
35 | 35 | ||
36 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o | 36 | firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 6c0441472..367f599ec 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -25,6 +25,7 @@ | |||
25 | // debug restricted shell | 25 | // debug restricted shell |
26 | //#define DEBUG_RESTRICTED_SHELL | 26 | //#define DEBUG_RESTRICTED_SHELL |
27 | 27 | ||
28 | |||
28 | // filesystem | 29 | // filesystem |
29 | #define RUN_FIREJAIL_BASEDIR "/run" | 30 | #define RUN_FIREJAIL_BASEDIR "/run" |
30 | #define RUN_FIREJAIL_DIR "/run/firejail" | 31 | #define RUN_FIREJAIL_DIR "/run/firejail" |
@@ -681,6 +682,17 @@ long unsigned int appimage2_size(const char *fname); | |||
681 | // cmdline.c | 682 | // cmdline.c |
682 | void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index); | 683 | void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index); |
683 | 684 | ||
685 | // sbox.c | ||
686 | // programs | ||
687 | #define PATH_FNET (LIBDIR "/firejail/fnet") | ||
688 | #define PATH_FIREMON (PREFIX "/bin/firemon") | ||
689 | // bitmapped filters for sbox_run | ||
690 | #define SBOX_ROOT 1 | ||
691 | #define SBOX_USER 2 | ||
692 | #define SBOX_CAPS 4 | ||
693 | #define SBOX_SECCOMP 8 | ||
694 | int sbox_run(unsigned filter, int num, ...); | ||
695 | |||
684 | 696 | ||
685 | #endif | 697 | #endif |
686 | 698 | ||
diff --git a/src/firejail/list.c b/src/firejail/list.c deleted file mode 100644 index d093a1f85..000000000 --- a/src/firejail/list.c +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 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 | #include "firejail.h" | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/stat.h> | ||
23 | |||
24 | static void set_privileges(void) { | ||
25 | struct stat s; | ||
26 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { | ||
27 | EUID_ROOT(); | ||
28 | |||
29 | // elevate privileges | ||
30 | if (setreuid(0, 0)) | ||
31 | errExit("setreuid"); | ||
32 | if (setregid(0, 0)) | ||
33 | errExit("setregid"); | ||
34 | } | ||
35 | else | ||
36 | drop_privs(1); | ||
37 | } | ||
38 | |||
39 | static char *get_firemon_path(const char *cmd) { | ||
40 | assert(cmd); | ||
41 | |||
42 | // start the argv[0] program in a new sandbox | ||
43 | char *firemon; | ||
44 | if (asprintf(&firemon, "%s/bin/firemon %s", PREFIX, cmd) == -1) | ||
45 | errExit("asprintf"); | ||
46 | |||
47 | return firemon; | ||
48 | } | ||
49 | |||
50 | void top(void) { | ||
51 | EUID_ASSERT(); | ||
52 | drop_privs(1); | ||
53 | char *cmd = get_firemon_path("--top"); | ||
54 | |||
55 | char *arg[4]; | ||
56 | arg[0] = "bash"; | ||
57 | arg[1] = "-c"; | ||
58 | arg[2] = cmd; | ||
59 | arg[3] = NULL; | ||
60 | execvp("/bin/bash", arg); | ||
61 | } | ||
62 | |||
63 | void netstats(void) { | ||
64 | EUID_ASSERT(); | ||
65 | set_privileges(); | ||
66 | char *cmd = get_firemon_path("--netstats"); | ||
67 | |||
68 | char *arg[4]; | ||
69 | arg[0] = "bash"; | ||
70 | arg[1] = "-c"; | ||
71 | arg[2] = cmd; | ||
72 | arg[3] = NULL; | ||
73 | execvp("/bin/bash", arg); | ||
74 | } | ||
75 | |||
76 | void list(void) { | ||
77 | EUID_ASSERT(); | ||
78 | drop_privs(1); | ||
79 | char *cmd = get_firemon_path("--list"); | ||
80 | |||
81 | char *arg[4]; | ||
82 | arg[0] = "bash"; | ||
83 | arg[1] = "-c"; | ||
84 | arg[2] = cmd; | ||
85 | arg[3] = NULL; | ||
86 | execvp("/bin/bash", arg); | ||
87 | } | ||
88 | |||
89 | void tree(void) { | ||
90 | EUID_ASSERT(); | ||
91 | drop_privs(1); | ||
92 | char *cmd = get_firemon_path("--tree"); | ||
93 | |||
94 | char *arg[4]; | ||
95 | arg[0] = "bash"; | ||
96 | arg[1] = "-c"; | ||
97 | arg[2] = cmd; | ||
98 | arg[3] = NULL; | ||
99 | execvp("/bin/bash", arg); | ||
100 | } | ||
101 | |||
diff --git a/src/firejail/main.c b/src/firejail/main.c index f41d5fcd3..15d42a4e0 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -54,9 +54,9 @@ Config cfg; // configuration | |||
54 | int arg_private = 0; // mount private /home and /tmp directoryu | 54 | int arg_private = 0; // mount private /home and /tmp directoryu |
55 | int arg_private_template = 0; // mount private /home using a template | 55 | int arg_private_template = 0; // mount private /home using a template |
56 | int arg_debug = 0; // print debug messages | 56 | int arg_debug = 0; // print debug messages |
57 | int arg_debug_check_filename; // print debug messages for filename checking | 57 | int arg_debug_check_filename = 0; // print debug messages for filename checking |
58 | int arg_debug_blacklists; // print debug messages for blacklists | 58 | int arg_debug_blacklists = 0; // print debug messages for blacklists |
59 | int arg_debug_whitelists; // print debug messages for whitelists | 59 | int arg_debug_whitelists = 0; // print debug messages for whitelists |
60 | int arg_nonetwork = 0; // --net=none | 60 | int arg_nonetwork = 0; // --net=none |
61 | int arg_command = 0; // -c | 61 | int arg_command = 0; // -c |
62 | int arg_overlay = 0; // overlay option | 62 | int arg_overlay = 0; // overlay option |
@@ -498,27 +498,32 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
498 | exit(0); | 498 | exit(0); |
499 | } | 499 | } |
500 | else if (strcmp(argv[i], "--list") == 0) { | 500 | else if (strcmp(argv[i], "--list") == 0) { |
501 | list(); | 501 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FIREMON, "--list"); |
502 | exit(0); | 502 | exit(rv); |
503 | } | 503 | } |
504 | else if (strcmp(argv[i], "--tree") == 0) { | 504 | else if (strcmp(argv[i], "--tree") == 0) { |
505 | tree(); | 505 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree"); |
506 | exit(0); | 506 | exit(rv); |
507 | } | 507 | } |
508 | else if (strcmp(argv[i], "--top") == 0) { | 508 | else if (strcmp(argv[i], "--top") == 0) { |
509 | top(); | 509 | int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FIREMON, "--top"); |
510 | exit(0); | 510 | exit(rv); |
511 | } | 511 | } |
512 | #ifdef HAVE_NETWORK | 512 | #ifdef HAVE_NETWORK |
513 | else if (strcmp(argv[i], "--netstats") == 0) { | 513 | else if (strcmp(argv[i], "--netstats") == 0) { |
514 | if (checkcfg(CFG_NETWORK)) { | 514 | if (checkcfg(CFG_NETWORK)) { |
515 | netstats(); | 515 | struct stat s; |
516 | int rv; | ||
517 | if (stat("/proc/sys/kernel/grsecurity", &s) == 0) | ||
518 | rv = sbox_run(SBOX_ROOT | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FIREMON, "--netstats"); | ||
519 | else | ||
520 | rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FIREMON, "--netstats"); | ||
521 | exit(rv); | ||
516 | } | 522 | } |
517 | else { | 523 | else { |
518 | fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); | 524 | fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); |
519 | exit(1); | 525 | exit(1); |
520 | } | 526 | } |
521 | exit(0); | ||
522 | } | 527 | } |
523 | #endif | 528 | #endif |
524 | #ifdef HAVE_FILE_TRANSFER | 529 | #ifdef HAVE_FILE_TRANSFER |
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c index d2aa84bb6..35d6dd214 100644 --- a/src/firejail/network_main.c +++ b/src/firejail/network_main.c | |||
@@ -25,49 +25,6 @@ | |||
25 | #include <net/if.h> | 25 | #include <net/if.h> |
26 | #include <stdarg.h> | 26 | #include <stdarg.h> |
27 | 27 | ||
28 | static void fnet_run(int num, ...) { | ||
29 | int i; | ||
30 | va_list valist; | ||
31 | va_start(valist, num); | ||
32 | |||
33 | char *fnet; | ||
34 | if (asprintf(&fnet, "%s/firejail/fnet", LIBDIR) == -1) | ||
35 | errExit("asprintf"); | ||
36 | |||
37 | char *arg[num + 2]; | ||
38 | arg[0] = fnet; | ||
39 | for (i = 0; i < num; i++) | ||
40 | arg[i + 1] = va_arg(valist, char*); | ||
41 | arg[i + 1] = NULL; | ||
42 | |||
43 | pid_t child = fork(); | ||
44 | if (child < 0) | ||
45 | errExit("fork"); | ||
46 | if (child == 0) { | ||
47 | // elevate privileges in order to get grsecurity working | ||
48 | if (setreuid(0, 0)) | ||
49 | errExit("setreuid"); | ||
50 | if (setregid(0, 0)) | ||
51 | errExit("setregid"); | ||
52 | |||
53 | execvp(arg[0], arg); | ||
54 | perror("execl"); | ||
55 | _exit(1); | ||
56 | } | ||
57 | |||
58 | int status; | ||
59 | if (waitpid(child, &status, 0) == -1 ) { | ||
60 | errExit("waitpid"); | ||
61 | } | ||
62 | if (WIFEXITED(status) && status != 0) { | ||
63 | fprintf(stderr, "Error: cannot run fnet\n"); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | va_end(valist); | ||
68 | free(fnet); | ||
69 | } | ||
70 | |||
71 | // configure bridge structure | 28 | // configure bridge structure |
72 | // - extract ip address and mask from the bridge interface | 29 | // - extract ip address and mask from the bridge interface |
73 | void net_configure_bridge(Bridge *br, char *dev_name) { | 30 | void net_configure_bridge(Bridge *br, char *dev_name) { |
@@ -175,7 +132,7 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) { | |||
175 | char *cstr; | 132 | char *cstr; |
176 | if (asprintf(&cstr, "%d", child) == -1) | 133 | if (asprintf(&cstr, "%d", child) == -1) |
177 | errExit("asprintf"); | 134 | errExit("asprintf"); |
178 | fnet_run(6, "create", "veth", dev, ifname, br->dev, cstr); | 135 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 7, PATH_FNET, "create", "veth", dev, ifname, br->dev, cstr); |
179 | free(cstr); | 136 | free(cstr); |
180 | 137 | ||
181 | char *msg; | 138 | char *msg; |
@@ -344,7 +301,7 @@ void network_main(pid_t child) { | |||
344 | } | 301 | } |
345 | else | 302 | else |
346 | // net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); | 303 | // net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); |
347 | fnet_run(5, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr); | 304 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr); |
348 | } | 305 | } |
349 | 306 | ||
350 | if (cfg.bridge1.configured) { | 307 | if (cfg.bridge1.configured) { |
@@ -352,7 +309,7 @@ void network_main(pid_t child) { | |||
352 | net_configure_veth_pair(&cfg.bridge1, "eth1", child); | 309 | net_configure_veth_pair(&cfg.bridge1, "eth1", child); |
353 | else | 310 | else |
354 | // net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); | 311 | // net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); |
355 | fnet_run(5, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr); | 312 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr); |
356 | } | 313 | } |
357 | 314 | ||
358 | if (cfg.bridge2.configured) { | 315 | if (cfg.bridge2.configured) { |
@@ -360,7 +317,7 @@ void network_main(pid_t child) { | |||
360 | net_configure_veth_pair(&cfg.bridge2, "eth2", child); | 317 | net_configure_veth_pair(&cfg.bridge2, "eth2", child); |
361 | else | 318 | else |
362 | // net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); | 319 | // net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); |
363 | fnet_run(5, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr); | 320 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr); |
364 | } | 321 | } |
365 | 322 | ||
366 | if (cfg.bridge3.configured) { | 323 | if (cfg.bridge3.configured) { |
@@ -368,25 +325,25 @@ void network_main(pid_t child) { | |||
368 | net_configure_veth_pair(&cfg.bridge3, "eth3", child); | 325 | net_configure_veth_pair(&cfg.bridge3, "eth3", child); |
369 | else | 326 | else |
370 | // net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); | 327 | // net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); |
371 | fnet_run(5, "create", "macvlan", cfg.bridge3.devsandbox, cfg.bridge3.dev, cstr); | 328 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge3.devsandbox, cfg.bridge3.dev, cstr); |
372 | } | 329 | } |
373 | 330 | ||
374 | // move interfaces in sandbox | 331 | // move interfaces in sandbox |
375 | if (cfg.interface0.configured) { | 332 | if (cfg.interface0.configured) { |
376 | // net_move_interface(cfg.interface0.dev, child); | 333 | // net_move_interface(cfg.interface0.dev, child); |
377 | fnet_run(3, "moveif", cfg.interface0.dev, cstr); | 334 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface0.dev, cstr); |
378 | } | 335 | } |
379 | if (cfg.interface1.configured) { | 336 | if (cfg.interface1.configured) { |
380 | // net_move_interface(cfg.interface1.dev, child); | 337 | // net_move_interface(cfg.interface1.dev, child); |
381 | fnet_run(3, "moveif", cfg.interface1.dev, cstr); | 338 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface1.dev, cstr); |
382 | } | 339 | } |
383 | if (cfg.interface2.configured) { | 340 | if (cfg.interface2.configured) { |
384 | // net_move_interface(cfg.interface2.dev, child); | 341 | // net_move_interface(cfg.interface2.dev, child); |
385 | fnet_run(3, "moveif", cfg.interface3.dev, cstr); | 342 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr); |
386 | } | 343 | } |
387 | if (cfg.interface3.configured) { | 344 | if (cfg.interface3.configured) { |
388 | // net_move_interface(cfg.interface3.dev, child); | 345 | // net_move_interface(cfg.interface3.dev, child); |
389 | fnet_run(3, "moveif", cfg.interface3.dev, cstr); | 346 | sbox_run(SBOX_ROOT | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr); |
390 | } | 347 | } |
391 | 348 | ||
392 | free(cstr); | 349 | free(cstr); |
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c index 1ef5bf13d..6321c703a 100644 --- a/src/firejail/protocol.c +++ b/src/firejail/protocol.c | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | #ifdef HAVE_SECCOMP | 48 | #ifdef HAVE_SECCOMP |
49 | #include "firejail.h" | 49 | #include "firejail.h" |
50 | #include "seccomp.h" | 50 | #include "../include/seccomp.h" |
51 | #include <sys/types.h> | 51 | #include <sys/types.h> |
52 | #include <sys/socket.h> | 52 | #include <sys/socket.h> |
53 | 53 | ||
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c new file mode 100644 index 000000000..8c6ace27e --- /dev/null +++ b/src/firejail/sbox.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014-2016 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 | #include "firejail.h" | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <unistd.h> | ||
24 | #include <net/if.h> | ||
25 | #include <stdarg.h> | ||
26 | #include "../include/seccomp.h" | ||
27 | |||
28 | static struct sock_filter filter[] = { | ||
29 | VALIDATE_ARCHITECTURE, | ||
30 | EXAMINE_SYSCALL, | ||
31 | |||
32 | #if defined(__x86_64__) | ||
33 | #define X32_SYSCALL_BIT 0x40000000 | ||
34 | // handle X32 ABI | ||
35 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), | ||
36 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), | ||
37 | RETURN_ERRNO(EPERM), | ||
38 | #endif | ||
39 | |||
40 | // syscall list | ||
41 | #ifdef SYS_mount | ||
42 | BLACKLIST(SYS_mount), // mount/unmount filesystems | ||
43 | #endif | ||
44 | #ifdef SYS_umount2 | ||
45 | BLACKLIST(SYS_umount2), | ||
46 | #endif | ||
47 | #ifdef SYS_ptrace | ||
48 | BLACKLIST(SYS_ptrace), // trace processes | ||
49 | #endif | ||
50 | #ifdef SYS_kexec_file_load | ||
51 | BLACKLIST(SYS_kexec_file_load), | ||
52 | #endif | ||
53 | #ifdef SYS_kexec_load | ||
54 | BLACKLIST(SYS_kexec_load), // loading a different kernel | ||
55 | #endif | ||
56 | #ifdef SYS_name_to_handle_at | ||
57 | BLACKLIST(SYS_name_to_handle_at), | ||
58 | #endif | ||
59 | #ifdef SYS_open_by_handle_at | ||
60 | BLACKLIST(SYS_open_by_handle_at), // open by handle | ||
61 | #endif | ||
62 | #ifdef SYS_init_module | ||
63 | BLACKLIST(SYS_init_module), // kernel module handling | ||
64 | #endif | ||
65 | #ifdef SYS_finit_module // introduced in 2013 | ||
66 | BLACKLIST(SYS_finit_module), | ||
67 | #endif | ||
68 | #ifdef SYS_create_module | ||
69 | BLACKLIST(SYS_create_module), | ||
70 | #endif | ||
71 | #ifdef SYS_delete_module | ||
72 | BLACKLIST(SYS_delete_module), | ||
73 | #endif | ||
74 | #ifdef SYS_iopl | ||
75 | BLACKLIST(SYS_iopl), // io permissions | ||
76 | #endif | ||
77 | #ifdef SYS_ioperm | ||
78 | BLACKLIST(SYS_ioperm), | ||
79 | #endif | ||
80 | #ifdef SYS_iopl | ||
81 | BLACKLIST(SYS_iopl), // io permissions | ||
82 | #endif | ||
83 | #ifdef SYS_ioprio_set | ||
84 | BLACKLIST(SYS_ioprio_set), | ||
85 | #endif | ||
86 | #ifdef SYS_ni_syscall // new io permissions call on arm devices | ||
87 | BLACKLIST(SYS_ni_syscall), | ||
88 | #endif | ||
89 | #ifdef SYS_swapon | ||
90 | BLACKLIST(SYS_swapon), // swap on/off | ||
91 | #endif | ||
92 | #ifdef SYS_swapoff | ||
93 | BLACKLIST(SYS_swapoff), | ||
94 | #endif | ||
95 | #ifdef SYS_syslog | ||
96 | BLACKLIST(SYS_syslog), // kernel printk control | ||
97 | #endif | ||
98 | RETURN_ALLOW | ||
99 | }; | ||
100 | |||
101 | static struct sock_fprog prog = { | ||
102 | .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), | ||
103 | .filter = filter, | ||
104 | }; | ||
105 | |||
106 | typedef struct sbox_config { | ||
107 | char *name; | ||
108 | char *path; | ||
109 | unsigned filters; | ||
110 | } SboxConfig; | ||
111 | |||
112 | |||
113 | int sbox_run(unsigned filter, int num, ...) { | ||
114 | EUID_ROOT(); | ||
115 | char *path = NULL; | ||
116 | int i; | ||
117 | va_list valist; | ||
118 | va_start(valist, num); | ||
119 | |||
120 | // build argument list | ||
121 | char *arg[num + 1]; | ||
122 | for (i = 0; i < num; i++) | ||
123 | arg[i] = va_arg(valist, char*); | ||
124 | arg[i] = NULL; | ||
125 | va_end(valist); | ||
126 | |||
127 | #if 0 | ||
128 | { | ||
129 | int i; | ||
130 | for (i = 0; i <= num; i++) | ||
131 | printf("#%s# ", arg[i]); | ||
132 | printf("\n"); | ||
133 | } | ||
134 | #endif | ||
135 | pid_t child = fork(); | ||
136 | if (child < 0) | ||
137 | errExit("fork"); | ||
138 | if (child == 0) { | ||
139 | // apply filters | ||
140 | if (filter & SBOX_CAPS) | ||
141 | caps_drop_all(); | ||
142 | |||
143 | if (filter & SBOX_SECCOMP) { | ||
144 | if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
145 | perror("prctl(NO_NEW_PRIVS)"); | ||
146 | } | ||
147 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { | ||
148 | perror("prctl(PR_SET_SECCOMP)"); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | if (filter & SBOX_ROOT) { | ||
153 | // elevate privileges in order to get grsecurity working | ||
154 | if (setreuid(0, 0)) | ||
155 | errExit("setreuid"); | ||
156 | if (setregid(0, 0)) | ||
157 | errExit("setregid"); | ||
158 | } | ||
159 | else if (filter & SBOX_USER) | ||
160 | drop_privs(1); | ||
161 | |||
162 | execvp(arg[0], arg); | ||
163 | perror("execl"); | ||
164 | _exit(1); | ||
165 | } | ||
166 | |||
167 | int status; | ||
168 | if (waitpid(child, &status, 0) == -1 ) { | ||
169 | errExit("waitpid"); | ||
170 | } | ||
171 | if (WIFEXITED(status) && status != 0) { | ||
172 | fprintf(stderr, "Error: cannot run fnet\n"); | ||
173 | exit(1); | ||
174 | } | ||
175 | |||
176 | return status; | ||
177 | } | ||
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 549359d94..09862ec20 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | #ifdef HAVE_SECCOMP | 21 | #ifdef HAVE_SECCOMP |
22 | #include "firejail.h" | 22 | #include "firejail.h" |
23 | #include "seccomp.h" | 23 | #include "../include/seccomp.h" |
24 | 24 | ||
25 | #define SECSIZE 128 // initial filter size | 25 | #define SECSIZE 128 // initial filter size |
26 | static struct sock_filter *sfilter = NULL; | 26 | static struct sock_filter *sfilter = NULL; |
diff --git a/src/fnet/main.c b/src/fnet/main.c index ae780c2ea..88f71c4b3 100644 --- a/src/fnet/main.c +++ b/src/fnet/main.c | |||
@@ -31,9 +31,20 @@ static void usage(void) { | |||
31 | } | 31 | } |
32 | 32 | ||
33 | int main(int argc, char **argv) { | 33 | int main(int argc, char **argv) { |
34 | #if 0 | ||
35 | { | ||
36 | system("cat /proc/self/status"); | ||
37 | int i; | ||
38 | for (i = 0; i < argc; i++) | ||
39 | printf("*%s* ", argv[i]); | ||
40 | printf("\n"); | ||
41 | } | ||
42 | #endif | ||
34 | if (argc < 2) | 43 | if (argc < 2) |
35 | return 1; | 44 | return 1; |
36 | 45 | ||
46 | |||
47 | |||
37 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { | 48 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { |
38 | usage(); | 49 | usage(); |
39 | return 0; | 50 | return 0; |
diff --git a/src/firejail/seccomp.h b/src/include/seccomp.h index 7d646dd9e..7d646dd9e 100644 --- a/src/firejail/seccomp.h +++ b/src/include/seccomp.h | |||