aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-11-15 07:09:41 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-11-15 07:09:41 -0500
commit77a891838f0456944777830152171c23fb52a71a (patch)
tree679ccfae005f3a1d0a17bcfa8c6000e8b2205d8a /src/firejail
parentnetfilter split (diff)
downloadfirejail-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.h4
-rw-r--r--src/firejail/main.c12
-rw-r--r--src/firejail/netfilter.c91
-rw-r--r--src/firejail/usage.c6
-rw-r--r--src/firejail/util.c43
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);
516void create_empty_file_as_root(const char *dir, mode_t mode); 516void create_empty_file_as_root(const char *dir, mode_t mode);
517int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); 517int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode);
518void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); 518void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid);
519char *read_text_file_or_exit(const char *fname);
520unsigned extract_timeout(const char *str); 519unsigned 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);
607void check_netfilter_file(const char *fname); 606void check_netfilter_file(const char *fname);
608void netfilter(const char *fname); 607void netfilter(const char *fname);
609void netfilter6(const char *fname); 608void netfilter6(const char *fname);
609void netfilter_print(pid_t pid, int ipv6);
610 610
611// netns.c 611// netns.c
612void check_netns(const char *nsname); 612void 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
134void 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
911char *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
947errexit:
948 close(fd);
949 fprintf(stderr, "Error: cannot read %s\n", fname);
950 exit(1);
951}
952
953
954unsigned extract_timeout(const char *str) { 911unsigned extract_timeout(const char *str) {
955 unsigned s; 912 unsigned s;
956 unsigned m; 913 unsigned m;