]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix IPv6 prefix underflow when confirming deprecated but valid leases.
authorRoy Marples <roy@marples.name>
Wed, 6 May 2015 15:21:56 +0000 (15:21 +0000)
committerRoy Marples <roy@marples.name>
Wed, 6 May 2015 15:21:56 +0000 (15:21 +0000)
ipv6.c

diff --git a/ipv6.c b/ipv6.c
index 66c2fca17fcf3d93cbb2c816ffe0d833baf22459..759bc1e30047f809cd6826249751063d28bb264d 100644 (file)
--- a/ipv6.c
+++ b/ipv6.c
@@ -689,20 +689,32 @@ ipv6_addaddr(struct ipv6_addr *ap, const struct timespec *now)
                        now = &n;
                }
                timespecsub(now, &ap->acquired, &n);
-               if (ap->prefix_pltime != ND6_INFINITE_LIFETIME)
+               if (ap->prefix_pltime != ND6_INFINITE_LIFETIME) {
                        ap->prefix_pltime -= (uint32_t)n.tv_sec;
+                       /* This can happen when confirming a
+                        * deprecated but still valid lease. */
+                       if (ap->prefix_pltime > pltime)
+                               ap->prefix_pltime = 0;
+               }
                if (ap->prefix_vltime != ND6_INFINITE_LIFETIME)
                        ap->prefix_vltime -= (uint32_t)n.tv_sec;
-       }
 
-       if (if_addaddress6(ap) == -1) {
-               logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
 #if 0
+               logger(ap->iface->ctx, LOG_DEBUG,
+                   "%s: acquired %lld.%.9ld, now %lld.%.9ld, diff %lld.%.9ld",
+                   ap->iface->name,
+                   (long long)ap->acquired.tv_sec, ap->acquired.tv_nsec,
+                   (long long)now->tv_sec, now->tv_nsec,
+                   (long long)n.tv_sec, n.tv_nsec);
                logger(ap->iface->ctx, LOG_DEBUG,
                    "%s: adj pltime %"PRIu32" seconds, "
                    "vltime %"PRIu32" seconds",
                    ap->iface->name, ap->prefix_pltime, ap->prefix_vltime);
 #endif
+       }
+
+       if (if_addaddress6(ap) == -1) {
+               logger(ap->iface->ctx, LOG_ERR, "if_addaddress6: %m");
                /* Restore real pltime and vltime */
                ap->prefix_pltime = pltime;
                ap->prefix_vltime = vltime;