Skip to content

Commit 518d886

Browse files
CBL-Mariner-Botazurelinux-securityKanishk-Bansal
authored
Merge PR "[AUTO-CHERRYPICK] [AutoPR- Security] Patch sriov-network-device-plugin for CVE-2026-42506, CVE-2026-39821, CVE-2026-27136, CVE-2026-42502, CVE-2026-25681, CVE-2026-25680 [CRITICAL] - branch 3.0-dev" #17568
Co-authored-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> Co-authored-by: Kanishk Bansal <103916909+Kanishk-Bansal@users.noreply.github.com>
1 parent e16b8b0 commit 518d886

7 files changed

Lines changed: 30500 additions & 1 deletion

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
From 7dce74f217c67a6b91a098109a32c72d6a50091b Mon Sep 17 00:00:00 2001
2+
From: Roland Shoemaker <roland@golang.org>
3+
Date: Tue, 12 May 2026 15:36:39 -0400
4+
Subject: [PATCH] html: improve Noah's Ark clause performance
5+
6+
Instead of iterating over each element in the stack, and checking each
7+
attribute against each other attribute in a ~cubic fashion, sort the
8+
attributes and just use slices.Equal.
9+
10+
Thanks to IPC Labs for reporting this issue.
11+
12+
Fixes CVE-2026-25680
13+
14+
Change-Id: Iec3513ba0b5da4f28f1359d24846401b9ab76ee3
15+
Reviewed-on: https://go-review.googlesource.com/c/net/+/781702
16+
TryBot-Bypass: Roland Shoemaker <roland@golang.org>
17+
Reviewed-by: Nicholas Husin <nsh@golang.org>
18+
Reviewed-by: Neal Patel <nealpatel@google.com>
19+
Reviewed-by: Nicholas Husin <husin@google.com>
20+
Auto-Submit: Gopher Robot <gobot@golang.org>
21+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
22+
Upstream-reference: https://github.com/golang/net/commit/08be507abce89191d78cd49da60f4501fc910472.patch
23+
---
24+
vendor/golang.org/x/net/html/parse.go | 34 ++++++++++++++++-----------
25+
1 file changed, 20 insertions(+), 14 deletions(-)
26+
27+
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
28+
index 3392845..4bd5e6d 100644
29+
--- a/vendor/golang.org/x/net/html/parse.go
30+
+++ b/vendor/golang.org/x/net/html/parse.go
31+
@@ -5,9 +5,11 @@
32+
package html
33+
34+
import (
35+
+ "cmp"
36+
"errors"
37+
"fmt"
38+
"io"
39+
+ "slices"
40+
"strings"
41+
42+
a "golang.org/x/net/html/atom"
43+
@@ -328,6 +330,14 @@ func (p *parser) addText(text string) {
44+
})
45+
}
46+
47+
+func attrCompare(a, b Attribute) int {
48+
+ return cmp.Or(
49+
+ cmp.Compare(a.Namespace, b.Namespace),
50+
+ cmp.Compare(a.Key, b.Key),
51+
+ cmp.Compare(a.Val, b.Val),
52+
+ )
53+
+}
54+
+
55+
// addElement adds a child element based on the current token.
56+
func (p *parser) addElement() {
57+
p.addChild(&Node{
58+
@@ -343,6 +353,10 @@ func (p *parser) addFormattingElement() {
59+
tagAtom, attr := p.tok.DataAtom, p.tok.Attr
60+
p.addElement()
61+
62+
+ // In order to optimize the search, we need the attributes to be sorted, so we
63+
+ // can just use slices.Equal.
64+
+ slices.SortFunc(attr, attrCompare)
65+
+
66+
// Implement the Noah's Ark clause, but with three per family instead of two.
67+
identicalElements := 0
68+
findIdenticalElements:
69+
@@ -360,19 +374,7 @@ findIdenticalElements:
70+
if n.DataAtom != tagAtom {
71+
continue
72+
}
73+
- if len(n.Attr) != len(attr) {
74+
- continue
75+
- }
76+
- compareAttributes:
77+
- for _, t0 := range n.Attr {
78+
- for _, t1 := range attr {
79+
- if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val {
80+
- // Found a match for this attribute, continue with the next attribute.
81+
- continue compareAttributes
82+
- }
83+
- }
84+
- // If we get here, there is no attribute that matches a.
85+
- // Therefore the element is not identical to the new one.
86+
+ if !slices.Equal(n.Attr, attr) {
87+
continue findIdenticalElements
88+
}
89+
90+
@@ -382,7 +384,11 @@ findIdenticalElements:
91+
}
92+
}
93+
94+
- p.afe = append(p.afe, p.top())
95+
+ // Sort the attributes to optimize future identical-element searches.
96+
+ top := p.top()
97+
+ slices.SortFunc(top.Attr, attrCompare)
98+
+
99+
+ p.afe = append(p.afe, top)
100+
}
101+
102+
// Section 12.2.4.3.
103+
--
104+
2.45.4
105+
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
From 69a785671f80c7210c57841da82e3744691db84b Mon Sep 17 00:00:00 2001
2+
From: Roland Shoemaker <roland@golang.org>
3+
Date: Mon, 4 May 2026 11:47:15 -0700
4+
Subject: [PATCH] html: escape greater-than symbol in doctype identifiers
5+
6+
During parsing, we unescape character references. When rendering, we
7+
re-escape certain characters in certain scenarios in order to avoid
8+
token content causing unexpected parser behavior.
9+
10+
We appear to have not taken this into account when rendering DOCTYPE
11+
tokens, allowing ">" in PUBLIC/SYSTEM identifier strings, which trigger
12+
a abrupt-doctype-system-identifier parse error which immediately emits
13+
the current DOCTYPE token and then continues parsing in the data state.
14+
15+
This may cause bypass in HTML santizers which use the html package for
16+
parsing.
17+
18+
Thanks to ensy for reporting this issue.
19+
20+
Fixes CVE-2026-25681
21+
22+
Change-Id: I1d5be92129d17bfbf0917148db2672d57c224a18
23+
Reviewed-on: https://go-review.googlesource.com/c/net/+/781703
24+
Reviewed-by: Neal Patel <nealpatel@google.com>
25+
Reviewed-by: Nicholas Husin <nsh@golang.org>
26+
TryBot-Bypass: Roland Shoemaker <roland@golang.org>
27+
Auto-Submit: Gopher Robot <gobot@golang.org>
28+
Reviewed-by: Nicholas Husin <husin@google.com>
29+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
30+
Upstream-reference: https://github.com/golang/net/commit/4ece7b612ad44ad6c4d5e0d5d4df9c18cc211905.patch
31+
---
32+
html/testdata/go/doctype_named_entity.dat | 8 ++++++++
33+
vendor/golang.org/x/net/html/render.go | 19 +++++++++++++------
34+
2 files changed, 21 insertions(+), 6 deletions(-)
35+
create mode 100644 html/testdata/go/doctype_named_entity.dat
36+
37+
diff --git a/html/testdata/go/doctype_named_entity.dat b/html/testdata/go/doctype_named_entity.dat
38+
new file mode 100644
39+
index 0000000..a8bd963
40+
--- /dev/null
41+
+++ b/html/testdata/go/doctype_named_entity.dat
42+
@@ -0,0 +1,8 @@
43+
+#data
44+
+<!DOCTYPE &gt; PUBLIC "&gt;" "&gt;">
45+
+#errors
46+
+#document
47+
+| <!DOCTYPE > ">" ">">
48+
+| <html>
49+
+| <head>
50+
+| <body>
51+
diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go
52+
index e8c1233..f3740cc 100644
53+
--- a/vendor/golang.org/x/net/html/render.go
54+
+++ b/vendor/golang.org/x/net/html/render.go
55+
@@ -113,14 +113,14 @@ func render1(w writer, n *Node) error {
56+
if _, err := w.WriteString(" PUBLIC "); err != nil {
57+
return err
58+
}
59+
- if err := writeQuoted(w, p); err != nil {
60+
+ if err := writeDoctypeQuoted(w, p); err != nil {
61+
return err
62+
}
63+
if s != "" {
64+
if err := w.WriteByte(' '); err != nil {
65+
return err
66+
}
67+
- if err := writeQuoted(w, s); err != nil {
68+
+ if err := writeDoctypeQuoted(w, s); err != nil {
69+
return err
70+
}
71+
}
72+
@@ -128,7 +128,7 @@ func render1(w writer, n *Node) error {
73+
if _, err := w.WriteString(" SYSTEM "); err != nil {
74+
return err
75+
}
76+
- if err := writeQuoted(w, s); err != nil {
77+
+ if err := writeDoctypeQuoted(w, s); err != nil {
78+
return err
79+
}
80+
}
81+
@@ -251,19 +251,26 @@ func childTextNodesAreLiteral(n *Node) bool {
82+
}
83+
}
84+
85+
-// writeQuoted writes s to w surrounded by quotes. Normally it will use double
86+
+// writeDoctypeQuoted writes s to w surrounded by quotes. Normally it will use double
87+
// quotes, but if s contains a double quote, it will use single quotes.
88+
+// If s contains any '>' characters, they are replaced with &gt; in order
89+
+// to prevent triggering an abrupt-doctype-system-identifier parse error.
90+
// It is used for writing the identifiers in a doctype declaration.
91+
// In valid HTML, they can't contain both types of quotes.
92+
-func writeQuoted(w writer, s string) error {
93+
+func writeDoctypeQuoted(w writer, s string) error {
94+
var q byte = '"'
95+
if strings.Contains(s, `"`) {
96+
+ // parseDoctype will never produce a Node with both quote types, but a user
97+
+ // can construct their own Node that violates this assumption.
98+
+ if strings.Contains(s, `'`) {
99+
+ return errors.New("doctype contains both quote types, cannot be safely rendered")
100+
+ }
101+
q = '\''
102+
}
103+
if err := w.WriteByte(q); err != nil {
104+
return err
105+
}
106+
- if _, err := w.WriteString(s); err != nil {
107+
+ if _, err := w.WriteString(strings.ReplaceAll(s, ">", "&gt;")); err != nil {
108+
return err
109+
}
110+
if err := w.WriteByte(q); err != nil {
111+
--
112+
2.45.4
113+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
From 963755e9931be254424d58cdd74a09da7ac347c4 Mon Sep 17 00:00:00 2001
2+
From: Roland Shoemaker <roland@golang.org>
3+
Date: Fri, 8 May 2026 12:09:06 -0700
4+
Subject: [PATCH] html: ignore duplicate attributes during tokenization
5+
6+
During tokenization ignore attributes with names we've already seen,
7+
per WHATWG 13.2.5.33. This removes a parser misalignment that could be
8+
leveraged to confuse sanitizers.
9+
10+
Thanks to ensy for reporting this issue.
11+
12+
Fixes CVE-2026-27136
13+
14+
Change-Id: Ib0a3edb8dbea35c431f74f8b0bbe6229625d7e1f
15+
Reviewed-on: https://go-review.googlesource.com/c/net/+/781685
16+
Reviewed-by: Neal Patel <nealpatel@google.com>
17+
Reviewed-by: Nicholas Husin <nsh@golang.org>
18+
TryBot-Bypass: Roland Shoemaker <roland@golang.org>
19+
Auto-Submit: Gopher Robot <gobot@golang.org>
20+
Reviewed-by: Nicholas Husin <husin@google.com>
21+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
22+
Upstream-reference: https://github.com/golang/net/commit/a452f3cc17168a60bc3f439a3ae0fcffc32eca0e.patch
23+
---
24+
vendor/golang.org/x/net/html/token.go | 13 +++++++++----
25+
1 file changed, 9 insertions(+), 4 deletions(-)
26+
27+
diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go
28+
index 6598c1f..058dfb2 100644
29+
--- a/vendor/golang.org/x/net/html/token.go
30+
+++ b/vendor/golang.org/x/net/html/token.go
31+
@@ -156,6 +156,7 @@ type Tokenizer struct {
32+
// incremented on each call to TagAttr.
33+
pendingAttr [2]span
34+
attr [][2]span
35+
+ attrNames map[string]bool
36+
nAttrReturned int
37+
// rawTag is the "script" in "</script>" that closes the next token. If
38+
// non-empty, the subsequent call to Next will return a raw or RCDATA text
39+
@@ -867,6 +868,7 @@ func (z *Tokenizer) readStartTag() TokenType {
40+
func (z *Tokenizer) readTag(saveAttr bool) {
41+
z.attr = z.attr[:0]
42+
z.nAttrReturned = 0
43+
+ clear(z.attrNames)
44+
// Read the tag name and attribute key/value pairs.
45+
z.readTagName()
46+
if z.skipWhiteSpace(); z.err != nil {
47+
@@ -880,9 +882,11 @@ func (z *Tokenizer) readTag(saveAttr bool) {
48+
z.raw.end--
49+
z.readTagAttrKey()
50+
z.readTagAttrVal()
51+
- // Save pendingAttr if saveAttr and that attribute has a non-empty key.
52+
- if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end {
53+
+ // Save pendingAttr if saveAttr and that attribute has a non-empty key, and the key hasn't been seen before.
54+
+ key := strings.ToLower(string(z.buf[z.pendingAttr[0].start:z.pendingAttr[0].end]))
55+
+ if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end && !z.attrNames[key] {
56+
z.attr = append(z.attr, z.pendingAttr)
57+
+ z.attrNames[key] = true
58+
}
59+
if z.skipWhiteSpace(); z.err != nil {
60+
break
61+
@@ -1273,8 +1277,9 @@ func NewTokenizer(r io.Reader) *Tokenizer {
62+
// The input is assumed to be UTF-8 encoded.
63+
func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer {
64+
z := &Tokenizer{
65+
- r: r,
66+
- buf: make([]byte, 0, 4096),
67+
+ r: r,
68+
+ buf: make([]byte, 0, 4096),
69+
+ attrNames: make(map[string]bool),
70+
}
71+
if contextTag != "" {
72+
switch s := strings.ToLower(contextTag); s {
73+
--
74+
2.45.4
75+

0 commit comments

Comments
 (0)