From be644098d73caed0c8cbea6c224e9985f5c20156 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Thu, 24 Jun 2021 14:34:13 +0200 Subject: [PATCH] nic_router: fix exc. in Interface::handle_config_3 When Interface::handle_config_3 (third step of applying a new configuration to interfaces) tried to detach the interface from the current IP config because the old and new IP config differed, it did so using the new domain. The former steps of the reconfiguration already installed the new domain reference at the interface. Therefore, also the DHCP server of the new domain was used. This, however caused uncaught exceptions because detaching from an IP config includes dissolving all DHCP allocations. This dissolving of DHCP allocations now operated on a DHCP server (the one of the new domain) that wasn't related to the allocations and, in the worst case, caused an uncaught exception because the IPs were out of its range. That said, this commit ensures that detaching an interface from an IP config is always done on the domain from which the IP config originated. Normally, this is the domain the interface is attached to. But in the case of Interface::handle_config_3, it is another - the former domain the interface was attached to. The commit also adapts the nic_router_dhcp_* tests in a way that they reconfigure the router in a way that would trigger the uncaught exception without the fix. Fixes #4200 --- repos/os/run/nic_router_dhcp.inc | 37 +++++++++++++++++---- repos/os/src/server/nic_router/domain.cc | 2 +- repos/os/src/server/nic_router/interface.cc | 7 ++-- repos/os/src/server/nic_router/interface.h | 2 +- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/repos/os/run/nic_router_dhcp.inc b/repos/os/run/nic_router_dhcp.inc index 7d62956a12..cdc7c1e502 100644 --- a/repos/os/run/nic_router_dhcp.inc +++ b/repos/os/run/nic_router_dhcp.inc @@ -71,7 +71,7 @@ append config { - + @@ -93,17 +93,17 @@ append config { - + - + - + @@ -114,7 +114,26 @@ append config { - + + + + + + + + + + + + + + + + + + + @@ -133,7 +152,7 @@ append config { - + @@ -281,6 +300,10 @@ append done_string ".*DHCP request completed:.*\n" append done_string ".* IP lease time: 3600 seconds.*\n" append done_string ".* Interface: 10.0.3.2/24.*\n" append done_string ".* Router: 10.0.3.1.*\n" +append done_string ".*DHCP request completed:.*\n" +append done_string ".* IP lease time: 3600 seconds.*\n" +append done_string ".* Interface: 10.0.3.2/24.*\n" +append done_string ".* Router: 10.0.3.1.*\n" append done_string ".* DNS server #1: 1.2.3.4.*\n" append done_string ".* DNS server #2: 2.3.4.5.*\n" append done_string ".* DNS server #3: 3.4.5.6.*\n" diff --git a/repos/os/src/server/nic_router/domain.cc b/repos/os/src/server/nic_router/domain.cc index 8e0870a59f..9ddb6f3a77 100644 --- a/repos/os/src/server/nic_router/domain.cc +++ b/repos/os/src/server/nic_router/domain.cc @@ -73,7 +73,7 @@ void Domain::_prepare_reconstructing_ip_config() /* detach all dependent interfaces from old IP config */ _interfaces.for_each([&] (Interface &interface) { - interface.detach_from_ip_config(); + interface.detach_from_ip_config(*this); }); _ip_config_dependents.for_each([&] (Domain &domain) { domain._interfaces.for_each([&] (Interface &interface) { diff --git a/repos/os/src/server/nic_router/interface.cc b/repos/os/src/server/nic_router/interface.cc index 6e9d3c9910..deb992d64b 100644 --- a/repos/os/src/server/nic_router/interface.cc +++ b/repos/os/src/server/nic_router/interface.cc @@ -412,10 +412,9 @@ void Interface::attach_to_ip_config(Domain &domain, } -void Interface::detach_from_ip_config() +void Interface::detach_from_ip_config(Domain &domain) { /* destroy our own ARP waiters */ - Domain &domain = _domain(); while (_own_arp_waiters.first()) { cancel_arp_waiting(*_own_arp_waiters.first()->object()); } @@ -453,7 +452,7 @@ void Interface::attach_to_remote_ip_config() void Interface::_detach_from_domain() { try { - detach_from_ip_config(); + detach_from_ip_config(domain()); _detach_from_domain_raw(); } catch (Pointer::Invalid) { } @@ -2086,7 +2085,7 @@ void Interface::handle_config_3() /* if the IP configs differ, detach completely from the IP config */ if (old_domain.ip_config() != new_domain.ip_config()) { - detach_from_ip_config(); + detach_from_ip_config(old_domain); attach_to_domain_finish(); return; } diff --git a/repos/os/src/server/nic_router/interface.h b/repos/os/src/server/nic_router/interface.h index 393b2ab45f..d76d5b8ff0 100644 --- a/repos/os/src/server/nic_router/interface.h +++ b/repos/os/src/server/nic_router/interface.h @@ -436,7 +436,7 @@ class Net::Interface : private Interface_list::Element void attach_to_domain(); - void detach_from_ip_config(); + void detach_from_ip_config(Domain &domain); void attach_to_ip_config(Domain &domain, Ipv4_config const &ip_config);