diff mbox series

[scarthgap] go: fix CVE-2026-56862

Message ID 20261016124507.350030-1-benhur.tessele@est.tech
State New
Headers show
Series [scarthgap] go: fix CVE-2026-56862 | expand

Commit Message

Benhur Tessele Oct. 16, 2026, 12:45 p.m. UTC
A malicious TLS 1.3 peer could keep sending KeyUpdate messages after
the handshake completed, forcing the other side to perform key
derivation indefinitely, because handshake records were always treated
as state-advancing.

Backport the upstream fix [1]. The bogo_config.json hunk is dropped
since the BoGo test harness does not exist in Go 1.22, and the new test
is adapted to use testConfig.

[1] https://github.com/golang/go/commit/27420571845abc6a97e19e21542a3213a74f67f4

Signed-off-by: Benhur Tessele <benhur.tessele@est.tech>
---
 meta/recipes-devtools/go/go-1.22.12.inc       |  1 +
 .../go/go/CVE-2026-56862.patch                | 98 +++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 meta/recipes-devtools/go/go/CVE-2026-56862.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index c8fb9ef450..cec3bbbb4e 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -63,6 +63,7 @@  SRC_URI += "\
     file://CVE-2026-32288.patch \
     file://CVE-2026-27145.patch \
     file://CVE-2026-39823.patch \
+    file://CVE-2026-56862.patch \
 "
 SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
 
diff --git a/meta/recipes-devtools/go/go/CVE-2026-56862.patch b/meta/recipes-devtools/go/go/CVE-2026-56862.patch
new file mode 100644
index 0000000000..5fca5be4ce
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-56862.patch
@@ -0,0 +1,98 @@ 
+From 616c582eae27699513109445d5c177b42c3bb9fc Mon Sep 17 00:00:00 2001
+From: "Nicholas S. Husin" <nsh@golang.org>
+Date: Wed, 22 Jul 2026 12:27:12 -0400
+Subject: [PATCH] crypto/tls: do not count handshake messages as
+ state-advancing post-handshake
+
+Previously, we always counted handshake messages, such as KeyUpdate, as
+state-advancing, regardless of whether a handshake has been completed or
+not. As a result, a malicious client can keep sending KeyUpdate messages
+to force the server to keep performing key derivation operations
+indefinitely.
+
+Fix the issue by making it so that handshake messages are regarded
+as state-advancing only prior to handshake completion.
+
+Thank you to Qi Deng of Aurascape.ai for reporting this issue.
+
+Fixes #79866
+Fixes #80528
+Fixes CVE-2026-56862
+
+Change-Id: I37d27fd5f16227a9dde5f29bb5ae6c436a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/804261
+Reviewed-by: Roland Shoemaker <roland@golang.org>
+Reviewed-by: Neal Patel <nealpatel@google.com>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Neal Patel <neal@golang.org>
+
+CVE: CVE-2026-56862
+Upstream-Status: Backport [https://github.com/golang/go/commit/27420571845abc6a97e19e21542a3213a74f67f4]
+
+Backport notes for go1.22.12:
+- Dropped the src/crypto/tls/bogo_config.json hunk; the BoGo test
+  harness and its config do not exist in Go 1.22.
+- Test uses testConfig instead of testConfigClient/testConfigServer,
+  which were introduced after Go 1.22.
+
+Signed-off-by: Benhur Tessele <benhur.tessele@est.tech>
+---
+ src/crypto/tls/conn.go      |  2 +-
+ src/crypto/tls/conn_test.go | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
+index 770d456f18..376b2dcd1e 100644
+--- a/src/crypto/tls/conn.go
++++ b/src/crypto/tls/conn.go
+@@ -699,7 +699,7 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
+ 		return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ 	}
+ 
+-	if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
++	if (typ == recordTypeApplicationData || (typ == recordTypeHandshake && !handshakeComplete)) && len(data) > 0 {
+ 		// This is a state-advancing message: reset the retry count.
+ 		c.retryCount = 0
+ 	}
+diff --git a/src/crypto/tls/conn_test.go b/src/crypto/tls/conn_test.go
+index 5e090a017d..303012ccc5 100644
+--- a/src/crypto/tls/conn_test.go
++++ b/src/crypto/tls/conn_test.go
+@@ -317,3 +317,37 @@ func TestRecordBadVersionTLS13(t *testing.T) {
+ 		t.Fatalf("unexpected error: got %q, want %q", err, expectedErr)
+ 	}
+ }
++
++// TestKeyUpdateSpamPostHandshakeTLS13 tests that TLS 1.3 KeyUpdate messages do
++// not count as a state-advancing message after a handshake has been completed.
++func TestKeyUpdateSpamPostHandshakeTLS13(t *testing.T) {
++	client, server := localPipe(t)
++	defer server.Close()
++	defer client.Close()
++
++	go func() {
++		c := Client(client, testConfig.Clone())
++		if err := c.Handshake(); err != nil {
++			t.Error(err)
++			return
++		}
++		ku, err := (&keyUpdateMsg{}).marshal()
++		if err != nil {
++			t.Error(err)
++			return
++		}
++		cs := cipherSuiteTLS13ByID(c.cipherSuite)
++		for i := 0; i <= maxUselessRecords; i++ {
++			c.writeRecordLocked(recordTypeHandshake, ku)
++			c.setWriteTrafficSecret(cs, QUICEncryptionLevelInitial, cs.nextTrafficSecret(c.out.trafficSecret))
++		}
++	}()
++	s := Server(server, testConfig.Clone())
++	if err := s.Handshake(); err != nil {
++		t.Fatal(err)
++	}
++	expectedErr := "tls: too many non-advancing records"
++	if _, err := s.Read(make([]byte, 1)); err == nil || err.Error() != expectedErr {
++		t.Fatalf("unexpected error: got %v, want %q", err, expectedErr)
++	}
++}