summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/firejail.h7
-rw-r--r--src/firejail/main.c21
-rw-r--r--src/firejail/network.c82
-rw-r--r--src/firejail/network_main.c2
-rw-r--r--src/firejail/sandbox.c12
-rw-r--r--todo2
6 files changed, 111 insertions, 15 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 09631be7a..261821338 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -40,6 +40,7 @@ typedef struct bridge_t {
40 uint32_t ip; // interface device IP address 40 uint32_t ip; // interface device IP address
41 uint32_t mask; // interface device mask 41 uint32_t mask; // interface device mask
42 uint8_t mac[6]; // interface mac address 42 uint8_t mac[6]; // interface mac address
43 int mtu; // interface mtu
43 44
44 // inside the sandbox 45 // inside the sandbox
45 char *devsandbox; // name of the device inside the sandbox 46 char *devsandbox; // name of the device inside the sandbox
@@ -60,7 +61,7 @@ typedef struct interface_t {
60 uint32_t ip; 61 uint32_t ip;
61 uint32_t mask; 62 uint32_t mask;
62 uint8_t mac[6]; 63 uint8_t mac[6];
63 // todo: add mtu 64 int mtu;
64 65
65 uint8_t configured; 66 uint8_t configured;
66} Interface; 67} Interface;
@@ -195,8 +196,8 @@ void net_dns_print(pid_t pid);
195 196
196// network.c 197// network.c
197void net_if_up(const char *ifname); 198void net_if_up(const char *ifname);
198void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask); 199void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu);
199int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]); 200int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu);
200int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); 201int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw);
201void net_ifprint(void); 202void net_ifprint(void);
202void net_bridge_add_interface(const char *bridge, const char *dev); 203void net_bridge_add_interface(const char *bridge, const char *dev);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index ea04ea73f..a7eda3906 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -822,7 +822,7 @@ int main(int argc, char **argv) {
822 if (!intf->dev) 822 if (!intf->dev)
823 errExit("strdup"); 823 errExit("strdup");
824 824
825 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac)) { 825 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) {
826 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev); 826 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev);
827 } 827 }
828 intf->configured = 1; 828 intf->configured = 1;
@@ -917,6 +917,22 @@ int main(int argc, char **argv) {
917 return 1; 917 return 1;
918 } 918 }
919 } 919 }
920 else if (strncmp(argv[i], "--mtu=", 6) == 0) {
921 Bridge *br = last_bridge_configured();
922 if (br == NULL) {
923 fprintf(stderr, "Error: no network device configured\n");
924 return 1;
925 }
926 if (br->mtu) {
927 fprintf(stderr, "Error: cannot configure mtu twice for the same interface\n");
928 return 1;
929 }
930
931 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 68 || br->mtu > 9198) {
932 fprintf(stderr, "Error: invalid mtu value\n");
933 return 1;
934 }
935 }
920 else if (strncmp(argv[i], "--ip=", 5) == 0) { 936 else if (strncmp(argv[i], "--ip=", 5) == 0) {
921 Bridge *br = last_bridge_configured(); 937 Bridge *br = last_bridge_configured();
922 if (br == NULL) { 938 if (br == NULL) {
@@ -1231,8 +1247,9 @@ int main(int argc, char **argv) {
1231 if (!arg_nonetwork) { 1247 if (!arg_nonetwork) {
1232 // create veth pair or macvlan device 1248 // create veth pair or macvlan device
1233 if (cfg.bridge0.configured) { 1249 if (cfg.bridge0.configured) {
1234 if (cfg.bridge0.macvlan == 0) 1250 if (cfg.bridge0.macvlan == 0) {
1235 net_configure_veth_pair(&cfg.bridge0, "eth0", child); 1251 net_configure_veth_pair(&cfg.bridge0, "eth0", child);
1252 }
1236 else 1253 else
1237 net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); 1254 net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child);
1238 } 1255 }
diff --git a/src/firejail/network.c b/src/firejail/network.c
index 888db938c..5469bbcd1 100644
--- a/src/firejail/network.c
+++ b/src/firejail/network.c
@@ -93,12 +93,63 @@ void net_ifprint(void) {
93 freeifaddrs(ifaddr); 93 freeifaddrs(ifaddr);
94} 94}
95 95
96int net_get_mtu(const char *ifname) {
97 int mtu = 0;
98 if (strlen(ifname) > IFNAMSIZ) {
99 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
100 exit(1);
101 }
102
103 int s;
104 struct ifreq ifr;
105
106 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
107 errExit("socket");
108
109 ifr.ifr_addr.sa_family = AF_INET;
110 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
111 if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == 0)
112 mtu = ifr.ifr_mtu;
113 if (arg_debug)
114 printf("MTU of %s is %d.\n", ifname, ifr.ifr_mtu);
115 close(s);
116
117
118 return mtu;
119}
120
121void net_set_mtu(const char *ifname, int mtu) {
122 if (strlen(ifname) > IFNAMSIZ) {
123 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
124 exit(1);
125 }
126
127 if (arg_debug)
128 printf("set interface %s MTU %d.\n", ifname, mtu);
129
130 int s;
131 struct ifreq ifr;
132
133 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
134 errExit("socket");
135
136 ifr.ifr_addr.sa_family = AF_INET;
137 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
138 ifr.ifr_mtu = mtu;
139 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) == 0)
140 mtu = ifr.ifr_mtu;
141 close(s);
142}
96 143
97// return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask 144// return -1 if the interface was not found; if the interface was found retrn 0 and fill in IP address and mask
98int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]) { 145int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu) {
99 assert(bridge); 146 assert(bridge);
100 assert(ip); 147 assert(ip);
101 assert(mask); 148 assert(mask);
149
150 if (arg_debug)
151 printf("get interface %s configuration\n", bridge);
152
102 int rv = -1; 153 int rv = -1;
103 struct ifaddrs *ifaddr, *ifa; 154 struct ifaddrs *ifaddr, *ifa;
104 155
@@ -117,8 +168,10 @@ int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t ma
117 *mask = ntohl(si->sin_addr.s_addr); 168 *mask = ntohl(si->sin_addr.s_addr);
118 si = (struct sockaddr_in *) ifa->ifa_addr; 169 si = (struct sockaddr_in *) ifa->ifa_addr;
119 *ip = ntohl(si->sin_addr.s_addr); 170 *ip = ntohl(si->sin_addr.s_addr);
120 if (strcmp(ifa->ifa_name, "lo") != 0) 171 if (strcmp(ifa->ifa_name, "lo") != 0) {
121 net_get_mac(ifa->ifa_name, mac); 172 net_get_mac(ifa->ifa_name, mac);
173 *mtu = net_get_mtu(bridge);
174 }
122 175
123 rv = 0; 176 rv = 0;
124 break; 177 break;
@@ -186,11 +239,13 @@ void net_if_up(const char *ifname) {
186} 239}
187 240
188// configure interface 241// configure interface
189void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { 242void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
190 if (strlen(ifname) > IFNAMSIZ) { 243 if (strlen(ifname) > IFNAMSIZ) {
191 fprintf(stderr, "Error: invalid network device name %s\n", ifname); 244 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
192 exit(1); 245 exit(1);
193 } 246 }
247 if (arg_debug)
248 printf("configure interface %s\n", ifname);
194 249
195 int sock = socket(AF_INET,SOCK_DGRAM,0); 250 int sock = socket(AF_INET,SOCK_DGRAM,0);
196 if (sock < 0) 251 if (sock < 0)
@@ -214,6 +269,15 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) {
214 errExit("ioctl"); 269 errExit("ioctl");
215 } 270 }
216 } 271 }
272
273 // configure mtu
274 if (mtu > 0) {
275 ifr.ifr_mtu = mtu;
276 if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0) {
277 close(sock);
278 errExit("ioctl");
279 }
280 }
217 281
218 close(sock); 282 close(sock);
219 usleep(10000); // sleep 10ms 283 usleep(10000); // sleep 10ms
@@ -264,6 +328,11 @@ void net_bridge_add_interface(const char *bridge, const char *dev) {
264 exit(1); 328 exit(1);
265 } 329 }
266 330
331 // somehow adding the interface to the bridge resets MTU on bridge device!!!
332 // workaround: restore MTU on the bridge device
333 // todo: put a real fix in
334 int mtu1 = net_get_mtu(bridge);
335
267 struct ifreq ifr; 336 struct ifreq ifr;
268 int err; 337 int err;
269 int ifindex = if_nametoindex(dev); 338 int ifindex = if_nametoindex(dev);
@@ -290,6 +359,13 @@ void net_bridge_add_interface(const char *bridge, const char *dev) {
290 } 359 }
291 (void) err; 360 (void) err;
292 close(sock); 361 close(sock);
362
363 int mtu2 = net_get_mtu(bridge);
364 if (mtu1 != mtu2) {
365 if (arg_debug)
366 printf("Restoring MTU for %s\n", bridge);
367 net_set_mtu(bridge, mtu1);
368 }
293} 369}
294 370
295#define BUFSIZE 1024 371#define BUFSIZE 1024
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index 21d11ff38..e9de84400 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -56,7 +56,7 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
56 } 56 }
57 } 57 }
58 58
59 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac)) { 59 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) {
60 fprintf(stderr, "Error: interface %s is not configured\n", br->dev); 60 fprintf(stderr, "Error: interface %s is not configured\n", br->dev);
61 exit(1); 61 exit(1);
62 } 62 }
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index ddfcc8404..c9146560b 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -84,7 +84,7 @@ static void sandbox_if_up(Bridge *br) {
84 assert(br->ipsandbox); 84 assert(br->ipsandbox);
85 if (arg_debug) 85 if (arg_debug)
86 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 86 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
87 net_if_ip(dev, br->ipsandbox, br->mask); 87 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu);
88 net_if_up(dev); 88 net_if_up(dev);
89 } 89 }
90 else if (br->arg_ip_none == 0 && br->macvlan == 1) { 90 else if (br->arg_ip_none == 0 && br->macvlan == 1) {
@@ -107,7 +107,7 @@ static void sandbox_if_up(Bridge *br) {
107 107
108 if (arg_debug) 108 if (arg_debug)
109 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 109 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
110 net_if_ip(dev, br->ipsandbox, br->mask); 110 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu);
111 net_if_up(dev); 111 net_if_up(dev);
112 } 112 }
113} 113}
@@ -308,25 +308,25 @@ int sandbox(void* sandbox_arg) {
308 if (cfg.interface0.configured && cfg.interface0.ip) { 308 if (cfg.interface0.configured && cfg.interface0.ip) {
309 if (arg_debug) 309 if (arg_debug)
310 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev); 310 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
311 net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask); 311 net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
312 net_if_up(cfg.interface0.dev); 312 net_if_up(cfg.interface0.dev);
313 } 313 }
314 if (cfg.interface1.configured && cfg.interface1.ip) { 314 if (cfg.interface1.configured && cfg.interface1.ip) {
315 if (arg_debug) 315 if (arg_debug)
316 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev); 316 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
317 net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask); 317 net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
318 net_if_up(cfg.interface1.dev); 318 net_if_up(cfg.interface1.dev);
319 } 319 }
320 if (cfg.interface2.configured && cfg.interface2.ip) { 320 if (cfg.interface2.configured && cfg.interface2.ip) {
321 if (arg_debug) 321 if (arg_debug)
322 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev); 322 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
323 net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask); 323 net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
324 net_if_up(cfg.interface2.dev); 324 net_if_up(cfg.interface2.dev);
325 } 325 }
326 if (cfg.interface3.configured && cfg.interface3.ip) { 326 if (cfg.interface3.configured && cfg.interface3.ip) {
327 if (arg_debug) 327 if (arg_debug)
328 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev); 328 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
329 net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask); 329 net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
330 net_if_up(cfg.interface3.dev); 330 net_if_up(cfg.interface3.dev);
331 } 331 }
332 332
diff --git a/todo b/todo
index 3e329f3c4..b2c98014c 100644
--- a/todo
+++ b/todo
@@ -43,3 +43,5 @@ make[1]: *** [seccomp.o] Error 1
43 43
446. Debian 32bit - multiple problems with the testing utility 446. Debian 32bit - multiple problems with the testing utility
45 45
467. Add IRC clients: KVIrc (KDE), BitchX (CLI), Smuxi, Konversation (KDE), HexChat, Irssi (CLI), WeeChat (CLI)
47RSS: Liferea, akregator (KDE), newsbeuter (CLI), rawdog,