crypto/tls: avoid overflow in parseECHConfigList

When parsing an ECHConfigList, length fields were previously evaluated
as a uint16. This would cause an infinite loop to occur when parsing a
65532 bytes long ECHConfig with a declared outer length header of 0.

Triggering this condition requires a payload of at least 65538 bytes. As
ECHConfigList payloads are typically delivered via protocols that limit
them to 65535 bytes (DNS HTTPS records and TLS extensions), regular
clients are safe from this issue.

Thank you to Nguyễn Hoàng Hải (facebookmark2022@gmail.com) for reporting
this issue.

Fixes #80513

Change-Id: I8c5011d3b375c24794dd38b915bb4dc06a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/804040
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
yuhan6665
2026-09-10 23:19:13 -04:00
parent 05238fd2b0
commit cd92ddab44
+3 -3
View File
@@ -65,7 +65,7 @@ func parseECHConfig(enc []byte) (skip bool, ec EchConfig, err error) {
if len(ec.raw) < int(ec.Length)+4 {
return false, EchConfig{}, &echConfigErr{"length"}
}
ec.raw = ec.raw[:ec.Length+4]
ec.raw = ec.raw[:int(ec.Length)+4]
if ec.Version != extensionEncryptedClientHello {
s.Skip(int(ec.Length))
return true, EchConfig{}, nil
@@ -128,7 +128,7 @@ func parseECHConfigList(data []byte) ([]EchConfig, error) {
if !s.ReadUint16(&length) {
return nil, errMalformedECHConfigList
}
if length != uint16(len(data)-2) {
if int(length) != len(data)-2 {
return nil, errMalformedECHConfigList
}
var configs []EchConfig
@@ -136,7 +136,7 @@ func parseECHConfigList(data []byte) ([]EchConfig, error) {
if len(s) < 4 {
return nil, errors.New("tls: malformed ECHConfig")
}
configLen := uint16(s[2])<<8 | uint16(s[3])
configLen := int(s[2])<<8 | int(s[3])
skip, ec, err := parseECHConfig(s)
if err != nil {
return nil, err