dns/dnsmessage: add boundary check in unpackSVCBResource Currently, bodyEnd is calculated using the length parameter from the resource header without verifying if it exceeds the physical capacity of the msg buffer. If a malformed record provides a length that exceeds the buffer, it bypasses the first-pass parameter validation and causes an out-of-bounds slice during the second-pass copy. Adding a check against len(msg) aligns this function with the boundary enforcement used throughout the rest of the package. Change-Id: I13f6ca83d1c30eac02286a49c12f8ec543d33e41 GitHub-Last-Rev: 78c35a160c45f09f2db04d9ec076dfb091a15595 GitHub-Pull-Request: golang/net#249 Reviewed-on: https://go-review.googlesource.com/c/net/+/781880 Reviewed-by: Sean Liao <sean@liao.dev> Reviewed-by: ISMAIL GAMAL <ismailismailgamal52@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/dns/dnsmessage/svcb.go b/dns/dnsmessage/svcb.go index 7729378..977d91e 100644 --- a/dns/dnsmessage/svcb.go +++ b/dns/dnsmessage/svcb.go
@@ -188,6 +188,10 @@ paramsOff := off bodyEnd := off + int(length) + if bodyEnd > len(msg) { + return SVCBResource{}, errResourceLen + } + var err error if r.Priority, paramsOff, err = unpackUint16(msg, paramsOff); err != nil { return SVCBResource{}, &nestedError{"Priority", err}
diff --git a/dns/dnsmessage/svcb_test.go b/dns/dnsmessage/svcb_test.go index 64a1bfd..02b388b 100644 --- a/dns/dnsmessage/svcb_test.go +++ b/dns/dnsmessage/svcb_test.go
@@ -437,3 +437,31 @@ }) } } + +func TestSVCBUnpackOutOfBounds(t *testing.T) { + // A minimal DNS message with an SVCB record where the header Length + // field (65535) maliciously exceeds the physical bounds of the buffer. + msg := []byte{ + 0x00, 0x01, // ID + 0x00, 0x00, // Flags + 0x00, 0x00, // QDCount = 0 + 0x00, 0x01, // ANCount = 1 + 0x00, 0x00, // NSCount = 0 + 0x00, 0x00, // ARCount = 0 + 0x00, // Name: "." + 0x00, 0x40, // Type: SVCB + 0x00, 0x01, // Class: INET + 0x00, 0x00, 0x00, 0x00, // TTL + 0xff, 0xff, // Length: 65535 (Spoofed) + 0x00, 0x01, // Priority + 0x00, // Target + 0x00, 0x01, // Param Key + 0xff, 0xf8, // Param Length + } + + var m Message + err := m.Unpack(msg) + if err == nil { + t.Fatal("expected error parsing malformed message, got nil") + } +}