@@ -54,6 +54,7 @@ SRC_URI += "\
file://CVE-2026-42499.patch \
file://CVE-2026-42501.patch \
file://CVE-2026-42504.patch \
+ file://CVE-2026-42507.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
new file mode 100644
@@ -0,0 +1,160 @@
+From 943e53a7b667a1570648b5f1c4592b9d9d5b4aac Mon Sep 17 00:00:00 2001
+From: "Nicholas S. Husin" <nsh@golang.org>
+Date: Mon, 11 May 2026 18:04:07 -0400
+Subject: [PATCH] net/textproto: escape arbitrary input when including them in
+ errors
+
+When returning errors, functions in the net/textproto package would
+include its input as part of the error, without any escaping. Note that
+said input is often controlled by external parties when using this
+package naturally. For example, a net/http client uses ReadMIMEHeader
+when parsing the headers it receive from a server.
+
+As a result, an attacker could inject arbitrary content into the error.
+Practically, this can result in an attacker injecting misleading
+content, terminal control bytes, etc. into a victim's output or logs.
+
+Fix this issue by making sure that ProtocolError usages within the
+package are properly escaped, and that Error.String will escape its Msg.
+
+Fixes #79346
+Fixes CVE-2026-42507
+
+Change-Id: Ide4c1005d8254f90d95d7a389b8ca3a26a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/777060
+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>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-by: Damien Neil <dneil@google.com>
+
+CVE: CVE-2026-42507
+Upstream-Status: Backport [https://github.com/golang/go/commit/1a7e601d07b67aec8d795c8182ee7257ba7d1960]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/smtp/smtp_test.go | 6 +++---
+ src/net/textproto/reader.go | 14 +++++++-------
+ src/net/textproto/reader_test.go | 6 ++++--
+ src/net/textproto/textproto.go | 2 +-
+ 4 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
+index 259b10b93d..3e03da5208 100644
+--- a/src/net/smtp/smtp_test.go
++++ b/src/net/smtp/smtp_test.go
+@@ -664,7 +664,7 @@ func TestHello(t *testing.T) {
+ err = c.Hello("customhost")
+ case 1:
+ err = c.StartTLS(nil)
+- if err.Error() == "502 Not implemented" {
++ if err.Error() == `502 "Not implemented"` {
+ err = nil
+ }
+ case 2:
+@@ -922,8 +922,8 @@ func TestAuthFailed(t *testing.T) {
+
+ if err == nil {
+ t.Error("Auth: expected error; got none")
+- } else if err.Error() != "535 Invalid credentials\nplease see www.example.com" {
+- t.Errorf("Auth: got error: %v, want: %s", err, "535 Invalid credentials\nplease see www.example.com")
++ } else if err.Error() != `535 "Invalid credentials\nplease see www.example.com"` {
++ t.Errorf("Auth: got error: %v, want: %s", err, `535 "Invalid credentials\nplease see www.example.com"`)
+ }
+
+ bcmdbuf.Flush()
+diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
+index 0027efe3ca..b4cd22a6ed 100644
+--- a/src/net/textproto/reader.go
++++ b/src/net/textproto/reader.go
+@@ -213,13 +213,13 @@ func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message
+
+ func parseCodeLine(line string, expectCode int) (code int, continued bool, message string, err error) {
+ if len(line) < 4 || line[3] != ' ' && line[3] != '-' {
+- err = ProtocolError("short response: " + line)
++ err = ProtocolError(fmt.Sprintf("short response: %q", line))
+ return
+ }
+ continued = line[3] == '-'
+ code, err = strconv.Atoi(line[0:3])
+ if err != nil || code < 100 {
+- err = ProtocolError("invalid response code: " + line)
++ err = ProtocolError(fmt.Sprintf("invalid response code: %q", line))
+ return
+ }
+ message = line[4:]
+@@ -251,7 +251,7 @@ func parseCodeLine(line string, expectCode int) (code int, continued bool, messa
+ func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error) {
+ code, continued, message, err := r.readCodeLine(expectCode)
+ if err == nil && continued {
+- err = ProtocolError("unexpected multi-line response: " + message)
++ err = ProtocolError(fmt.Sprintf("unexpected multi-line response: %q", message))
+ }
+ return
+ }
+@@ -536,7 +536,7 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
+ if err != nil {
+ return m, err
+ }
+- return m, ProtocolError("malformed MIME header initial line: " + string(line))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header initial line: %q", line))
+ }
+
+ for {
+@@ -548,15 +548,15 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
+ // Key ends at first colon.
+ k, v, ok := bytes.Cut(kv, colon)
+ if !ok {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ key, ok := canonicalMIMEHeaderKey(k)
+ if !ok {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ for _, c := range v {
+ if !validHeaderValueByte(c) {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ }
+
+diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
+index 26ff617470..844069a4ad 100644
+--- a/src/net/textproto/reader_test.go
++++ b/src/net/textproto/reader_test.go
+@@ -409,6 +409,8 @@ func TestReadMultiLineError(t *testing.T) {
+ "Unexpected but legal text!\n" +
+ "5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp"
+
++ wantError := `550 "5.1.1 The email account that you tried to reach does not exist. Please try\n5.1.1 double-checking the recipient's email address for typos or\n5.1.1 unnecessary spaces. Learn more at\nUnexpected but legal text!\n5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp"`
++
+ code, msg, err := r.ReadResponse(250)
+ if err == nil {
+ t.Errorf("ReadResponse: no error, want error")
+@@ -419,8 +421,8 @@ func TestReadMultiLineError(t *testing.T) {
+ if msg != wantMsg {
+ t.Errorf("ReadResponse: msg=%q, want %q", msg, wantMsg)
+ }
+- if err != nil && err.Error() != "550 "+wantMsg {
+- t.Errorf("ReadResponse: error=%q, want %q", err.Error(), "550 "+wantMsg)
++ if err != nil && err.Error() != wantError {
++ t.Errorf("ReadResponse: error=%q, want %q", err.Error(), wantError)
+ }
+ }
+
+diff --git a/src/net/textproto/textproto.go b/src/net/textproto/textproto.go
+index 4ae3ecff74..a2291eff2b 100644
+--- a/src/net/textproto/textproto.go
++++ b/src/net/textproto/textproto.go
+@@ -38,7 +38,7 @@ type Error struct {
+ }
+
+ func (e *Error) Error() string {
+- return fmt.Sprintf("%03d %s", e.Code, e.Msg)
++ return fmt.Sprintf("%03d %q", e.Code, e.Msg)
+ }
+
+ // A ProtocolError describes a protocol violation such
+--
+2.43.0
+