From ac23c1d3091e02d8aa5e41718d9ccd993597451d Mon Sep 17 00:00:00 2001 From: George Hicken Date: Mon, 30 Jul 2018 15:44:43 -0700 Subject: [PATCH] Avoid integer overflow in dhcp renewal (#8154) This ensures that we do not get an integer overflow after 64 contiguous failures to renew a DHCP lease. That was resulting in a divide-by-zero and, depending on how the runtime handling went, a silent exit or a panic. (cherry picked from commit c119a8aa7a0cb666577b09b436318d32143fc658) --- lib/tether/ops_linux.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/tether/ops_linux.go b/lib/tether/ops_linux.go index 2b4010477c..267a7010ce 100644 --- a/lib/tether/ops_linux.go +++ b/lib/tether/ops_linux.go @@ -756,8 +756,11 @@ func ApplyEndpoint(nl Netlink, t *BaseOperations, endpoint *NetworkEndpoint) err } func (t *BaseOperations) dhcpLoop(stop chan struct{}, e *NetworkEndpoint, dc client.Client) { - divisor := time.Duration(2) + // wait half of the remaining lease time before trying again if we fail to renew exp := time.After(dc.LastAck().LeaseTime() / 2) + // the divisor starts set to 4 so that we can update it AFTER the duration is calculated. This allows combining the check for integer overflow with + // the minimum wait time. + divisor := time.Duration(4) for { select { case <-stop: @@ -772,13 +775,13 @@ func (t *BaseOperations) dhcpLoop(stop chan struct{}, e *NetworkEndpoint, dc cli if err != nil { log.Errorf("failed to renew ip address for network %s: %s", e.Name, err) - // wait half of the remaining lease time before trying again - divisor *= 2 duration := dc.LastAck().LeaseTime() / divisor // for now go with a minimum retry of 1min if duration < time.Minute { duration = time.Minute + } else if divisor*2 > divisor { + divisor *= 2 } exp = time.After(duration)