diff options
Diffstat (limited to 'src/firejail/network_main.c')
-rw-r--r-- | src/firejail/network_main.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c index 907b84642..d2aa84bb6 100644 --- a/src/firejail/network_main.c +++ b/src/firejail/network_main.c | |||
@@ -23,6 +23,50 @@ | |||
23 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <net/if.h> | 25 | #include <net/if.h> |
26 | #include <stdarg.h> | ||
27 | |||
28 | static void fnet_run(int num, ...) { | ||
29 | int i; | ||
30 | va_list valist; | ||
31 | va_start(valist, num); | ||
32 | |||
33 | char *fnet; | ||
34 | if (asprintf(&fnet, "%s/firejail/fnet", LIBDIR) == -1) | ||
35 | errExit("asprintf"); | ||
36 | |||
37 | char *arg[num + 2]; | ||
38 | arg[0] = fnet; | ||
39 | for (i = 0; i < num; i++) | ||
40 | arg[i + 1] = va_arg(valist, char*); | ||
41 | arg[i + 1] = NULL; | ||
42 | |||
43 | pid_t child = fork(); | ||
44 | if (child < 0) | ||
45 | errExit("fork"); | ||
46 | if (child == 0) { | ||
47 | // elevate privileges in order to get grsecurity working | ||
48 | if (setreuid(0, 0)) | ||
49 | errExit("setreuid"); | ||
50 | if (setregid(0, 0)) | ||
51 | errExit("setregid"); | ||
52 | |||
53 | execvp(arg[0], arg); | ||
54 | perror("execl"); | ||
55 | _exit(1); | ||
56 | } | ||
57 | |||
58 | int status; | ||
59 | if (waitpid(child, &status, 0) == -1 ) { | ||
60 | errExit("waitpid"); | ||
61 | } | ||
62 | if (WIFEXITED(status) && status != 0) { | ||
63 | fprintf(stderr, "Error: cannot run fnet\n"); | ||
64 | exit(1); | ||
65 | } | ||
66 | |||
67 | va_end(valist); | ||
68 | free(fnet); | ||
69 | } | ||
26 | 70 | ||
27 | // configure bridge structure | 71 | // configure bridge structure |
28 | // - extract ip address and mask from the bridge interface | 72 | // - extract ip address and mask from the bridge interface |
@@ -127,13 +171,12 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) { | |||
127 | else | 171 | else |
128 | dev = br->veth_name; | 172 | dev = br->veth_name; |
129 | 173 | ||
130 | net_create_veth(dev, ifname, child); | 174 | // net_create_veth(dev, ifname, child); |
131 | 175 | char *cstr; | |
132 | // add interface to the bridge | 176 | if (asprintf(&cstr, "%d", child) == -1) |
133 | net_bridge_add_interface(br->dev, dev); | 177 | errExit("asprintf"); |
134 | 178 | fnet_run(6, "create", "veth", dev, ifname, br->dev, cstr); | |
135 | // bring up the interface | 179 | free(cstr); |
136 | net_if_up(dev); | ||
137 | 180 | ||
138 | char *msg; | 181 | char *msg; |
139 | if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1) | 182 | if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1) |
@@ -290,47 +333,61 @@ void net_dns_print(pid_t pid) { | |||
290 | } | 333 | } |
291 | 334 | ||
292 | void network_main(pid_t child) { | 335 | void network_main(pid_t child) { |
336 | char *cstr; | ||
337 | if (asprintf(&cstr, "%d", child) == -1) | ||
338 | errExit("asprintf"); | ||
339 | |||
293 | // create veth pair or macvlan device | 340 | // create veth pair or macvlan device |
294 | if (cfg.bridge0.configured) { | 341 | if (cfg.bridge0.configured) { |
295 | if (cfg.bridge0.macvlan == 0) { | 342 | if (cfg.bridge0.macvlan == 0) { |
296 | net_configure_veth_pair(&cfg.bridge0, "eth0", child); | 343 | net_configure_veth_pair(&cfg.bridge0, "eth0", child); |
297 | } | 344 | } |
298 | else | 345 | else |
299 | net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); | 346 | // net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); |
347 | fnet_run(5, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr); | ||
300 | } | 348 | } |
301 | 349 | ||
302 | if (cfg.bridge1.configured) { | 350 | if (cfg.bridge1.configured) { |
303 | if (cfg.bridge1.macvlan == 0) | 351 | if (cfg.bridge1.macvlan == 0) |
304 | net_configure_veth_pair(&cfg.bridge1, "eth1", child); | 352 | net_configure_veth_pair(&cfg.bridge1, "eth1", child); |
305 | else | 353 | else |
306 | net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); | 354 | // net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); |
355 | fnet_run(5, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr); | ||
307 | } | 356 | } |
308 | 357 | ||
309 | if (cfg.bridge2.configured) { | 358 | if (cfg.bridge2.configured) { |
310 | if (cfg.bridge2.macvlan == 0) | 359 | if (cfg.bridge2.macvlan == 0) |
311 | net_configure_veth_pair(&cfg.bridge2, "eth2", child); | 360 | net_configure_veth_pair(&cfg.bridge2, "eth2", child); |
312 | else | 361 | else |
313 | net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); | 362 | // net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); |
363 | fnet_run(5, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr); | ||
314 | } | 364 | } |
315 | 365 | ||
316 | if (cfg.bridge3.configured) { | 366 | if (cfg.bridge3.configured) { |
317 | if (cfg.bridge3.macvlan == 0) | 367 | if (cfg.bridge3.macvlan == 0) |
318 | net_configure_veth_pair(&cfg.bridge3, "eth3", child); | 368 | net_configure_veth_pair(&cfg.bridge3, "eth3", child); |
319 | else | 369 | else |
320 | net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); | 370 | // net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); |
371 | fnet_run(5, "create", "macvlan", cfg.bridge3.devsandbox, cfg.bridge3.dev, cstr); | ||
321 | } | 372 | } |
322 | 373 | ||
323 | // move interfaces in sandbox | 374 | // move interfaces in sandbox |
324 | if (cfg.interface0.configured) { | 375 | if (cfg.interface0.configured) { |
325 | net_move_interface(cfg.interface0.dev, child); | 376 | // net_move_interface(cfg.interface0.dev, child); |
377 | fnet_run(3, "moveif", cfg.interface0.dev, cstr); | ||
326 | } | 378 | } |
327 | if (cfg.interface1.configured) { | 379 | if (cfg.interface1.configured) { |
328 | net_move_interface(cfg.interface1.dev, child); | 380 | // net_move_interface(cfg.interface1.dev, child); |
381 | fnet_run(3, "moveif", cfg.interface1.dev, cstr); | ||
329 | } | 382 | } |
330 | if (cfg.interface2.configured) { | 383 | if (cfg.interface2.configured) { |
331 | net_move_interface(cfg.interface2.dev, child); | 384 | // net_move_interface(cfg.interface2.dev, child); |
385 | fnet_run(3, "moveif", cfg.interface3.dev, cstr); | ||
332 | } | 386 | } |
333 | if (cfg.interface3.configured) { | 387 | if (cfg.interface3.configured) { |
334 | net_move_interface(cfg.interface3.dev, child); | 388 | // net_move_interface(cfg.interface3.dev, child); |
389 | fnet_run(3, "moveif", cfg.interface3.dev, cstr); | ||
335 | } | 390 | } |
391 | |||
392 | free(cstr); | ||
336 | } | 393 | } |