aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2018-07-17 07:45:54 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2018-07-17 07:45:54 -0400
commit53cfdf2d8063c802d6f049d27ea62f6ca7c94622 (patch)
treee6af105c731f19e6a17423fe512cfebb664b51e9 /src
parentnetwork testing (diff)
downloadfirejail-53cfdf2d8063c802d6f049d27ea62f6ca7c94622.tar.gz
firejail-53cfdf2d8063c802d6f049d27ea62f6ca7c94622.tar.zst
firejail-53cfdf2d8063c802d6f049d27ea62f6ca7c94622.zip
rework --netmask
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/main.c35
-rw-r--r--src/firejail/network_main.c99
-rw-r--r--src/firejail/profile.c7
4 files changed, 70 insertions, 72 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 0654439d6..0faf10340 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -408,7 +408,6 @@ int sandbox(void* sandbox_arg);
408void start_application(int no_sandbox); 408void start_application(int no_sandbox);
409 409
410// network_main.c 410// network_main.c
411void net_configure_bridge(Bridge *br, char *dev_name);
412void net_configure_sandbox_ip(Bridge *br); 411void net_configure_sandbox_ip(Bridge *br);
413void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); 412void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child);
414void net_check_cfg(void); 413void net_check_cfg(void);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 42ed504f9..8e4fc6f38 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -265,7 +265,7 @@ static void check_network(Bridge *br) {
265 assert(br); 265 assert(br);
266 if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address 266 if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address
267 net_configure_sandbox_ip(br); 267 net_configure_sandbox_ip(br);
268 else if (br->ipsandbox && br->ip && br->mask) { // for macvlan check network range 268 else if (br->ipsandbox) { // for macvlan check network range
269 char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); 269 char *rv = in_netrange(br->ipsandbox, br->ip, br->mask);
270 if (rv) { 270 if (rv) {
271 fprintf(stderr, "%s", rv); 271 fprintf(stderr, "%s", rv);
@@ -1848,7 +1848,8 @@ int main(int argc, char **argv) {
1848 fprintf(stderr, "Error: maximum 4 network devices are allowed\n"); 1848 fprintf(stderr, "Error: maximum 4 network devices are allowed\n");
1849 return 1; 1849 return 1;
1850 } 1850 }
1851 net_configure_bridge(br, argv[i] + 6); 1851 br->dev = argv[i] + 6;
1852 br->configured = 1;
1852 } 1853 }
1853 else 1854 else
1854 exit_err_feature("networking"); 1855 exit_err_feature("networking");
@@ -1913,10 +1914,6 @@ int main(int argc, char **argv) {
1913 fprintf(stderr, "Error: invalid IP range\n"); 1914 fprintf(stderr, "Error: invalid IP range\n");
1914 return 1; 1915 return 1;
1915 } 1916 }
1916 if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) {
1917 fprintf(stderr, "Error: IP range addresses not in network range\n");
1918 return 1;
1919 }
1920 } 1917 }
1921 else 1918 else
1922 exit_err_feature("networking"); 1919 exit_err_feature("networking");
@@ -1994,26 +1991,16 @@ int main(int argc, char **argv) {
1994 fprintf(stderr, "Error: no network device configured\n"); 1991 fprintf(stderr, "Error: no network device configured\n");
1995 exit(1); 1992 exit(1);
1996 } 1993 }
1997 if (br->arg_ip_none || br->masksandbox) { 1994 if (br->arg_ip_none || br->mask) {
1998 fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); 1995 fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n");
1999 exit(1); 1996 exit(1);
2000 } 1997 }
2001 1998
2002 // configure this network mask for the last bridge defined 1999 // configure this network mask for the last bridge defined
2003 if (atoip(argv[i] + 10, &br->masksandbox)) { 2000 if (atoip(argv[i] + 10, &br->mask)) {
2004 fprintf(stderr, "Error: invalid network mask\n"); 2001 fprintf(stderr, "Error: invalid network mask\n");
2005 exit(1); 2002 exit(1);
2006 } 2003 }
2007
2008 // if the bridge is not configured, use this mask as the bridge mask
2009 if (br->mask == 0)
2010 br->mask = br->masksandbox;
2011 else {
2012 fprintf(stderr, "Error: interface %s already has a network mask defined; "
2013 "please remove --netmask\n",
2014 br->dev);
2015 exit(1);
2016 }
2017 } 2004 }
2018 else 2005 else
2019 exit_err_feature("networking"); 2006 exit_err_feature("networking");
@@ -2431,10 +2418,14 @@ int main(int argc, char **argv) {
2431 flock(lockfd_network, LOCK_EX); 2418 flock(lockfd_network, LOCK_EX);
2432 } 2419 }
2433 2420
2434 check_network(&cfg.bridge0); 2421 if (cfg.bridge0.configured && cfg.bridge0.arg_ip_none == 0)
2435 check_network(&cfg.bridge1); 2422 check_network(&cfg.bridge0);
2436 check_network(&cfg.bridge2); 2423 if (cfg.bridge1.configured && cfg.bridge1.arg_ip_none == 0)
2437 check_network(&cfg.bridge3); 2424 check_network(&cfg.bridge1);
2425 if (cfg.bridge2.configured && cfg.bridge2.arg_ip_none == 0)
2426 check_network(&cfg.bridge2);
2427 if (cfg.bridge3.configured && cfg.bridge3.arg_ip_none == 0)
2428 check_network(&cfg.bridge3);
2438 2429
2439 // save network mapping in shared memory 2430 // save network mapping in shared memory
2440 network_set_run_file(sandbox_pid); 2431 network_set_run_file(sandbox_pid);
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index 488615bda..e30d07229 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -28,11 +28,9 @@
28 28
29// configure bridge structure 29// configure bridge structure
30// - extract ip address and mask from the bridge interface 30// - extract ip address and mask from the bridge interface
31void net_configure_bridge(Bridge *br, char *dev_name) { 31static void net_configure_bridge(Bridge *br) {
32 assert(br); 32 assert(br);
33 assert(dev_name); 33 assert(br->dev);
34
35 br->dev = dev_name;
36 34
37 // check the bridge device exists 35 // check the bridge device exists
38 char sysbridge[30 + strlen(br->dev)]; 36 char sysbridge[30 + strlen(br->dev)];
@@ -58,22 +56,23 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
58 } 56 }
59 } 57 }
60 58
61 // allow unconfigured interfaces 59 int mtu = br->mtu; // preserve mtu value in case the user changed it with --mtu
62 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { 60 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu))
61 // allow unconfigured interfaces
63 fwarning("the network interface %s is not configured\n", br->dev); 62 fwarning("the network interface %s is not configured\n", br->dev);
64// don't configure an ip address on unconfigured interfaces 63 if (mtu)
65// br->arg_ip_none = 1; 64 br->mtu = mtu;
65
66 if (arg_debug) {
67 if (br->macvlan == 0)
68 printf("Bridge device %s at %d.%d.%d.%d/%d\n",
69 br->dev, PRINT_IP(br->ip), mask2bits(br->mask));
70 else
71 printf("macvlan parent device %s at %d.%d.%d.%d/%d\n",
72 br->dev, PRINT_IP(br->ip), mask2bits(br->mask));
66 } 73 }
67 else {
68 if (arg_debug) {
69 if (br->macvlan == 0)
70 printf("Bridge device %s at %d.%d.%d.%d/%d\n",
71 br->dev, PRINT_IP(br->ip), mask2bits(br->mask));
72 else
73 printf("macvlan parent device %s at %d.%d.%d.%d/%d\n",
74 br->dev, PRINT_IP(br->ip), mask2bits(br->mask));
75 }
76 74
75 if (br->mask) {
77 uint32_t range = ~br->mask + 1; // the number of potential addresses 76 uint32_t range = ~br->mask + 1; // the number of potential addresses
78 // this software is not supported for /31 networks 77 // this software is not supported for /31 networks
79 if (range < 4) { 78 if (range < 4) {
@@ -82,7 +81,31 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
82 } 81 }
83 } 82 }
84 83
85 br->configured = 1; 84
85 // no interface network mask - no ip address will be configured
86 if (br->mask == 0)
87 goto err_no_ip;
88 // no interface ip - extract the network address from the address configured by the user
89 else if (br->ip == 0 && br->ipsandbox)
90 br->ip = br->ipsandbox & br->mask;
91 // no interface ip - extract the network address from the default gateway configured by the user
92 else if (br->ip == 0 && cfg.defaultgw)
93 br->ip = cfg.defaultgw & br->mask;
94 // no ip address will be configured
95 else if (br->ip == 0)
96 goto err_no_ip;
97
98 if ((br->iprange_start && in_netrange(br->iprange_start, br->ip, br->mask)) ||
99 (br->iprange_end && in_netrange(br->iprange_end, br->ip, br->mask))) {
100 fprintf(stderr, "Error: IP range addresses not in network range\n");
101 exit(1);
102 }
103
104 return;
105
106err_no_ip:
107 br->arg_ip_none = 1;
108 fwarning("Not enough information to configure an IP address for\n interface --net=%s\n", br->dev);
86} 109}
87 110
88 111
@@ -93,7 +116,7 @@ void net_configure_sandbox_ip(Bridge *br) {
93 116
94 if (br->arg_ip_none) 117 if (br->arg_ip_none)
95 br->ipsandbox = 0; 118 br->ipsandbox = 0;
96 else if (br->ipsandbox && br->ip && br->mask) { 119 else if (br->ipsandbox) {
97 // check network range 120 // check network range
98 char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); 121 char *rv = in_netrange(br->ipsandbox, br->ip, br->mask);
99 if (rv) { 122 if (rv) {
@@ -106,20 +129,9 @@ void net_configure_sandbox_ip(Bridge *br) {
106 exit(1); 129 exit(1);
107 } 130 }
108 } 131 }
109 else if (br->ipsandbox && br->masksandbox) { 132 else
110 // send an ARP request and check if there is anybody on this IP address
111 if (arp_check(br->dev, br->ipsandbox)) {
112 fprintf(stderr, "Error: IP address %d.%d.%d.%d is already in use\n", PRINT_IP(br->ipsandbox));
113 exit(1);
114 }
115 }
116 else if (br->ip && br->mask)
117 // ip address assigned by arp-scan for a bridge device 133 // ip address assigned by arp-scan for a bridge device
118 br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); 134 br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask);
119 else {
120 br->ipsandbox = 0;
121 br->arg_ip_none = 1;
122 }
123} 135}
124 136
125 137
@@ -159,31 +171,22 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) {
159// the default address should be in the range of at least on of the bridge devices 171// the default address should be in the range of at least on of the bridge devices
160void check_default_gw(uint32_t defaultgw) { 172void check_default_gw(uint32_t defaultgw) {
161 assert(defaultgw); 173 assert(defaultgw);
162
163 if (cfg.bridge0.configured) { 174 if (cfg.bridge0.configured) {
164 if (cfg.bridge0.ip == 0 && cfg.bridge0.ipsandbox)
165 return;
166 char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); 175 char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask);
167 if (rv == 0) 176 if (rv == 0)
168 return; 177 return;
169 } 178 }
170 if (cfg.bridge1.configured) { 179 if (cfg.bridge1.configured) {
171 if (cfg.bridge1.ip == 0 && cfg.bridge1.ipsandbox)
172 return;
173 char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); 180 char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask);
174 if (rv == 0) 181 if (rv == 0)
175 return; 182 return;
176 } 183 }
177 if (cfg.bridge2.configured) { 184 if (cfg.bridge2.configured) {
178 if (cfg.bridge2.ip == 0 && cfg.bridge2.ipsandbox)
179 return;
180 char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); 185 char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask);
181 if (rv == 0) 186 if (rv == 0)
182 return; 187 return;
183 } 188 }
184 if (cfg.bridge3.configured) { 189 if (cfg.bridge3.configured) {
185 if (cfg.bridge3.ip == 0 && cfg.bridge3.ipsandbox)
186 return;
187 char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); 190 char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask);
188 if (rv == 0) 191 if (rv == 0)
189 return; 192 return;
@@ -196,14 +199,22 @@ void check_default_gw(uint32_t defaultgw) {
196void net_check_cfg(void) { 199void net_check_cfg(void) {
197 EUID_ASSERT(); 200 EUID_ASSERT();
198 int net_configured = 0; 201 int net_configured = 0;
199 if (cfg.bridge0.configured) 202 if (cfg.bridge0.configured) {
203 net_configure_bridge(&cfg.bridge0);
200 net_configured++; 204 net_configured++;
201 if (cfg.bridge1.configured) 205 }
206 if (cfg.bridge1.configured) {
207 net_configure_bridge(&cfg.bridge1);
202 net_configured++; 208 net_configured++;
203 if (cfg.bridge2.configured) 209 }
210 if (cfg.bridge2.configured) {
211 net_configure_bridge(&cfg.bridge2);
204 net_configured++; 212 net_configured++;
205 if (cfg.bridge3.configured) 213 }
214 if (cfg.bridge3.configured) {
215 net_configure_bridge(&cfg.bridge3);
206 net_configured++; 216 net_configured++;
217 }
207 218
208 int if_configured = 0; 219 int if_configured = 0;
209 if (cfg.interface0.configured) 220 if (cfg.interface0.configured)
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index fc575d4b5..425f8f5c9 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -358,7 +358,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
358 fprintf(stderr, "Error: maximum 4 network devices are allowed\n"); 358 fprintf(stderr, "Error: maximum 4 network devices are allowed\n");
359 exit(1); 359 exit(1);
360 } 360 }
361 net_configure_bridge(br, ptr + 4); 361 br->dev = ptr + 4;
362 br->configured = 1;
362 } 363 }
363 else 364 else
364 warning_feature_disabled("networking"); 365 warning_feature_disabled("networking");
@@ -423,10 +424,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
423 fprintf(stderr, "Error: invalid IP range\n"); 424 fprintf(stderr, "Error: invalid IP range\n");
424 exit(1); 425 exit(1);
425 } 426 }
426 if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) {
427 fprintf(stderr, "Error: IP range addresses not in network range\n");
428 exit(1);
429 }
430 } 427 }
431 else 428 else
432 warning_feature_disabled("networking"); 429 warning_feature_disabled("networking");