diff --git a/dns/dnsmessage/message.go b/dns/dnsmessage/message.go index 39692226..7a978b47 100644 --- a/dns/dnsmessage/message.go +++ b/dns/dnsmessage/message.go @@ -291,6 +291,7 @@ var ( errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)") errStringTooLong = errors.New("character string exceeds maximum length (255)") errParamOutOfOrder = errors.New("parameter out of order") + errTooLongSVCBValue = errors.New("value too long (>65535 bytes)") ) // Internal constants. diff --git a/dns/dnsmessage/svcb.go b/dns/dnsmessage/svcb.go index 21ba45d9..635e751d 100644 --- a/dns/dnsmessage/svcb.go +++ b/dns/dnsmessage/svcb.go @@ -5,6 +5,7 @@ package dnsmessage import ( + "math" "slices" "strings" ) @@ -171,6 +172,9 @@ func (r *SVCBResource) pack(msg []byte, compression map[string]uint16, compressi if i > 0 && param.Key <= previousKey { return oldMsg, &nestedError{"SVCBResource.Params", errParamOutOfOrder} } + if len(param.Value) > math.MaxUint16 { + return oldMsg, &nestedError{"SVCBResource.Params", errTooLongSVCBValue} + } msg = packUint16(msg, uint16(param.Key)) msg = packUint16(msg, uint16(len(param.Value))) msg = append(msg, param.Value...) diff --git a/dns/dnsmessage/svcb_test.go b/dns/dnsmessage/svcb_test.go index 6b49f0c8..74fcccda 100644 --- a/dns/dnsmessage/svcb_test.go +++ b/dns/dnsmessage/svcb_test.go @@ -6,6 +6,7 @@ package dnsmessage import ( "bytes" + "math" "reflect" "testing" ) @@ -364,3 +365,29 @@ func TestSVCBWireFormat(t *testing.T) { } testRecord(bytes, parsed) } + +func TestSVCBPackLongValue(t *testing.T) { + b := NewBuilder(nil, Header{}) + b.StartQuestions() + b.StartAnswers() + + res := SVCBResource{ + Target: MustNewName("example.com."), + Params: []SVCParam{ + { + Key: SVCParamMandatory, + Value: make([]byte, math.MaxUint16+1), + }, + }, + } + + err := b.SVCBResource(ResourceHeader{Name: MustNewName("example.com.")}, res) + if err == nil || err.Error() != "ResourceBody: SVCBResource.Params: value too long (>65535 bytes)" { + t.Fatalf(`b.SVCBResource() = %v; want = "ResourceBody: SVCBResource.Params: value too long (>65535 bytes)"`, err) + } + + err = b.HTTPSResource(ResourceHeader{Name: MustNewName("example.com.")}, HTTPSResource{res}) + if err == nil || err.Error() != "ResourceBody: SVCBResource.Params: value too long (>65535 bytes)" { + t.Fatalf(`b.HTTPSResource() = %v; want = "ResourceBody: SVCBResource.Params: value too long (>65535 bytes)"`, err) + } +}