Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions SPECS/caddy/CVE-2025-47911.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
commit 59706cdaa8f95502fdec64b67b4c61d6ca58727d
Author: Roland Shoemaker <roland@golang.org>
Date: Mon Sep 29 16:33:18 2025 -0700

html: impose open element stack size limit

The HTML specification contains a number of algorithms which are
quadratic in complexity by design. Instead of adding complicated
workarounds to prevent these cases from becoming extremely expensive in
pathological cases, we impose a limit of 512 to the size of the stack of
open elements. It is extremely unlikely that non-adversarial HTML
documents will ever hit this limit (but if we see cases of this, we may
want to make the limit configurable via a ParseOption).

Thanks to Guido Vranken and Jakub Ciolek for both independently
reporting this issue.

Fixes CVE-2025-47911
Fixes golang/go#75682

Change-Id: I890517b189af4ffbf427d25d3fde7ad7ec3509ad
Reviewed-on: https://go-review.googlesource.com/c/net/+/709876
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go
index 04c6bec..12f2273 100644
--- a/vendor/golang.org/x/net/html/escape.go
+++ b/vendor/golang.org/x/net/html/escape.go
@@ -299,7 +299,7 @@ func escape(w writer, s string) error {
case '\r':
esc = "&#13;"
default:
- panic("unrecognized escape character")
+ panic("html: unrecognized escape character")
}
s = s[i+1:]
if _, err := w.WriteString(esc); err != nil {
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
index 722e927..88fc005 100644
--- a/vendor/golang.org/x/net/html/parse.go
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -231,7 +231,14 @@ func (p *parser) addChild(n *Node) {
}

if n.Type == ElementNode {
- p.oe = append(p.oe, n)
+ p.insertOpenElement(n)
+ }
+}
+
+func (p *parser) insertOpenElement(n *Node) {
+ p.oe = append(p.oe, n)
+ if len(p.oe) > 512 {
+ panic("html: open stack of elements exceeds 512 nodes")
}
}

@@ -810,7 +817,7 @@ func afterHeadIM(p *parser) bool {
p.im = inFramesetIM
return true
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
- p.oe = append(p.oe, p.head)
+ p.insertOpenElement(p.head)
defer p.oe.remove(p.head)
return inHeadIM(p)
case a.Head:
@@ -2324,9 +2331,13 @@ func (p *parser) parseCurrentToken() {
}
}

-func (p *parser) parse() error {
+func (p *parser) parse() (err error) {
+ defer func() {
+ if panicErr := recover(); panicErr != nil {
+ err = fmt.Errorf("%s", panicErr)
+ }
+ }()
// Iterate until EOF. Any other error will cause an early return.
- var err error
for err != io.EOF {
// CDATA sections are allowed only in foreign content.
n := p.oe.top()
@@ -2355,6 +2366,8 @@ func (p *parser) parse() error {
// <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,
// with no corresponding node in the resulting tree.
//
+// Parse will reject HTML that is nested deeper than 512 elements.
+//
// The input is assumed to be UTF-8 encoded.
func Parse(r io.Reader) (*Node, error) {
return ParseWithOptions(r)
119 changes: 119 additions & 0 deletions SPECS/caddy/CVE-2025-58190.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
commit 6ec8895aa5f6594da7356da7d341b98133629009
Author: Roland Shoemaker <roland@golang.org>
Date: Mon Sep 29 19:38:24 2025 -0700

html: align in row insertion mode with spec

Update inRowIM to match the HTML specification. This fixes an issue
where a specific HTML document could cause the parser to enter an
infinite loop when trying to parse a </tbody> and implied </tr> next to
each other.

Fixes CVE-2025-58190
Fixes golang/go#70179

Change-Id: Idcb133c87c7d475cc8c7eb1f1550ea21d8bdddea
Reviewed-on: https://go-review.googlesource.com/c/net/+/709875
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>

diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
index 518ee4c..722e927 100644
--- a/vendor/golang.org/x/net/html/parse.go
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
return -1
}
default:
- panic("unreachable")
+ panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s))
}
}
switch s {
@@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) {
return
}
default:
- panic("unreachable")
+ panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s))
}
}
}
@@ -1678,7 +1678,7 @@ func inTableBodyIM(p *parser) bool {
return inTableIM(p)
}

