From e2d512c2e7e93ae68b90ecdbb9b3c994b5a67d6f Mon Sep 17 00:00:00 2001 From: "Theo Gaige (Schneider Electric)" Date: Fri, 19 Jun 2026 09:51:18 +0200 Subject: [PATCH] go: patch CVE-2026-27145 Backport patch from [1] [1] https://go.dev/cl/783621 (From OE-Core rev: 209a1b3a48b8e3996e1b53f2d7efe335855b7375) Signed-off-by: Theo Gaige (Schneider Electric) Signed-off-by: Yoann Congal Signed-off-by: Paul Barker --- meta/recipes-devtools/go/go-1.22.12.inc | 1 + .../go/go/CVE-2026-27145.patch | 96 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 meta/recipes-devtools/go/go/CVE-2026-27145.patch diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc index c825ebd25a..99c5f8b63b 100644 --- a/meta/recipes-devtools/go/go-1.22.12.inc +++ b/meta/recipes-devtools/go/go-1.22.12.inc @@ -61,6 +61,7 @@ SRC_URI += "\ file://CVE-2025-58183.patch \ file://CVE-2026-25679.patch \ file://CVE-2026-32288.patch \ + file://CVE-2026-27145.patch \ " SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" diff --git a/meta/recipes-devtools/go/go/CVE-2026-27145.patch b/meta/recipes-devtools/go/go/CVE-2026-27145.patch new file mode 100644 index 0000000000..f231aab458 --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2026-27145.patch @@ -0,0 +1,96 @@ +From 612753600a0184c8b792425dea62e530170ca811 Mon Sep 17 00:00:00 2001 +From: Ian Alexander +Date: Wed, 27 May 2026 04:22:31 -0400 +Subject: [PATCH] crypto/x509: split candidate hostname only once + +(*x509.Certificate).VerifyHostname previously called matchHostnames in a +loop over all DNS Subject Alternative Name (SAN) entries. This caused +strings.Split(host, ".") to execute repeatedly on the same input +hostname. + +With a large DNS SAN list, verification costs scaled quadratically based +on the number of SAN entries multiplied by the hostname's label count. +Because x509.Verify validates hostnames before building the certificate +chain, this overhead occurred even for untrusted certificates. + +Thanks to Jakub Ciolek for reporting this issue. + +Fixes #79694 +Fixes CVE-2026-27145 + +Change-Id: I2788b8ee22ffd28e45bcc7b0d860549084906a74 +Reviewed-on: https://go-review.googlesource.com/c/go/+/783621 +LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com +Reviewed-by: David Chase +Reviewed-by: Neal Patel + +CVE: CVE-2026-27145 +Upstream-Status: Backport [https://github.com/golang/go/commit/d01955d5d50ccb5f46c215f88c1781742b3f117d] +Signed-off-by: Theo Gaige (Schneider Electric) +--- + src/crypto/x509/verify.go | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go +index 1de06bc95b..4c423a5fca 100644 +--- a/src/crypto/x509/verify.go ++++ b/src/crypto/x509/verify.go +@@ -102,7 +102,7 @@ func (h HostnameError) Error() string { + c := h.Certificate + maxNamesIncluded := 100 + +- if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) { ++ if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, splitHostname(h.Host)) { + return "x509: certificate relies on legacy Common Name field, use SANs instead" + } + +@@ -1081,16 +1081,14 @@ func matchExactly(hostA, hostB string) bool { + return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB) + } + +-func matchHostnames(pattern, host string) bool { ++func matchHostnames(pattern string, hostParts []string) bool { + pattern = toLowerCaseASCII(pattern) +- host = toLowerCaseASCII(strings.TrimSuffix(host, ".")) + +- if len(pattern) == 0 || len(host) == 0 { ++ if len(pattern) == 0 || len(hostParts) == 0 { + return false + } + + patternParts := strings.Split(pattern, ".") +- hostParts := strings.Split(host, ".") + + if len(patternParts) != len(hostParts) { + return false +@@ -1168,6 +1166,7 @@ func (c *Certificate) VerifyHostname(h string) error { + + candidateName := toLowerCaseASCII(h) // Save allocations inside the loop. + validCandidateName := validHostnameInput(candidateName) ++ hostParts := splitHostname(candidateName) + + for _, match := range c.DNSNames { + // Ideally, we'd only match valid hostnames according to RFC 6125 like +@@ -1176,7 +1175,7 @@ func (c *Certificate) VerifyHostname(h string) error { + // always allow perfect matches, and only apply wildcard and trailing + // dot processing to valid hostnames. + if validCandidateName && validHostnamePattern(match) { +- if matchHostnames(match, candidateName) { ++ if matchHostnames(match, hostParts) { + return nil + } + } else { +@@ -1189,6 +1188,10 @@ func (c *Certificate) VerifyHostname(h string) error { + return HostnameError{c, h} + } + ++func splitHostname(host string) []string { ++ return strings.Split(toLowerCaseASCII(strings.TrimSuffix(host, ".")), ".") ++} ++ + func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool { + usages := make([]ExtKeyUsage, len(keyUsages)) + copy(usages, keyUsages) +-- +2.43.0 +