From 7c23ba7b07f3a5a19272d61f242dc020dc38d576 Mon Sep 17 00:00:00 2001 From: Lucas Clemente Date: Fri, 27 May 2016 23:07:29 +0200 Subject: [PATCH] validate lengths when parsing frames ref #123 --- frames/connection_close_frame.go | 4 ++++ frames/connection_close_frame_test.go | 6 ++++++ frames/stream_frame.go | 4 ++++ frames/stream_frame_test.go | 6 ++++++ 4 files changed, 20 insertions(+) diff --git a/frames/connection_close_frame.go b/frames/connection_close_frame.go index dd773703..f7739573 100644 --- a/frames/connection_close_frame.go +++ b/frames/connection_close_frame.go @@ -38,6 +38,10 @@ func ParseConnectionCloseFrame(r *bytes.Reader) (*ConnectionCloseFrame, error) { return nil, err } + if reasonPhraseLen > uint16(protocol.MaxPacketSize) { + return nil, qerr.Error(qerr.InvalidConnectionCloseData, "reason phrase too long") + } + reasonPhrase := make([]byte, reasonPhraseLen) if _, err := io.ReadFull(r, reasonPhrase); err != nil { return nil, err diff --git a/frames/connection_close_frame_test.go b/frames/connection_close_frame_test.go index 452a30d0..0aee892a 100644 --- a/frames/connection_close_frame_test.go +++ b/frames/connection_close_frame_test.go @@ -29,6 +29,12 @@ var _ = Describe("ConnectionCloseFrame", func() { Expect(frame.ReasonPhrase).To(BeEmpty()) Expect(b.Len()).To(Equal(0)) }) + + It("rejects long reason phrases", func() { + b := bytes.NewReader([]byte{0x02, 0xAD, 0xFB, 0xCA, 0xDE, 0xff, 0xf}) + _, err := ParseConnectionCloseFrame(b) + Expect(err).To(MatchError(qerr.Error(qerr.InvalidConnectionCloseData, "reason phrase too long"))) + }) }) Context("when writing", func() { diff --git a/frames/stream_frame.go b/frames/stream_frame.go index da999178..b7be58f0 100644 --- a/frames/stream_frame.go +++ b/frames/stream_frame.go @@ -62,6 +62,10 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) { } } + if dataLen > uint16(protocol.MaxPacketSize) { + return nil, qerr.Error(qerr.InvalidStreamData, "data len too large") + } + if dataLen == 0 { // The rest of the packet is data frame.Data, err = ioutil.ReadAll(r) diff --git a/frames/stream_frame_test.go b/frames/stream_frame_test.go index ff5d5608..f365ac8b 100644 --- a/frames/stream_frame_test.go +++ b/frames/stream_frame_test.go @@ -47,6 +47,12 @@ var _ = Describe("StreamFrame", func() { _, err := ParseStreamFrame(b) Expect(err).To(MatchError(qerr.EmptyStreamFrameNoFin)) }) + + It("rejects frames to too large dataLen", func() { + b := bytes.NewReader([]byte{0xa0, 0x1, 0xff, 0xf}) + _, err := ParseStreamFrame(b) + Expect(err).To(MatchError(qerr.Error(qerr.InvalidStreamData, "data len too large"))) + }) }) Context("when writing", func() {