diff options
| author | Damien Neil <dneil@google.com> | 2025-09-30 15:11:16 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-10-07 11:00:38 -0700 |
| commit | a402f4ad285514f5f3db90516d72047d591b307a (patch) | |
| tree | 12ce5f8f46b3fd99b6e594f5b3f77186f95325a8 | |
| parent | f9f198ab05e3282cbf6b13251d47d9141981e401 (diff) | |
| download | go-a402f4ad285514f5f3db90516d72047d591b307a.tar.xz | |
[release-branch.go1.24] net/textproto: avoid quadratic complexity in Reader.ReadResponse
Reader.ReadResponse constructed a response string from repeated
string concatenation, permitting a malicious sender to cause excessive
memory allocation and CPU consumption by sending a response consisting
of many short lines.
Use a strings.Builder to construct the string instead.
Thanks to Jakub Ciolek for reporting this issue.
Fixes CVE-2025-61724
For #75716
Fixes #75717
Change-Id: I1a98ce85a21b830cb25799f9ac9333a67400d736
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2940
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2980
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/709837
Reviewed-by: Carlos Amedee <carlos@golang.org>
TryBot-Bypass: Michael Pratt <mpratt@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
| -rw-r--r-- | src/net/textproto/reader.go | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go index f98e05bd1d..2c926ca876 100644 --- a/src/net/textproto/reader.go +++ b/src/net/textproto/reader.go @@ -284,8 +284,10 @@ func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err err // // An expectCode <= 0 disables the check of the status code. func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error) { - code, continued, message, err := r.readCodeLine(expectCode) + code, continued, first, err := r.readCodeLine(expectCode) multi := continued + var messageBuilder strings.Builder + messageBuilder.WriteString(first) for continued { line, err := r.ReadLine() if err != nil { @@ -296,12 +298,15 @@ func (r *Reader) ReadResponse(expectCode int) (code int, message string, err err var moreMessage string code2, continued, moreMessage, err = parseCodeLine(line, 0) if err != nil || code2 != code { - message += "\n" + strings.TrimRight(line, "\r\n") + messageBuilder.WriteByte('\n') + messageBuilder.WriteString(strings.TrimRight(line, "\r\n")) continued = true continue } - message += "\n" + moreMessage + messageBuilder.WriteByte('\n') + messageBuilder.WriteString(moreMessage) } + message = messageBuilder.String() if err != nil && multi && message != "" { // replace one line error message with all lines (full message) err = &Error{code, message} |
