diff options
author | netblue30 <netblue30@yahoo.com> | 2017-11-15 07:09:41 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-11-15 07:09:41 -0500 |
commit | 77a891838f0456944777830152171c23fb52a71a (patch) | |
tree | 679ccfae005f3a1d0a17bcfa8c6000e8b2205d8a /src/firejail | |
parent | netfilter split (diff) | |
download | firejail-77a891838f0456944777830152171c23fb52a71a.tar.gz firejail-77a891838f0456944777830152171c23fb52a71a.tar.zst firejail-77a891838f0456944777830152171c23fb52a71a.zip |
netfilter split, --netfilter.print, --netfilter6.print
Diffstat (limited to 'src/firejail')
-rw-r--r-- | src/firejail/firejail.h | 4 | ||||
-rw-r--r-- | src/firejail/main.c | 12 | ||||
-rw-r--r-- | src/firejail/netfilter.c | 91 | ||||
-rw-r--r-- | src/firejail/usage.c | 6 | ||||
-rw-r--r-- | src/firejail/util.c | 43 |
5 files changed, 96 insertions, 60 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ab3c13598..f7bebe1b6 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -516,7 +516,6 @@ void create_empty_dir_as_root(const char *dir, mode_t mode); | |||
516 | void create_empty_file_as_root(const char *dir, mode_t mode); | 516 | void create_empty_file_as_root(const char *dir, mode_t mode); |
517 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); | 517 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); |
518 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); | 518 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); |
519 | char *read_text_file_or_exit(const char *fname); | ||
520 | unsigned extract_timeout(const char *str); | 519 | unsigned extract_timeout(const char *str); |
521 | 520 | ||
522 | // fs_var.c | 521 | // fs_var.c |
@@ -607,6 +606,7 @@ void check_output(int argc, char **argv); | |||
607 | void check_netfilter_file(const char *fname); | 606 | void check_netfilter_file(const char *fname); |
608 | void netfilter(const char *fname); | 607 | void netfilter(const char *fname); |
609 | void netfilter6(const char *fname); | 608 | void netfilter6(const char *fname); |
609 | void netfilter_print(pid_t pid, int ipv6); | ||
610 | 610 | ||
611 | // netns.c | 611 | // netns.c |
612 | void check_netns(const char *nsname); | 612 | void check_netns(const char *nsname); |
@@ -766,7 +766,7 @@ void build_appimage_cmdline(char **command_line, char **window_title, int argc, | |||
766 | // sbox.c | 766 | // sbox.c |
767 | // programs | 767 | // programs |
768 | #define PATH_FNET (LIBDIR "/firejail/fnet") | 768 | #define PATH_FNET (LIBDIR "/firejail/fnet") |
769 | #define PATH_FNETFILTER (LIBDIR "/firejail/fnetfilter#define PATH_FNET (LIBDIR "/firejail/fnet") | 769 | #define PATH_FNETFILTER (LIBDIR "/firejail/fnetfilter") |
770 | #define PATH_FIREMON (PREFIX "/bin/firemon") | 770 | #define PATH_FIREMON (PREFIX "/bin/firemon") |
771 | #define PATH_FIREJAIL (PREFIX "/bin/firejail") | 771 | #define PATH_FIREJAIL (PREFIX "/bin/firejail") |
772 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") | 772 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") |
diff --git a/src/firejail/main.c b/src/firejail/main.c index c8b347b5f..d6b0a230e 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -429,6 +429,18 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
429 | exit_err_feature("networking"); | 429 | exit_err_feature("networking"); |
430 | exit(0); | 430 | exit(0); |
431 | } | 431 | } |
432 | else if (strncmp(argv[i], "--netfilter.print=", 18) == 0) { | ||
433 | // extract pid or sandbox name | ||
434 | pid_t pid = read_pid(argv[i] + 18); | ||
435 | netfilter_print(pid, 0); | ||
436 | exit(0); | ||
437 | } | ||
438 | else if (strncmp(argv[i], "--netfilter6.print=", 19) == 0) { | ||
439 | // extract pid or sandbox name | ||
440 | pid_t pid = read_pid(argv[i] + 19); | ||
441 | netfilter_print(pid, 1); | ||
442 | exit(0); | ||
443 | } | ||
432 | #endif | 444 | #endif |
433 | //************************************* | 445 | //************************************* |
434 | // independent commands - the program will exit! | 446 | // independent commands - the program will exit! |
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c index 517d0462f..e1d0edd01 100644 --- a/src/firejail/netfilter.c +++ b/src/firejail/netfilter.c | |||
@@ -63,6 +63,9 @@ void netfilter(const char *fname) { | |||
63 | return; | 63 | return; |
64 | } | 64 | } |
65 | 65 | ||
66 | if (arg_debug) | ||
67 | printf("Installing firewall\n"); | ||
68 | |||
66 | // create an empty user-owned SBOX_STDIN_FILE | 69 | // create an empty user-owned SBOX_STDIN_FILE |
67 | create_empty_file_as_root(SBOX_STDIN_FILE, 0644); | 70 | create_empty_file_as_root(SBOX_STDIN_FILE, 0644); |
68 | if (set_perms(SBOX_STDIN_FILE, getuid(), getgid(), 0644)) | 71 | if (set_perms(SBOX_STDIN_FILE, getuid(), getgid(), 0644)) |
@@ -106,19 +109,15 @@ void netfilter6(const char *fname) { | |||
106 | return; | 109 | return; |
107 | } | 110 | } |
108 | 111 | ||
109 | // create the filter file | ||
110 | char *filter = read_text_file_or_exit(fname); | ||
111 | FILE *fp = fopen(SBOX_STDIN_FILE, "w"); | ||
112 | if (!fp) { | ||
113 | fprintf(stderr, "Error: cannot open %s\n", SBOX_STDIN_FILE); | ||
114 | exit(1); | ||
115 | } | ||
116 | fprintf(fp, "%s\n", filter); | ||
117 | fclose(fp); | ||
118 | |||
119 | // push filter | ||
120 | if (arg_debug) | 112 | if (arg_debug) |
121 | printf("Installing network filter:\n%s\n", filter); | 113 | printf("Installing IPv6 firewall\n"); |
114 | |||
115 | // create an empty user-owned SBOX_STDIN_FILE | ||
116 | create_empty_file_as_root(SBOX_STDIN_FILE, 0644); | ||
117 | if (set_perms(SBOX_STDIN_FILE, getuid(), getgid(), 0644)) | ||
118 | errExit("set_perms"); | ||
119 | |||
120 | sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FNETFILTER, fname, SBOX_STDIN_FILE); | ||
122 | 121 | ||
123 | // first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter | 122 | // first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter |
124 | // we run this command with caps and seccomp disabled in order to allow the loading of these modules | 123 | // we run this command with caps and seccomp disabled in order to allow the loading of these modules |
@@ -129,6 +128,72 @@ void netfilter6(const char *fname) { | |||
129 | if (arg_debug) | 128 | if (arg_debug) |
130 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, ip6tables, "-vL"); | 129 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, ip6tables, "-vL"); |
131 | 130 | ||
132 | free(filter); | ||
133 | return; | 131 | return; |
134 | } | 132 | } |
133 | |||
134 | void netfilter_print(pid_t pid, int ipv6) { | ||
135 | EUID_ASSERT(); | ||
136 | |||
137 | // verify sandbox | ||
138 | EUID_ROOT(); | ||
139 | char *comm = pid_proc_comm(pid); | ||
140 | EUID_USER(); | ||
141 | if (!comm) { | ||
142 | fprintf(stderr, "Error: cannot find sandbox\n"); | ||
143 | exit(1); | ||
144 | } | ||
145 | |||
146 | // check for firejail sandbox | ||
147 | if (strcmp(comm, "firejail") != 0) { | ||
148 | fprintf(stderr, "Error: cannot find sandbox\n"); | ||
149 | exit(1); | ||
150 | } | ||
151 | free(comm); | ||
152 | |||
153 | // check network namespace | ||
154 | char *name; | ||
155 | if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1) | ||
156 | errExit("asprintf"); | ||
157 | struct stat s; | ||
158 | if (stat(name, &s) == -1) { | ||
159 | fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n"); | ||
160 | exit(1); | ||
161 | } | ||
162 | |||
163 | // join the network namespace | ||
164 | pid_t child; | ||
165 | if (find_child(pid, &child) == -1) { | ||
166 | fprintf(stderr, "Error: cannot join the network namespace\n"); | ||
167 | exit(1); | ||
168 | } | ||
169 | |||
170 | EUID_ROOT(); | ||
171 | if (join_namespace(child, "net")) { | ||
172 | fprintf(stderr, "Error: cannot join the network namespace\n"); | ||
173 | exit(1); | ||
174 | } | ||
175 | |||
176 | // find iptables executable | ||
177 | char *iptables = NULL; | ||
178 | char *iptables_restore = NULL; | ||
179 | if (ipv6) { | ||
180 | if (stat("/sbin/ip6tables", &s) == 0) | ||
181 | iptables = "/sbin/ip6tables"; | ||
182 | else if (stat("/usr/sbin/ip6tables", &s) == 0) | ||
183 | iptables = "/usr/sbin/ip6tables"; | ||
184 | } | ||
185 | else { | ||
186 | if (stat("/sbin/iptables", &s) == 0) | ||
187 | iptables = "/sbin/iptables"; | ||
188 | else if (stat("/usr/sbin/iptables", &s) == 0) | ||
189 | iptables = "/usr/sbin/iptables"; | ||
190 | } | ||
191 | |||
192 | if (iptables == NULL) { | ||
193 | fprintf(stderr, "Error: iptables command not found\n"); | ||
194 | exit(1); | ||
195 | } | ||
196 | |||
197 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL"); | ||
198 | } | ||
199 | |||
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 38de99471..f1581e847 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -122,8 +122,10 @@ void usage(void) { | |||
122 | printf(" --net=ethernet_interface - enable network namespaces and connect to this\n"); | 122 | printf(" --net=ethernet_interface - enable network namespaces and connect to this\n"); |
123 | printf("\tEthernet interface.\n"); | 123 | printf("\tEthernet interface.\n"); |
124 | printf(" --net=none - enable a new, unconnected network namespace.\n"); | 124 | printf(" --net=none - enable a new, unconnected network namespace.\n"); |
125 | printf(" --netfilter[=filename] - enable the default client network filter.\n"); | 125 | printf(" --netfilter[=filename] - enable firewall.\n"); |
126 | printf(" --netfilter6=filename - enable the IPv6 network filter.\n"); | 126 | printf(" --netfilter.print=name|pid - print the firewall.\n"); |
127 | printf(" --netfilter6=filename - enable IPv6 firewall.\n"); | ||
128 | printf(" --netfilter6.print=name|pid - print the IPv6 firewall.\n"); | ||
127 | printf(" --netns=name - Run the program in a named, persistent network namespace.\n"); | 129 | printf(" --netns=name - Run the program in a named, persistent network namespace.\n"); |
128 | printf(" --netstats - monitor network statistics.\n"); | 130 | printf(" --netstats - monitor network statistics.\n"); |
129 | #endif | 131 | #endif |
diff --git a/src/firejail/util.c b/src/firejail/util.c index cea2b76e3..fde180e49 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -908,49 +908,6 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) { | |||
908 | ASSERT_PERMS(fname, uid, gid, mode); | 908 | ASSERT_PERMS(fname, uid, gid, mode); |
909 | } | 909 | } |
910 | 910 | ||
911 | char *read_text_file_or_exit(const char *fname) { | ||
912 | assert(fname); | ||
913 | |||
914 | // open file | ||
915 | int fd = open(fname, O_RDONLY); | ||
916 | if (fd == -1) { | ||
917 | fprintf(stderr, "Error: cannot read %s\n", fname); | ||
918 | exit(1); | ||
919 | } | ||
920 | |||
921 | int size = lseek(fd, 0, SEEK_END); | ||
922 | if (size == -1) | ||
923 | goto errexit; | ||
924 | if (lseek(fd, 0 , SEEK_SET) == -1) | ||
925 | goto errexit; | ||
926 | |||
927 | // allocate memory | ||
928 | char *data = malloc(size + 1); // + '\0' | ||
929 | if (data == NULL) | ||
930 | goto errexit; | ||
931 | memset(data, 0, size + 1); | ||
932 | |||
933 | // read file | ||
934 | int rd = 0; | ||
935 | while (rd < size) { | ||
936 | int rv = read(fd, (unsigned char *) data + rd, size - rd); | ||
937 | if (rv == -1) { | ||
938 | goto errexit; | ||
939 | } | ||
940 | rd += rv; | ||
941 | } | ||
942 | |||
943 | // close file | ||
944 | close(fd); | ||
945 | return data; | ||
946 | |||
947 | errexit: | ||
948 | close(fd); | ||
949 | fprintf(stderr, "Error: cannot read %s\n", fname); | ||
950 | exit(1); | ||
951 | } | ||
952 | |||
953 | |||
954 | unsigned extract_timeout(const char *str) { | 911 | unsigned extract_timeout(const char *str) { |
955 | unsigned s; | 912 | unsigned s; |
956 | unsigned m; | 913 | unsigned m; |