Avoid time operations that can panic

We have reports of runtime panics (linkerd/linkerd2#7748) that sound a
lot like rust-lang/rust#86470. We don't have any evidence that these
panics originate in h2, but there is one use of `Instant::sub` that
could panic in this way.

Even though this is almost definitely a bug in Rust, it seems most
prudent to actively avoid the uses of `Instant` that are prone to this
bug. These fixes should ultimately be made in the standard library, but
this change lets us avoid this problem while we wait for those fixes.

This change replaces uses of `Instant::elapsed` and `Instant::sub` with
calls to `Instant::saturating_duration_since` to prevent this class of
panic.

See also hyperium/hyper#2746
This commit is contained in:
Oliver Gould
2022-01-31 23:52:42 +00:00
committed by Sean McArthur
parent b0d01bb200
commit 4dc2b4a164

View File

@@ -860,7 +860,10 @@ impl Recv {
let reset_duration = self.reset_duration; let reset_duration = self.reset_duration;
while let Some(stream) = self.pending_reset_expired.pop_if(store, |stream| { while let Some(stream) = self.pending_reset_expired.pop_if(store, |stream| {
let reset_at = stream.reset_at.expect("reset_at must be set if in queue"); let reset_at = stream.reset_at.expect("reset_at must be set if in queue");
now - reset_at > reset_duration // rust-lang/rust#86470 tracks a bug in the standard library where `Instant`
// subtraction can panic (because, on some platforms, `Instant` isn't actually
// monotonic). We use a saturating operation to avoid this panic here.
now.saturating_duration_since(reset_at) > reset_duration
}) { }) {
counts.transition_after(stream, true); counts.transition_after(stream, true);
} }