diff options
author | netblue30 <netblue30@yahoo.com> | 2015-10-07 10:33:59 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2015-10-07 10:33:59 -0400 |
commit | d8c437feadcf82b0a6f5ba0654e2e38da2a59150 (patch) | |
tree | 8a1cf81b6a6d47ac479b16e01a07f0c7eb1bb6f2 /src | |
parent | main page (diff) | |
download | firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.tar.gz firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.tar.zst firejail-d8c437feadcf82b0a6f5ba0654e2e38da2a59150.zip |
adding --mtu option
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 7 | ||||
-rw-r--r-- | src/firejail/main.c | 21 | ||||
-rw-r--r-- | src/firejail/network.c | 82 | ||||
-rw-r--r-- | src/firejail/network_main.c | 2 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 12 |
5 files changed, 109 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 |
197 | void net_if_up(const char *ifname); | 198 | void net_if_up(const char *ifname); |
198 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask); | 199 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu); |
199 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]); | 200 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu); |
200 | int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); | 201 | int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); |
201 | void net_ifprint(void); | 202 | void net_ifprint(void); |
202 | void net_bridge_add_interface(const char *bridge, const char *dev); | 203 | void 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 | ||
96 | int 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 | |||
121 | void 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 |
98 | int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6]) { | 145 | int 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 |
189 | void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask) { | 242 | void 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 | ||