diff --git a/internal/wire/ietf_header.go b/internal/wire/ietf_header.go index 38188641..9bc23d27 100644 --- a/internal/wire/ietf_header.go +++ b/internal/wire/ietf_header.go @@ -60,6 +60,9 @@ func parseLongHeader(b *bytes.Reader, packetSentBy protocol.Perspective, typeByt if packetSentBy == protocol.PerspectiveClient { return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "sent by the client") } + if b.Len() == 0 { + return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list") + } h.SupportedVersions = make([]protocol.VersionNumber, b.Len()/4) for i := 0; b.Len() > 0; i++ { v, err := utils.BigEndian.ReadUint32(b) diff --git a/internal/wire/ietf_header_test.go b/internal/wire/ietf_header_test.go index 16f6c031..ecd96bab 100644 --- a/internal/wire/ietf_header_test.go +++ b/internal/wire/ietf_header_test.go @@ -78,6 +78,12 @@ var _ = Describe("Header", func() { _, err := ParseHeader(b, protocol.PerspectiveClient) Expect(err).To(MatchError("InvalidVersionNegotiationPacket: sent by the client")) }) + + It("errors if the version list is emtpy", func() { + b := bytes.NewReader(data) + _, err := ParseHeader(b, protocol.PerspectiveServer) + Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list")) + }) }) }) diff --git a/internal/wire/public_header.go b/internal/wire/public_header.go index 5b3a18c4..0e9d9b7d 100644 --- a/internal/wire/public_header.go +++ b/internal/wire/public_header.go @@ -205,6 +205,9 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, versi // Version (optional) if !header.ResetFlag && header.VersionFlag { if packetSentBy == protocol.PerspectiveServer { // parse the version negotiaton packet + if b.Len() == 0 { + return nil, qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list") + } if b.Len()%4 != 0 { return nil, qerr.InvalidVersionNegotiationPacket } diff --git a/internal/wire/public_header_test.go b/internal/wire/public_header_test.go index 07a5a281..98414cdf 100644 --- a/internal/wire/public_header_test.go +++ b/internal/wire/public_header_test.go @@ -145,14 +145,10 @@ var _ = Describe("Public Header", func() { Expect(b.Len()).To(BeZero()) }) - It("parses a version negotiation packet that contains 0 versions", func() { + It("errors if it doesn't contain any versions", func() { b := bytes.NewReader([]byte{0x9, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}) - hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown) - Expect(err).ToNot(HaveOccurred()) - Expect(hdr.VersionFlag).To(BeTrue()) - Expect(hdr.VersionNumber).To(BeZero()) // unitialized - Expect(hdr.SupportedVersions).To(BeEmpty()) - Expect(b.Len()).To(BeZero()) + _, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown) + Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list")) }) It("reads version negotiation packets containing unsupported versions", func() {