Files
amethyst/quic
Claude e4d96421c2 fix(quic): reserved-bit checks, TLS bounds, SendBuffer shrink
Round 4 of the audit follow-ups.

* Reserved-bit enforcement on unmasked QUIC headers (RFC 9000 §17.2 /
  §17.3.1). Pre-fix the parser silently accepted long-header packets
  with bits 0x0C set or short-header packets with bits 0x18 set after
  HP unmasking — the spec mandates PROTOCOL_VIOLATION close. Added
  [QuicProtocolViolationException] and a top-level catch in
  feedDatagram that translates the throw into markClosedExternally.
  Long-header parse also drops a now-dead `if form==1` branch on the
  first-byte mask: we already early-returned in non-long paths above,
  so the mask is always 0x0F.

* TLS handshake-message bounds:
   - TlsCertificateChain.decodeBody: reject `listLen > r.remaining`
     up front; assert `r.position == end` after the cert loop.
     Without this, a malicious peer could push us into reading past
     the message limit on per-cert extensions.
   - TlsServerHello.decodeBody / TlsEncryptedExtensions.decodeBody:
     reject trailing bytes after the extensions block.
   - TlsEncryptedExtensions.alpn: enforce RFC 7301 §3.1 (server
     returns EXACTLY one protocol_name); validate outerLen matches
     remaining and reject multi-name responses.

* SendBuffer.data shrink: pre-fix the doubling-on-grow buffer never
  shrank, so a stream that ever held N bytes pinned `data.size = N`
  for the connection's lifetime. Long-tail memory retention on
  per-stream basis. advanceFlushedFloorIfPossible now releases
  capacity once live bytes occupy ≤ 1/4 of the allocation, shrinking
  to max(SHRINK_FLOOR_BYTES=4096, 2*dataLen). Below the floor the
  doubling cost is negligible; above it the multi-MiB transients
  release back to the heap.

All 269 :quic:jvmTest tests pass. BUILD SUCCESSFUL in 47s.

https://claude.ai/code/session_01AhGvbMV8uPRse3TmAGaddM
2026-05-08 23:40:20 +00:00
..