From 2fd5af9f929bce8219f9616ac8510d121483f108 Mon Sep 17 00:00:00 2001 From: Tom Thorogood Date: Mon, 1 Feb 2021 18:45:50 +1030 Subject: [PATCH] Validate Rdlength and off in UnpackRRWithHeader (#1215) --- msg.go | 11 +++++++++-- parse_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/msg.go b/msg.go index 7001f6da..1728a98b 100644 --- a/msg.go +++ b/msg.go @@ -624,11 +624,18 @@ func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err rr = &RFC3597{Hdr: h} } - if noRdata(h) { - return rr, off, nil + if off < 0 || off > len(msg) { + return &h, off, &Error{err: "bad off"} } end := off + int(h.Rdlength) + if end < off || end > len(msg) { + return &h, end, &Error{err: "bad rdlength"} + } + + if noRdata(h) { + return rr, off, nil + } off, err = rr.unpack(msg, off) if err != nil { diff --git a/parse_test.go b/parse_test.go index 886f46cc..1895506e 100644 --- a/parse_test.go +++ b/parse_test.go @@ -1884,3 +1884,41 @@ func TestParseAPLErrors(t *testing.T) { }) } } + +func TestUnpackRRWithHeaderInvalidLengths(t *testing.T) { + rr, err := NewRR("test.example.org. 300 IN SSHFP 1 2 BC6533CDC95A79078A39A56EA7635984ED655318ADA9B6159E30723665DA95BB") + if err != nil { + t.Fatalf("failed to parse SSHFP record: %v", err) + } + + buf := make([]byte, Len(rr)) + headerEnd, end, err := packRR(rr, buf, 0, compressionMap{}, false) + if err != nil { + t.Fatalf("failed to pack A record: %v", err) + } + + rr.Header().Rdlength = uint16(end - headerEnd) + for _, off := range []int{ + -1, + end + 1, + 1<<16 - 1, + } { + _, _, err := UnpackRRWithHeader(*rr.Header(), buf, off) + if de, ok := err.(*Error); !ok || de.err != "bad off" { + t.Errorf("UnpackRRWithHeader with bad offset (%d) returned wrong or no error: %v", off, err) + } + } + + for _, rdlength := range []uint16{ + uint16(end - headerEnd + 1), + uint16(end), + 1<<16 - 1, + } { + rr.Header().Rdlength = rdlength + + _, _, err := UnpackRRWithHeader(*rr.Header(), buf, headerEnd) + if de, ok := err.(*Error); !ok || de.err != "bad rdlength" { + t.Errorf("UnpackRRWithHeader with bad rdlength (%d) returned wrong or no error: %v", rdlength, err) + } + } +}