]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.24] net/mail: avoid quadratic behavior in mail address parsing
authorDamien Neil <dneil@google.com>
Thu, 25 Sep 2025 21:41:53 +0000 (14:41 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 7 Oct 2025 18:00:31 +0000 (11:00 -0700)
RFC 5322 domain-literal parsing built the dtext value one character
at a time with string concatenation, resulting in excessive
resource consumption when parsing very large domain-literal values.

Replace with a subslice.

Benchmark not included in this CL because it's too narrow to be
of general ongoing use, but for:

    ParseAddress("alice@[" + strings.Repeat("a", 0x40000) + "]")

goos: darwin
goarch: arm64
pkg: net/mail
cpu: Apple M4 Pro
                │  /tmp/bench.0  │            /tmp/bench.1             │
                │     sec/op     │   sec/op     vs base                │
ParseAddress-14   1987.732m ± 9%   1.524m ± 5%  -99.92% (p=0.000 n=10)

                │   /tmp/bench.0   │             /tmp/bench.1              │
                │       B/op       │     B/op      vs base                 │
ParseAddress-14   33692.767Mi ± 0%   1.282Mi ± 0%  -100.00% (p=0.000 n=10)

                │  /tmp/bench.0  │            /tmp/bench.1            │
                │   allocs/op    │ allocs/op   vs base                │
ParseAddress-14   263711.00 ± 0%   17.00 ± 0%  -99.99% (p=0.000 n=10)

Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

Fixes CVE-2025-61725
For #75680
Fixes #75700

Change-Id: Id971c2d5b59882bb476e22fceb7e01ec08234bb7
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2840
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2962
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/709835
Auto-Submit: Michael Pratt <mpratt@google.com>
TryBot-Bypass: Michael Pratt <mpratt@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
src/net/mail/message.go

index 21b075e78affbe7f6c8667fa720ba523e0e62536..0925484741f0ae08901dbc806a98d39fee62dcbd 100644 (file)
@@ -725,7 +725,8 @@ func (p *addrParser) consumeDomainLiteral() (string, error) {
        }
 
        // Parse the dtext
-       var dtext string
+       dtext := p.s
+       dtextLen := 0
        for {
                if p.empty() {
                        return "", errors.New("mail: unclosed domain-literal")
@@ -742,9 +743,10 @@ func (p *addrParser) consumeDomainLiteral() (string, error) {
                        return "", fmt.Errorf("mail: bad character in domain-literal: %q", r)
                }
 
-               dtext += p.s[:size]
+               dtextLen += size
                p.s = p.s[size:]
        }
+       dtext = dtext[:dtextLen]
 
        // Skip the trailing ]
        if !p.consume(']') {