Skip to content
Draft
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
105 changes: 105 additions & 0 deletions SPECS/packer/CVE-2026-25680.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
From 40a0242b90f50d017b39d95e5bdb2c88437f5973 Mon Sep 17 00:00:00 2001
From: Roland Shoemaker <roland@golang.org>
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 <roland@golang.org>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Neal Patel <nealpatel@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
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 3d3ae4a..df5f5b9 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

113 changes: 113 additions & 0 deletions SPECS/packer/CVE-2026-25681.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
From 01688a761079d2a4b40afe5654b04cd966be5d36 Mon Sep 17 00:00:00 2001
From: Roland Shoemaker <roland@golang.org>
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 <nealpatel@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
TryBot-Bypass: Roland Shoemaker <roland@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
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
+<!DOCTYPE &gt; PUBLIC "&gt;" "&gt;">
+#errors
+#document
+| <!DOCTYPE > ">" ">">
+| <html>
+| <head>
+| <body>
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 &gt; 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, ">", "&gt;")); err != nil {
return err
}
if err := w.WriteByte(q); err != nil {
--
2.45.4

61 changes: 61 additions & 0 deletions SPECS/packer/CVE-2026-39827.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
From c2e3c5905d86e8ac8961e380e46c4423e9f9660c Mon Sep 17 00:00:00 2001
From: Nicola Murino <nicola.murino@gmail.com>
Date: Sun, 1 Mar 2026 11:49:28 +0100
Subject: [PATCH] ssh: prevent memory leak when rejecting channels

When a server rejects an incoming channel request via
NewChannel.Reject, the channel is left in the multiplexer's
channel list. Because the channel is never explicitly removed or
closed, its internal buffers and sync primitives remain allocated
for the lifetime of the SSH connection.

A malicious client could exploit this behavior by repeatedly
requesting to open channels that are destined to be rejected,
causing unbounded memory growth and potentially leading to a
Denial of Service (DoS) via resource exhaustion.

This change fixes the leak by calling ch.mux.chanList.remove
within the Reject method, removing the channel from the list and allowing the
garbage collector to reclaim the associated memory immediately.

Fixes golang/go#35127
Fixes CVE-2026-3982

Change-Id: Iaa177f5dfd151812dd404e528a4a1c77527a0e29
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781320
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/golang/crypto/commit/6c195c8a97ae3d91a366ebdd7787d5faa64bf42a.patch
---
vendor/golang.org/x/crypto/ssh/channel.go | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/vendor/golang.org/x/crypto/ssh/channel.go b/vendor/golang.org/x/crypto/ssh/channel.go
index cc0bb7a..00e4ceb 100644
--- a/vendor/golang.org/x/crypto/ssh/channel.go
+++ b/vendor/golang.org/x/crypto/ssh/channel.go
@@ -530,7 +530,17 @@ func (ch *channel) Reject(reason RejectionReason, message string) error {
Language: "en",
}
ch.decided = true
- return ch.sendMessage(reject)
+ err := ch.sendMessage(reject)
+
+ // Remove the channel from the mux to prevent memory leaks.
+ // Do not call ch.close() here: no goroutine holds a reference to a
+ // rejected channel's internal channels (msg, incomingRequests), so
+ // removing it from chanList is sufficient for GC. Calling close()
+ // would race with the mux loop goroutine (handlePacket or dropAll),
+ // causing a panic from closing an already-closed channel.
+ ch.mux.chanList.remove(ch.localId)
+
+ return err
}

func (ch *channel) Read(data []byte) (int, error) {
--
2.45.4

69 changes: 69 additions & 0 deletions SPECS/packer/CVE-2026-39828.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
From b73ac14dba2a0aa2ea9d75f54b39786ec949ed22 Mon Sep 17 00:00:00 2001
From: Nicola Murino <nicola.murino@gmail.com>
Date: Sun, 1 Feb 2026 17:55:09 +0100
Subject: [PATCH] ssh: enforce nil Permissions when returning
PartialSuccessError

In serverAuthenticate, the permissions variable is reset to nil at the
beginning of the authentication loop. If an authentication callback
returns a PartialSuccessError along with non-nil Permissions, those
permissions are currently silently discarded before the next
authentication step.

This change returns an error if a callback returns both a PartialSuccessError
and non-nil Permissions, preventing API misuse where the user might
erroneously expect those permissions to be preserved or merged into the
final session permissions.

This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport.

Fixes golang/go#79562
Fixes CVE-2026-39828

Change-Id: I632c9e46e2b5e8804ef88081063a3612a2462f9f
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/781621
Reviewed-by: Neal Patel <nealpatel@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/golang/crypto/commit/b25012b37bb33a8d0a59388aad6b32e43ce87225.patch
---
vendor/golang.org/x/crypto/ssh/server.go | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 5b5ccd9..181bda3 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -196,8 +196,10 @@ func (c *pubKeyCache) add(candidate cachedPubKey) {
type ServerConn struct {
Conn

- // If the succeeding authentication callback returned a
- // non-nil Permissions pointer, it is stored here.
+ // If the succeeding authentication callback returned a non-nil Permissions
+ // pointer, it is stored here. These are the permissions from the final,
+ // successful authentication method. Permissions returned by callbacks that
+ // return PartialSuccessError are not preserved and must be nil.
Permissions *Permissions
}

@@ -778,6 +780,13 @@ userAuthLoop:
var failureMsg userAuthFailureMsg

if partialSuccess, ok := authErr.(*PartialSuccessError); ok {
+ // Permissions are not preserved between authentication steps. To
+ // avoid confusion about the final state of the connection, we
+ // disallow returning non-nil Permissions combined with
+ // PartialSuccessError.
+ if perms != nil {
+ return nil, errors.New("ssh: permissions must be nil when returning PartialSuccessError")
+ }
// After a partial success error we don't allow changing the user
// name and execute the NoClientAuthCallback.
partialSuccessReturned = true
--
2.45.4

Loading
Loading