Skip to content
Open
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
75 changes: 75 additions & 0 deletions SPECS/containerd2/CVE-2026-27136.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
From 854b3d9d75f1a6c90b4ef78036e54ae6e574c045 Mon Sep 17 00:00:00 2001
From: Roland Shoemaker <roland@golang.org>
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 <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/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 6598c1f..058dfb2 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 "</script>" 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
@@ -1273,8 +1277,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

Loading
Loading