From: "Theo Gaige (Schneider Electric)" <[email protected]>
Backport patch from [1] [1] https://go.dev/cl/763762 Signed-off-by: Theo Gaige (Schneider Electric) <[email protected]> Reviewed-by: Bruno Vernay <[email protected]> --- meta/recipes-devtools/go/go-1.22.12.inc | 1 + .../go/go/CVE-2026-32289.patch | 217 ++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32289.patch diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc index 99c2945a8c..288cd5c95f 100644 --- a/meta/recipes-devtools/go/go-1.22.12.inc +++ b/meta/recipes-devtools/go/go-1.22.12.inc @@ -44,6 +44,7 @@ SRC_URI += "\ file://CVE-2026-27142.patch \ file://CVE-2026-32280.patch \ file://CVE-2026-32283.patch \ + file://CVE-2026-32289.patch \ " SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" diff --git a/meta/recipes-devtools/go/go/CVE-2026-32289.patch b/meta/recipes-devtools/go/go/CVE-2026-32289.patch new file mode 100644 index 0000000000..28ff0c00e0 --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2026-32289.patch @@ -0,0 +1,217 @@ +From 5291c6d3e6d0bc0a764a9a6bd6b3de1be64b8264 Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker <[email protected]> +Date: Mon, 23 Mar 2026 13:34:23 -0700 +Subject: [PATCH] html/template: properly track JS template literal brace depth + across contexts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Properly track JS template literal brace depth across branches/ranges, +and prevent accidental re-use of escape analysis by including the +brace depth in the stringification/mangling for contexts. + +Fixes #78331 +Fixes CVE-2026-32289 + +Change-Id: I9f3f47c29e042220b18e4d3299db7a3fae4207fa +Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3882 +Reviewed-by: Neal Patel <[email protected]> +Reviewed-by: Nicholas Husin <[email protected]> +Reviewed-on: https://go-review.googlesource.com/c/go/+/763762 +Reviewed-by: Russ Cox <[email protected]> +LUCI-TryBot-Result: Go LUCI <[email protected]> +Auto-Submit: David Chase <[email protected]> +Reviewed-by: Fan Mỹ Tâm Club <[email protected]> + +CVE: CVE-2026-32289 +Upstream-Status: Backport [https://github.com/golang/go/commit/199c4d1c3c9d509a51f777c81cb17d4b17728097] +Signed-off-by: Theo Gaige (Schneider Electric) <[email protected]> +--- + src/html/template/context.go | 14 +++++++++++- + src/html/template/escape.go | 4 ++-- + src/html/template/escape_test.go | 38 +++++++++++++++++++++----------- + 3 files changed, 40 insertions(+), 16 deletions(-) + +diff --git a/src/html/template/context.go b/src/html/template/context.go +index 8b3af2feab..132ae2d28d 100644 +--- a/src/html/template/context.go ++++ b/src/html/template/context.go +@@ -6,6 +6,7 @@ package template + + import ( + "fmt" ++ "slices" + "text/template/parse" + ) + +@@ -37,7 +38,7 @@ func (c context) String() string { + if c.err != nil { + err = c.err + } +- return fmt.Sprintf("{%v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.attr, c.element, err) ++ return fmt.Sprintf("{%v %v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.jsBraceDepth, c.attr, c.element, err) + } + + // eq reports whether two contexts are equal. +@@ -46,6 +47,7 @@ func (c context) eq(d context) bool { + c.delim == d.delim && + c.urlPart == d.urlPart && + c.jsCtx == d.jsCtx && ++ slices.Equal(c.jsBraceDepth, d.jsBraceDepth) && + c.attr == d.attr && + c.element == d.element && + c.err == d.err +@@ -68,6 +70,9 @@ func (c context) mangle(templateName string) string { + if c.jsCtx != jsCtxRegexp { + s += "_" + c.jsCtx.String() + } ++ if c.jsBraceDepth != nil { ++ s += fmt.Sprintf("_jsBraceDepth(%v)", c.jsBraceDepth) ++ } + if c.attr != attrNone { + s += "_" + c.attr.String() + } +@@ -77,6 +82,13 @@ func (c context) mangle(templateName string) string { + return s + } + ++// clone returns a copy of c with the same field values. ++func (c context) clone() context { ++ clone := c ++ clone.jsBraceDepth = slices.Clone(c.jsBraceDepth) ++ return clone ++} ++ + // state describes a high-level HTML parser state. + // + // It bounds the top of the element stack, and by extension the HTML insertion +diff --git a/src/html/template/escape.go b/src/html/template/escape.go +index b368cab38c..c031ed27b9 100644 +--- a/src/html/template/escape.go ++++ b/src/html/template/escape.go +@@ -522,7 +522,7 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) + if nodeName == "range" { + e.rangeContext = &rangeContext{outer: e.rangeContext} + } +- c0 := e.escapeList(c, n.List) ++ c0 := e.escapeList(c.clone(), n.List) + if nodeName == "range" { + if c0.state != stateError { + c0 = joinRange(c0, e.rangeContext) +@@ -553,7 +553,7 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) + return c0 + } + } +- c1 := e.escapeList(c, n.ElseList) ++ c1 := e.escapeList(c.clone(), n.ElseList) + return join(c0, c1, n, nodeName) + } + +diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go +index 1970db1695..435c83378f 100644 +--- a/src/html/template/escape_test.go ++++ b/src/html/template/escape_test.go +@@ -1181,6 +1181,18 @@ func TestErrors(t *testing.T) { + // html is allowed since it is the last command in the pipeline, but urlquery is not. + `predefined escaper "urlquery" disallowed in template`, + }, ++ { ++ "<script>var a = `{{if .X}}`{{end}}", ++ `{{if}} branches end in different contexts`, ++ }, ++ { ++ "<script>var a = `{{if .X}}a{{else}}`{{end}}", ++ `{{if}} branches end in different contexts`, ++ }, ++ { ++ "<script>var a = `{{if .X}}a{{else}}b{{end}}`</script>", ++ ``, ++ }, + } + for _, test := range tests { + buf := new(bytes.Buffer) +@@ -1752,7 +1764,7 @@ func TestEscapeText(t *testing.T) { + }, + { + "<script>var a = `${", +- context{state: stateJS, element: elementScript}, ++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${}", +@@ -1760,27 +1772,27 @@ func TestEscapeText(t *testing.T) { + }, + { + "<script>var a = `${`", +- context{state: stateJSTmplLit, element: elementScript}, ++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${var a = \"", +- context{state: stateJSDqStr, element: elementScript}, ++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${var a = \"`", +- context{state: stateJSDqStr, element: elementScript}, ++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${var a = \"}", +- context{state: stateJSDqStr, element: elementScript}, ++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${``", +- context{state: stateJS, element: elementScript}, ++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${`}", +- context{state: stateJSTmplLit, element: elementScript}, ++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>`${ {} } asd`</script><script>`${ {} }", +@@ -1788,7 +1800,7 @@ func TestEscapeText(t *testing.T) { + }, + { + "<script>var foo = `${ (_ => { return \"x\" })() + \"${", +- context{state: stateJSDqStr, element: elementScript}, ++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var a = `${ {</script><script>var b = `${ x }", +@@ -1816,23 +1828,23 @@ func TestEscapeText(t *testing.T) { + }, + { + "<script>`${ { `` }", +- context{state: stateJS, element: elementScript}, ++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>`${ { }`", +- context{state: stateJSTmplLit, element: elementScript}, ++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, + }, + { + "<script>var foo = `${ foo({ a: { c: `${", +- context{state: stateJS, element: elementScript}, ++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{2, 0}}, + }, + { + "<script>var foo = `${ foo({ a: { c: `${ {{.}} }` }, b: ", +- context{state: stateJS, element: elementScript}, ++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{1}}, + }, + { + "<script>`${ `}", +- context{state: stateJSTmplLit, element: elementScript}, ++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}}, + }, + } + +-- +2.43.0 + -- 2.43.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#237488): https://lists.openembedded.org/g/openembedded-core/message/237488 Mute This Topic: https://lists.openembedded.org/mt/119422292/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
