From 7cf68d50db096febce65ba05adbe478292eaf857 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 27 Oct 2016 23:30:57 +0700 Subject: [PATCH] fix DOS against ReceivedPacketHandler garbage collector fixes #334 --- ackhandler/received_packet_handler.go | 4 +++- ackhandler/received_packet_handler_test.go | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ackhandler/received_packet_handler.go b/ackhandler/received_packet_handler.go index f33eebc61..b0175b842 100644 --- a/ackhandler/received_packet_handler.go +++ b/ackhandler/received_packet_handler.go @@ -7,6 +7,7 @@ import ( "github.com/lucas-clemente/quic-go/frames" "github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/qerr" + "github.com/lucas-clemente/quic-go/utils" ) var ( @@ -134,7 +135,8 @@ func (h *receivedPacketHandler) GetAckFrame(dequeue bool) (*frames.AckFrame, err } func (h *receivedPacketHandler) garbageCollectReceivedTimes() { - for i := h.lowestInReceivedTimes; i <= h.ignorePacketsBelow; i++ { + // the highest element in the receivedTimes map is the largest observed packet + for i := h.lowestInReceivedTimes; i <= utils.MinPacketNumber(h.ignorePacketsBelow, h.largestObserved); i++ { delete(h.receivedTimes, i) } if h.ignorePacketsBelow > h.lowestInReceivedTimes { diff --git a/ackhandler/received_packet_handler_test.go b/ackhandler/received_packet_handler_test.go index 948ce93d2..1f06b61a5 100644 --- a/ackhandler/received_packet_handler_test.go +++ b/ackhandler/received_packet_handler_test.go @@ -310,5 +310,16 @@ var _ = Describe("receivedPacketHandler", func() { Expect(handler.receivedTimes).To(HaveKey(protocol.PacketNumber(4))) Expect(handler.lowestInReceivedTimes).To(Equal(protocol.PacketNumber(4))) }) + + // this prevents a DOS where a client sends us an unreasonably high LeastUnacked value + It("does not garbage collect packets higher than the LargestObserved packet number", func() { + err := handler.ReceivedPacket(10) + Expect(err).ToNot(HaveOccurred()) + handler.largestObserved = 5 + err = handler.ReceivedStopWaiting(&frames.StopWaitingFrame{LeastUnacked: 20}) + Expect(err).ToNot(HaveOccurred()) + Expect(handler.receivedTimes).To(HaveKey(protocol.PacketNumber(10))) + Expect(handler.lowestInReceivedTimes).To(Equal(protocol.PacketNumber(20))) + }) }) })