-// Section 12.2.6.4.14.
+// Section 13.2.6.4.14.
func inRowIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@@ -1690,7 +1690,9 @@ func inRowIM(p *parser) bool {
p.im = inCellIM
return true
case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:
- if p.popUntil(tableScope, a.Tr) {
+ if p.elementInScope(tableScope, a.Tr) {
+ p.clearStackToContext(tableRowScope)
+ p.oe.pop()
p.im = inTableBodyIM
return false
}
@@ -1700,22 +1702,28 @@ func inRowIM(p *parser) bool {
case EndTagToken:
switch p.tok.DataAtom {
case a.Tr:
- if p.popUntil(tableScope, a.Tr) {
+ if p.elementInScope(tableScope, a.Tr) {
+ p.clearStackToContext(tableRowScope)
+ p.oe.pop()
p.im = inTableBodyIM
return true
}
// Ignore the token.
return true
case a.Table:
- if p.popUntil(tableScope, a.Tr) {
+ if p.elementInScope(tableScope, a.Tr) {
+ p.clearStackToContext(tableRowScope)
+ p.oe.pop()
p.im = inTableBodyIM
return false
}
// Ignore the token.
return true
case a.Tbody, a.Tfoot, a.Thead:
- if p.elementInScope(tableScope, p.tok.DataAtom) {
- p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())
+ if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) {
+ p.clearStackToContext(tableRowScope)
+ p.oe.pop()
+ p.im = inTableBodyIM
return false
}
// Ignore the token.
@@ -2222,16 +2230,20 @@ func parseForeignContent(p *parser) bool {
p.acknowledgeSelfClosingTag()
}
case EndTagToken:
+ if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) {
+ p.oe = p.oe[:len(p.oe)-1]
+ return true
+ }
for i := len(p.oe) - 1; i >= 0; i-- {
- if p.oe[i].Namespace == "" {
- return p.im(p)
- }
if strings.EqualFold(p.oe[i].Data, p.tok.Data) {
p.oe = p.oe[:i]
+ return true
+ }
+ if i > 0 && p.oe[i-1].Namespace == "" {
break
}
}
- return true
+ return p.im(p)
default:
// Ignore the token.
}
7 changes: 6 additions & 1 deletion SPECS/caddy/caddy.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Summary: Web server with automatic HTTPS
Name: caddy
Version: 2.9.1
Release: 19%{?dist}
Release: 20%{?dist}
Distribution: Edge Microvisor Toolkit
Vendor: Intel Corporation
# main source code is Apache-2.0
Expand Down Expand Up @@ -35,6 +35,8 @@ Patch6: CVE-2025-61727.patch
Patch7: CVE-2025-61729.patch
Patch8: CVE-2025-47913.patch
Patch9: CVE-2025-47914.patch
Patch10: CVE-2025-58190.patch
Patch11: CVE-2025-47911.patch
# https://github.com/caddyserver/caddy/commit/2028da4e74cd41f0f7f94222c6599da1a371d4b8
BuildRequires: golang >= 1.25.5
# dario.cat/mergo : BSD-3-Clause
Expand Down Expand Up @@ -457,6 +459,9 @@ fi
%{_datadir}/fish/vendor_completions.d/caddy.fish

%changelog
* Fri Feb 13 2026 Rajesh Shanmugam <rajesh1x.shanmugam@intel.com> - 2.9.1-20
- Add patch for CVE-2025-47911 and CVE-2025-58190

* Fri Feb 13 2026 Andy <andy.peng@intel.com> - 2.9.1-19
- Update BuildRequires for golang

Expand Down
Loading