]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Fix fault where chronyd enters an endless loop on x86_64
authorJohn Hasler <john@dhh.gt.org>
Tue, 29 Apr 2008 17:40:15 +0000 (12:40 -0500)
committerRichard P. Curnow <rc@rc0.org.uk>
Wed, 1 Oct 2008 22:57:20 +0000 (23:57 +0100)
John writes:
Here is a patch that should prevent the endless loop.  I've changed
UTI_NormaliseTimeval() to use divide/remainder instead of a loop.  It also
replaces some similar loops with calls to UTI_NormaliseTimeval() and fixes
an unrelated bug in UTI_DiffTimevals().

util.c

diff --git a/util.c b/util.c
index 431be1ece25e2cc7a86107345140fe525c47f099..d506ffdaaa44495c2e26e70526689d251b5d1a9f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -87,15 +87,17 @@ UTI_CompareTimevals(struct timeval *a, struct timeval *b)
 INLINE_STATIC void
 UTI_NormaliseTimeval(struct timeval *x)
 {
-  while (x->tv_usec >= 1000000) {
-    ++x->tv_sec;
-    x->tv_usec -= 1000000;
+  /* Reduce tv_usec to within +-1000000 of zero. JGH */
+  if ((x->tv_usec >= 1000000) || (x->tv_usec <= -1000000)) {
+    x->tv_sec += x->tv_usec/1000000;
+    x->tv_usec = x->tv_usec%1000000;
   }
 
-  while (x->tv_usec < 0) {
+  /* Make tv_usec positive. JGH */
+   if (x->tv_usec < 0) {
     --x->tv_sec;
     x->tv_usec += 1000000;
 }
+ }
 
 }
 
@@ -110,17 +112,9 @@ UTI_DiffTimevals(struct timeval *result,
   result->tv_usec = a->tv_usec - b->tv_usec;
 
   /* Correct microseconds field to bring it into the range
-     [0,1000000) */
+     (0,1000000) */
 
-  while (result->tv_usec < 0) {
-    result->tv_usec += 1000000;
-    --result->tv_sec;
-  }
-
-  while (result->tv_usec > 999999) {
-    result->tv_usec -= 1000000;
-    ++result->tv_sec;
-  }
+  UTI_NormaliseTimeval(result); /* JGH */
 
   return;
 }
@@ -191,7 +185,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier,
   }
 
   tvhalf.tv_sec = tvdiff.tv_sec / 2;
-  tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2);
+  tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2) * 500000; /* JGH */
   
   average->tv_sec  = earlier->tv_sec  + tvhalf.tv_sec;
   average->tv_usec = earlier->tv_usec + tvhalf.tv_usec;
@@ -199,17 +193,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier,
   /* Bring into range */
   UTI_NormaliseTimeval(average);
 
-  while (average->tv_usec >= 1000000) {
-    ++average->tv_sec;
-    average->tv_usec -= 1000000;
-  }
-
-  while (average->tv_usec < 0) {
-    --average->tv_sec;
-    average->tv_usec += 1000000;
-  }
-
-}
+ }
 
 /* ================================================== */