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());