Protect against integer overflow in BackoffEntrySerializer

Bug: 1172708
Change-Id: I4c5c87a3b3c7f27295ed4aa067c04a74ee4009bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2664806
Reviewed-by: Maksim Orlovich <[email protected]>
Commit-Queue: Dan McArdle <[email protected]>
Cr-Commit-Position: refs/heads/master@{#850644}
diff --git a/net/base/backoff_entry_serializer.cc b/net/base/backoff_entry_serializer.cc
index 8c0ac3a7..9f7832ab 100644
--- a/net/base/backoff_entry_serializer.cc
+++ b/net/base/backoff_entry_serializer.cc
@@ -37,9 +37,17 @@
 
   serialized->AppendInteger(entry.failure_count());
 
-  // Can't use entry.GetTimeUntilRelease as it doesn't allow negative deltas.
-  base::TimeDelta backoff_duration =
-      entry.GetReleaseTime() - entry.GetTimeTicksNow();
+  // Convert both |base::TimeTicks| values into |base::TimeDelta| values by
+  // subtracting |kZeroTicks. This way, the top-level subtraction uses
+  // |base::TimeDelta::operator-|, which has clamping semantics.
+  const base::TimeTicks kZeroTicks;
+  base::TimeDelta backoff_duration = (entry.GetReleaseTime() - kZeroTicks) -
+                                     (entry.GetTimeTicksNow() - kZeroTicks);
+  // We cannot serialize infinity doubles as JSON values, so default to zero.
+  if (backoff_duration.is_inf()) {
+    backoff_duration = base::TimeDelta();
+  }
+
   // Redundantly stores both the remaining time delta and the absolute time.
   // The delta is used to work around some cases where wall clock time changes.
   serialized->AppendDouble(backoff_duration.InSecondsF());