From 990203b4776c19a259e9b41fe6298ef0e17a2a08 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Wed, 10 Jan 2024 17:26:06 -0800 Subject: [PATCH] Bound memory use in RETIRE_CONNECTION_ID frame queue --- quinn-proto/src/connection/mod.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/quinn-proto/src/connection/mod.rs b/quinn-proto/src/connection/mod.rs index 27111f1a0..b70a0abcc 100644 --- a/quinn-proto/src/connection/mod.rs +++ b/quinn-proto/src/connection/mod.rs @@ -2718,10 +2718,22 @@ impl Connection { match self.rem_cids.insert(frame) { Ok(None) => {} Ok(Some((retired, reset_token))) => { - self.spaces[SpaceId::Data] - .pending - .retire_cids - .extend(retired); + let pending_retired = + &mut self.spaces[SpaceId::Data].pending.retire_cids; + /// Ensure `pending_retired` cannot grow without bound. Limit is + /// somewhat arbitrary but very permissive. + const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; + // We don't bother counting in-flight frames because those are bounded + // by congestion control. + if (pending_retired.len() as u64) + .saturating_add(retired.end.saturating_sub(retired.start)) + > MAX_PENDING_RETIRED_CIDS + { + return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( + "queued too many retired CIDs", + )); + } + pending_retired.extend(retired); self.set_reset_token(reset_token); } Err(InsertError::ExceedsLimit) => {