From 53cfdf2d8063c802d6f049d27ea62f6ca7c94622 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 17 Jul 2018 07:45:54 -0400 Subject: rework --netmask --- src/firejail/firejail.h | 1 - src/firejail/main.c | 35 ++++++---------- src/firejail/network_main.c | 99 +++++++++++++++++++++++++-------------------- src/firejail/profile.c | 7 +--- test/network/iprange.exp | 8 ++-- 5 files changed, 74 insertions(+), 76 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); void start_application(int no_sandbox); // network_main.c -void net_configure_bridge(Bridge *br, char *dev_name); void net_configure_sandbox_ip(Bridge *br); void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); void 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) { assert(br); if (br->macvlan == 0) // for bridge devices check network range or arp-scan and assign address net_configure_sandbox_ip(br); - else if (br->ipsandbox && br->ip && br->mask) { // for macvlan check network range + else if (br->ipsandbox) { // for macvlan check network range char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); if (rv) { fprintf(stderr, "%s", rv); @@ -1848,7 +1848,8 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: maximum 4 network devices are allowed\n"); return 1; } - net_configure_bridge(br, argv[i] + 6); + br->dev = argv[i] + 6; + br->configured = 1; } else exit_err_feature("networking"); @@ -1913,10 +1914,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: invalid IP range\n"); return 1; } - if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) { - fprintf(stderr, "Error: IP range addresses not in network range\n"); - return 1; - } } else exit_err_feature("networking"); @@ -1994,26 +1991,16 @@ int main(int argc, char **argv) { fprintf(stderr, "Error: no network device configured\n"); exit(1); } - if (br->arg_ip_none || br->masksandbox) { + if (br->arg_ip_none || br->mask) { fprintf(stderr, "Error: cannot configure the network mask twice for the same interface\n"); exit(1); } // configure this network mask for the last bridge defined - if (atoip(argv[i] + 10, &br->masksandbox)) { + if (atoip(argv[i] + 10, &br->mask)) { fprintf(stderr, "Error: invalid network mask\n"); exit(1); } - - // if the bridge is not configured, use this mask as the bridge mask - if (br->mask == 0) - br->mask = br->masksandbox; - else { - fprintf(stderr, "Error: interface %s already has a network mask defined; " - "please remove --netmask\n", - br->dev); - exit(1); - } } else exit_err_feature("networking"); @@ -2431,10 +2418,14 @@ int main(int argc, char **argv) { flock(lockfd_network, LOCK_EX); } - check_network(&cfg.bridge0); - check_network(&cfg.bridge1); - check_network(&cfg.bridge2); - check_network(&cfg.bridge3); + if (cfg.bridge0.configured && cfg.bridge0.arg_ip_none == 0) + check_network(&cfg.bridge0); + if (cfg.bridge1.configured && cfg.bridge1.arg_ip_none == 0) + check_network(&cfg.bridge1); + if (cfg.bridge2.configured && cfg.bridge2.arg_ip_none == 0) + check_network(&cfg.bridge2); + if (cfg.bridge3.configured && cfg.bridge3.arg_ip_none == 0) + check_network(&cfg.bridge3); // save network mapping in shared memory 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 @@ // configure bridge structure // - extract ip address and mask from the bridge interface -void net_configure_bridge(Bridge *br, char *dev_name) { +static void net_configure_bridge(Bridge *br) { assert(br); - assert(dev_name); - - br->dev = dev_name; + assert(br->dev); // check the bridge device exists char sysbridge[30 + strlen(br->dev)]; @@ -58,22 +56,23 @@ void net_configure_bridge(Bridge *br, char *dev_name) { } } - // allow unconfigured interfaces - if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { + int mtu = br->mtu; // preserve mtu value in case the user changed it with --mtu + if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) + // allow unconfigured interfaces fwarning("the network interface %s is not configured\n", br->dev); -// don't configure an ip address on unconfigured interfaces -// br->arg_ip_none = 1; + if (mtu) + br->mtu = mtu; + + if (arg_debug) { + if (br->macvlan == 0) + printf("Bridge device %s at %d.%d.%d.%d/%d\n", + br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); + else + printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", + br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); } - else { - if (arg_debug) { - if (br->macvlan == 0) - printf("Bridge device %s at %d.%d.%d.%d/%d\n", - br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); - else - printf("macvlan parent device %s at %d.%d.%d.%d/%d\n", - br->dev, PRINT_IP(br->ip), mask2bits(br->mask)); - } + if (br->mask) { uint32_t range = ~br->mask + 1; // the number of potential addresses // this software is not supported for /31 networks if (range < 4) { @@ -82,7 +81,31 @@ void net_configure_bridge(Bridge *br, char *dev_name) { } } - br->configured = 1; + + // no interface network mask - no ip address will be configured + if (br->mask == 0) + goto err_no_ip; + // no interface ip - extract the network address from the address configured by the user + else if (br->ip == 0 && br->ipsandbox) + br->ip = br->ipsandbox & br->mask; + // no interface ip - extract the network address from the default gateway configured by the user + else if (br->ip == 0 && cfg.defaultgw) + br->ip = cfg.defaultgw & br->mask; + // no ip address will be configured + else if (br->ip == 0) + goto err_no_ip; + + if ((br->iprange_start && in_netrange(br->iprange_start, br->ip, br->mask)) || + (br->iprange_end && in_netrange(br->iprange_end, br->ip, br->mask))) { + fprintf(stderr, "Error: IP range addresses not in network range\n"); + exit(1); + } + + return; + +err_no_ip: + br->arg_ip_none = 1; + fwarning("Not enough information to configure an IP address for\n interface --net=%s\n", br->dev); } @@ -93,7 +116,7 @@ void net_configure_sandbox_ip(Bridge *br) { if (br->arg_ip_none) br->ipsandbox = 0; - else if (br->ipsandbox && br->ip && br->mask) { + else if (br->ipsandbox) { // check network range char *rv = in_netrange(br->ipsandbox, br->ip, br->mask); if (rv) { @@ -106,20 +129,9 @@ void net_configure_sandbox_ip(Bridge *br) { exit(1); } } - else if (br->ipsandbox && br->masksandbox) { - // send an ARP request and check if there is anybody on this IP address - if (arp_check(br->dev, br->ipsandbox)) { - fprintf(stderr, "Error: IP address %d.%d.%d.%d is already in use\n", PRINT_IP(br->ipsandbox)); - exit(1); - } - } - else if (br->ip && br->mask) + else // ip address assigned by arp-scan for a bridge device br->ipsandbox = arp_assign(br->dev, br); //br->ip, br->mask); - else { - br->ipsandbox = 0; - br->arg_ip_none = 1; - } } @@ -159,31 +171,22 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) { // the default address should be in the range of at least on of the bridge devices void check_default_gw(uint32_t defaultgw) { assert(defaultgw); - if (cfg.bridge0.configured) { - if (cfg.bridge0.ip == 0 && cfg.bridge0.ipsandbox) - return; char *rv = in_netrange(defaultgw, cfg.bridge0.ip, cfg.bridge0.mask); if (rv == 0) return; } if (cfg.bridge1.configured) { - if (cfg.bridge1.ip == 0 && cfg.bridge1.ipsandbox) - return; char *rv = in_netrange(defaultgw, cfg.bridge1.ip, cfg.bridge1.mask); if (rv == 0) return; } if (cfg.bridge2.configured) { - if (cfg.bridge2.ip == 0 && cfg.bridge2.ipsandbox) - return; char *rv = in_netrange(defaultgw, cfg.bridge2.ip, cfg.bridge2.mask); if (rv == 0) return; } if (cfg.bridge3.configured) { - if (cfg.bridge3.ip == 0 && cfg.bridge3.ipsandbox) - return; char *rv = in_netrange(defaultgw, cfg.bridge3.ip, cfg.bridge3.mask); if (rv == 0) return; @@ -196,14 +199,22 @@ void check_default_gw(uint32_t defaultgw) { void net_check_cfg(void) { EUID_ASSERT(); int net_configured = 0; - if (cfg.bridge0.configured) + if (cfg.bridge0.configured) { + net_configure_bridge(&cfg.bridge0); net_configured++; - if (cfg.bridge1.configured) + } + if (cfg.bridge1.configured) { + net_configure_bridge(&cfg.bridge1); net_configured++; - if (cfg.bridge2.configured) + } + if (cfg.bridge2.configured) { + net_configure_bridge(&cfg.bridge2); net_configured++; - if (cfg.bridge3.configured) + } + if (cfg.bridge3.configured) { + net_configure_bridge(&cfg.bridge3); net_configured++; + } int if_configured = 0; 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) { fprintf(stderr, "Error: maximum 4 network devices are allowed\n"); exit(1); } - net_configure_bridge(br, ptr + 4); + br->dev = ptr + 4; + br->configured = 1; } else warning_feature_disabled("networking"); @@ -423,10 +424,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { fprintf(stderr, "Error: invalid IP range\n"); exit(1); } - if (in_netrange(br->iprange_start, br->ip, br->mask) || in_netrange(br->iprange_end, br->ip, br->mask)) { - fprintf(stderr, "Error: IP range addresses not in network range\n"); - exit(1); - } } else warning_feature_disabled("networking"); diff --git a/test/network/iprange.exp b/test/network/iprange.exp index 232cb9bbc..227fc58cb 100755 --- a/test/network/iprange.exp +++ b/test/network/iprange.exp @@ -29,9 +29,9 @@ expect { timeout {puts "TESTING ERROR 3\n";exit} "Child process initialized" } -sleep 1 +after 100 send -- "exit\r" -sleep 2 +sleep 1 send -- "firejail --profile=iprange.profile\r" expect { @@ -55,9 +55,9 @@ expect { timeout {puts "TESTING ERROR 8\n";exit} "Child process initialized" } -sleep 1 +after 100 send -- "exit\r" -sleep 2 +sleep 1 -- cgit v1.2.3-70-g09d2