diff --git a/SPECS/cni-plugins/CVE-2026-25680.patch b/SPECS/cni-plugins/CVE-2026-25680.patch new file mode 100644 index 00000000000..f98af62047c --- /dev/null +++ b/SPECS/cni-plugins/CVE-2026-25680.patch @@ -0,0 +1,105 @@ +From f7cfb4ece85dacabf18d73f90d098f312c8f7082 Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Tue, 12 May 2026 15:36:39 -0400 +Subject: [PATCH] html: improve Noah's Ark clause performance + +Instead of iterating over each element in the stack, and checking each +attribute against each other attribute in a ~cubic fashion, sort the +attributes and just use slices.Equal. + +Thanks to IPC Labs for reporting this issue. + +Fixes CVE-2026-25680 + +Change-Id: Iec3513ba0b5da4f28f1359d24846401b9ab76ee3 +Reviewed-on: https://go-review.googlesource.com/c/net/+/781702 +TryBot-Bypass: Roland Shoemaker +Reviewed-by: Nicholas Husin +Reviewed-by: Neal Patel +Reviewed-by: Nicholas Husin +Auto-Submit: Gopher Robot +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/net/commit/08be507abce89191d78cd49da60f4501fc910472.patch +--- + vendor/golang.org/x/net/html/parse.go | 34 ++++++++++++++++----------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go +index 3392845..4bd5e6d 100644 +--- a/vendor/golang.org/x/net/html/parse.go ++++ b/vendor/golang.org/x/net/html/parse.go +@@ -5,9 +5,11 @@ + package html + + import ( ++ "cmp" + "errors" + "fmt" + "io" ++ "slices" + "strings" + + a "golang.org/x/net/html/atom" +@@ -328,6 +330,14 @@ func (p *parser) addText(text string) { + }) + } + ++func attrCompare(a, b Attribute) int { ++ return cmp.Or( ++ cmp.Compare(a.Namespace, b.Namespace), ++ cmp.Compare(a.Key, b.Key), ++ cmp.Compare(a.Val, b.Val), ++ ) ++} ++ + // addElement adds a child element based on the current token. + func (p *parser) addElement() { + p.addChild(&Node{ +@@ -343,6 +353,10 @@ func (p *parser) addFormattingElement() { + tagAtom, attr := p.tok.DataAtom, p.tok.Attr + p.addElement() + ++ // In order to optimize the search, we need the attributes to be sorted, so we ++ // can just use slices.Equal. ++ slices.SortFunc(attr, attrCompare) ++ + // Implement the Noah's Ark clause, but with three per family instead of two. + identicalElements := 0 + findIdenticalElements: +@@ -360,19 +374,7 @@ findIdenticalElements: + if n.DataAtom != tagAtom { + continue + } +- if len(n.Attr) != len(attr) { +- continue +- } +- compareAttributes: +- for _, t0 := range n.Attr { +- for _, t1 := range attr { +- if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { +- // Found a match for this attribute, continue with the next attribute. +- continue compareAttributes +- } +- } +- // If we get here, there is no attribute that matches a. +- // Therefore the element is not identical to the new one. ++ if !slices.Equal(n.Attr, attr) { + continue findIdenticalElements + } + +@@ -382,7 +384,11 @@ findIdenticalElements: + } + } + +- p.afe = append(p.afe, p.top()) ++ // Sort the attributes to optimize future identical-element searches. ++ top := p.top() ++ slices.SortFunc(top.Attr, attrCompare) ++ ++ p.afe = append(p.afe, top) + } + + // Section 12.2.4.3. +-- +2.45.4 + diff --git a/SPECS/cni-plugins/CVE-2026-25681.patch b/SPECS/cni-plugins/CVE-2026-25681.patch new file mode 100644 index 00000000000..e9e7f96d79a --- /dev/null +++ b/SPECS/cni-plugins/CVE-2026-25681.patch @@ -0,0 +1,113 @@ +From 1fe63c675e236b38f901c4ece5db7bf725272afb Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Mon, 4 May 2026 11:47:15 -0700 +Subject: [PATCH] html: escape greater-than symbol in doctype identifiers + +During parsing, we unescape character references. When rendering, we +re-escape certain characters in certain scenarios in order to avoid +token content causing unexpected parser behavior. + +We appear to have not taken this into account when rendering DOCTYPE +tokens, allowing ">" in PUBLIC/SYSTEM identifier strings, which trigger +a abrupt-doctype-system-identifier parse error which immediately emits +the current DOCTYPE token and then continues parsing in the data state. + +This may cause bypass in HTML santizers which use the html package for +parsing. + +Thanks to ensy for reporting this issue. + +Fixes CVE-2026-25681 + +Change-Id: I1d5be92129d17bfbf0917148db2672d57c224a18 +Reviewed-on: https://go-review.googlesource.com/c/net/+/781703 +Reviewed-by: Neal Patel +Reviewed-by: Nicholas Husin +TryBot-Bypass: Roland Shoemaker +Auto-Submit: Gopher Robot +Reviewed-by: Nicholas Husin +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/net/commit/4ece7b612ad44ad6c4d5e0d5d4df9c18cc211905.patch +--- + html/testdata/go/doctype_named_entity.dat | 8 ++++++++ + vendor/golang.org/x/net/html/render.go | 19 +++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + create mode 100644 html/testdata/go/doctype_named_entity.dat + +diff --git a/html/testdata/go/doctype_named_entity.dat b/html/testdata/go/doctype_named_entity.dat +new file mode 100644 +index 0000000..a8bd963 +--- /dev/null ++++ b/html/testdata/go/doctype_named_entity.dat +@@ -0,0 +1,8 @@ ++#data ++ ++#errors ++#document ++| ">" ">"> ++| ++| ++| +diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go +index e8c1233..f3740cc 100644 +--- a/vendor/golang.org/x/net/html/render.go ++++ b/vendor/golang.org/x/net/html/render.go +@@ -113,14 +113,14 @@ func render1(w writer, n *Node) error { + if _, err := w.WriteString(" PUBLIC "); err != nil { + return err + } +- if err := writeQuoted(w, p); err != nil { ++ if err := writeDoctypeQuoted(w, p); err != nil { + return err + } + if s != "" { + if err := w.WriteByte(' '); err != nil { + return err + } +- if err := writeQuoted(w, s); err != nil { ++ if err := writeDoctypeQuoted(w, s); err != nil { + return err + } + } +@@ -128,7 +128,7 @@ func render1(w writer, n *Node) error { + if _, err := w.WriteString(" SYSTEM "); err != nil { + return err + } +- if err := writeQuoted(w, s); err != nil { ++ if err := writeDoctypeQuoted(w, s); err != nil { + return err + } + } +@@ -251,19 +251,26 @@ func childTextNodesAreLiteral(n *Node) bool { + } + } + +-// writeQuoted writes s to w surrounded by quotes. Normally it will use double ++// writeDoctypeQuoted writes s to w surrounded by quotes. Normally it will use double + // quotes, but if s contains a double quote, it will use single quotes. ++// If s contains any '>' characters, they are replaced with > in order ++// to prevent triggering an abrupt-doctype-system-identifier parse error. + // It is used for writing the identifiers in a doctype declaration. + // In valid HTML, they can't contain both types of quotes. +-func writeQuoted(w writer, s string) error { ++func writeDoctypeQuoted(w writer, s string) error { + var q byte = '"' + if strings.Contains(s, `"`) { ++ // parseDoctype will never produce a Node with both quote types, but a user ++ // can construct their own Node that violates this assumption. ++ if strings.Contains(s, `'`) { ++ return errors.New("doctype contains both quote types, cannot be safely rendered") ++ } + q = '\'' + } + if err := w.WriteByte(q); err != nil { + return err + } +- if _, err := w.WriteString(s); err != nil { ++ if _, err := w.WriteString(strings.ReplaceAll(s, ">", ">")); err != nil { + return err + } + if err := w.WriteByte(q); err != nil { +-- +2.45.4 + diff --git a/SPECS/cni-plugins/CVE-2026-27136.patch b/SPECS/cni-plugins/CVE-2026-27136.patch new file mode 100644 index 00000000000..cf5ce250f05 --- /dev/null +++ b/SPECS/cni-plugins/CVE-2026-27136.patch @@ -0,0 +1,75 @@ +From 7c97195cfc6d79f6b9d52fc70eb2543965dfa2bd Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 8 May 2026 12:09:06 -0700 +Subject: [PATCH] html: ignore duplicate attributes during tokenization + +During tokenization ignore attributes with names we've already seen, +per WHATWG 13.2.5.33. This removes a parser misalignment that could be +leveraged to confuse sanitizers. + +Thanks to ensy for reporting this issue. + +Fixes CVE-2026-27136 + +Change-Id: Ib0a3edb8dbea35c431f74f8b0bbe6229625d7e1f +Reviewed-on: https://go-review.googlesource.com/c/net/+/781685 +Reviewed-by: Neal Patel +Reviewed-by: Nicholas Husin +TryBot-Bypass: Roland Shoemaker +Auto-Submit: Gopher Robot +Reviewed-by: Nicholas Husin +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/net/commit/a452f3cc17168a60bc3f439a3ae0fcffc32eca0e.patch +--- + vendor/golang.org/x/net/html/token.go | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go +index 9bbdf7d..8f475e3 100644 +--- a/vendor/golang.org/x/net/html/token.go ++++ b/vendor/golang.org/x/net/html/token.go +@@ -156,6 +156,7 @@ type Tokenizer struct { + // incremented on each call to TagAttr. + pendingAttr [2]span + attr [][2]span ++ attrNames map[string]bool + nAttrReturned int + // rawTag is the "script" in "" that closes the next token. If + // non-empty, the subsequent call to Next will return a raw or RCDATA text +@@ -867,6 +868,7 @@ func (z *Tokenizer) readStartTag() TokenType { + func (z *Tokenizer) readTag(saveAttr bool) { + z.attr = z.attr[:0] + z.nAttrReturned = 0 ++ clear(z.attrNames) + // Read the tag name and attribute key/value pairs. + z.readTagName() + if z.skipWhiteSpace(); z.err != nil { +@@ -880,9 +882,11 @@ func (z *Tokenizer) readTag(saveAttr bool) { + z.raw.end-- + z.readTagAttrKey() + z.readTagAttrVal() +- // Save pendingAttr if saveAttr and that attribute has a non-empty key. +- if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end { ++ // Save pendingAttr if saveAttr and that attribute has a non-empty key, and the key hasn't been seen before. ++ key := strings.ToLower(string(z.buf[z.pendingAttr[0].start:z.pendingAttr[0].end])) ++ if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end && !z.attrNames[key] { + z.attr = append(z.attr, z.pendingAttr) ++ z.attrNames[key] = true + } + if z.skipWhiteSpace(); z.err != nil { + break +@@ -1269,8 +1273,9 @@ func NewTokenizer(r io.Reader) *Tokenizer { + // The input is assumed to be UTF-8 encoded. + func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer { + z := &Tokenizer{ +- r: r, +- buf: make([]byte, 0, 4096), ++ r: r, ++ buf: make([]byte, 0, 4096), ++ attrNames: make(map[string]bool), + } + if contextTag != "" { + switch s := strings.ToLower(contextTag); s { +-- +2.45.4 + diff --git a/SPECS/cni-plugins/CVE-2026-42502.patch b/SPECS/cni-plugins/CVE-2026-42502.patch new file mode 100644 index 00000000000..7a624bc5f84 --- /dev/null +++ b/SPECS/cni-plugins/CVE-2026-42502.patch @@ -0,0 +1,64 @@ +From b19152b050d2971ea9a1ee1eea95f944d4de65df Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Mon, 4 May 2026 14:01:10 -0700 +Subject: [PATCH] html: properly render fostered elements in foreign content + +When we foster elements under another parent, there are complicated +rules about which namespace may apply. This in particular affects +childTextNodesAreLiteral, which checks if we should be emitting raw +text, or escaped text. + +In childTextNodesAreLiteral, check if there is an ancestor which has a +different namespace. If one is found, check if it's an HTML integration +point. If not, treat the node as if it were in its parents namespace, if +so, treat it as HTML. + +Thanks to Tristan Madani for reporting this issue. + +Fixes CVE-2026-42502 + +Change-Id: I0ae1780dae335e5f719d7f176cefa83670cfea3d +Reviewed-on: https://go-review.googlesource.com/c/net/+/781701 +Reviewed-by: Neal Patel +Reviewed-by: Nicholas Husin +TryBot-Bypass: Roland Shoemaker +Reviewed-by: Nicholas Husin +Auto-Submit: Gopher Robot +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/net/commit/a8fb2fe4f7378f816302b9f2f7b8290ce512e5dd.patch +--- + vendor/golang.org/x/net/html/render.go | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go +index f3740cc..f2aa2ad 100644 +--- a/vendor/golang.org/x/net/html/render.go ++++ b/vendor/golang.org/x/net/html/render.go +@@ -243,8 +243,24 @@ func childTextNodesAreLiteral(n *Node) bool { + if n.Namespace != "" { + return false + } ++ + switch n.Data { + case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": ++ // We need to check if n is a node that was fostered from a HTML namespace ++ // into a non-HTML namespace (in which case, different rules apply to it). ++ // We do this by walking up the tree until we find a node with a non-empty ++ // namespace. If we find such a node, we also have to check if it's ++ // an HTML integration point. If it isn't, then the node we're currently ++ // looking at is foster-parented and we should return false. ++ for p := n.Parent; p != nil; p = p.Parent { ++ if p.Namespace != "" { ++ if !htmlIntegrationPoint(p) { ++ return false ++ } ++ break ++ } ++ } ++ + return true + default: + return false +-- +2.45.4 + diff --git a/SPECS/cni-plugins/CVE-2026-42506.patch b/SPECS/cni-plugins/CVE-2026-42506.patch new file mode 100644 index 00000000000..219f1b0d0ed --- /dev/null +++ b/SPECS/cni-plugins/CVE-2026-42506.patch @@ -0,0 +1,76 @@ +From 2d74e15927d5afe82bd4cc3056e49fe5c6f6bbcb Mon Sep 17 00:00:00 2001 +From: Roland Shoemaker +Date: Fri, 8 May 2026 11:58:29 -0700 +Subject: [PATCH] html: properly check namespace in "in body" any other end tag + +When processing "any other end tag" in the "in body" insertion mode, +when searching for a matching start tag, properly check that said tag is +in the HTML namespace. + +Thanks to ensy for reporting this issue. + +Fixes CVE-2026-42506 + +Change-Id: Ia05867b3d8f8df69f7e9410a85d126fe0b092875 +Reviewed-on: https://go-review.googlesource.com/c/net/+/781700 +Auto-Submit: Gopher Robot +TryBot-Bypass: Roland Shoemaker +Reviewed-by: Nicholas Husin +Reviewed-by: Nicholas Husin +Reviewed-by: Neal Patel +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/golang/net/commit/0dc5b7a5f81d7155ade6d5e9db35992998679932.patch +--- + vendor/golang.org/x/net/html/parse.go | 4 +--- + .../x/net/html/testdata/go/in_body_end.dat | 17 +++++++++++++++++ + 2 files changed, 18 insertions(+), 3 deletions(-) + create mode 100644 vendor/golang.org/x/net/html/testdata/go/in_body_end.dat + +diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go +index 4d12a1c..3392845 100644 +--- a/vendor/golang.org/x/net/html/parse.go ++++ b/vendor/golang.org/x/net/html/parse.go +@@ -1368,8 +1368,6 @@ func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) { + } + + // inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM. +-// "Any other end tag" handling from 12.2.6.5 The rules for parsing tokens in foreign content +-// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign + func (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) { + for i := len(p.oe) - 1; i >= 0; i-- { + // Two element nodes have the same tag if they have the same Data (a +@@ -1379,7 +1377,7 @@ func (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) { + // Uncommon (custom) tags get a zero DataAtom. + // + // The if condition here is equivalent to (p.oe[i].Data == tagName). +- if (p.oe[i].DataAtom == tagAtom) && ++ if p.oe[i].Namespace == "" && (p.oe[i].DataAtom == tagAtom) && + ((tagAtom != 0) || (p.oe[i].Data == tagName)) { + p.oe = p.oe[:i] + break +diff --git a/vendor/golang.org/x/net/html/testdata/go/in_body_end.dat b/vendor/golang.org/x/net/html/testdata/go/in_body_end.dat +new file mode 100644 +index 0000000..5e14b34 +--- /dev/null ++++ b/vendor/golang.org/x/net/html/testdata/go/in_body_end.dat +@@ -0,0 +1,17 @@ ++#data ++--> ++#errors ++#document ++| ++| ++| ++| ++| ++| ++| ++|