1
0
mirror of https://git.yoctoproject.org/poky synced 2026-07-15 15:37:03 +00:00

go: fix CVE-2026-32288

This patch applies the upstream fix [1], as referenced in [2],
to address unbounded sparse map handling in `archive/tar`.

[1] https://github.com/golang/go/commit/82b0cdb7411ea2cf02d3a45e6983cc7c8c009d9e
[2] https://security-tracker.debian.org/tracker/CVE-2026-32288

Reference:
https://nvd.nist.gov/vuln/detail/CVE-2026-32288

(From OE-Core rev: 775c3af36899eebe5612844accdfd2a8a2a9327a)

Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
Sudhir Dumbhare
2026-06-12 06:16:19 -07:00
committed by Paul Barker
parent 3401fba731
commit 7d782f3ed0
2 changed files with 163 additions and 0 deletions
+1
View File
@@ -60,6 +60,7 @@ SRC_URI += "\
file://CVE-2026-42507.patch \
file://CVE-2025-58183.patch \
file://CVE-2026-25679.patch \
file://CVE-2026-32288.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
@@ -0,0 +1,162 @@
From 12bbeb57c20d32519c3f891b428c6f7765db8f55 Mon Sep 17 00:00:00 2001
From: Damien Neil <dneil@google.com>
Date: Mon, 23 Mar 2026 13:12:44 -0700
Subject: [PATCH] [release-branch.go1.25] archive/tar: limit the number of
old GNU sparse format entries
We did not set a limit on the maximum size of sparse maps in
the old GNU sparse format. Set a limit based on the cumulative
size of the extension blocks used to encode the map (consistent
with how we limit the sparse map size for other formats).
Add an additional limit to the total number of sparse file entries,
regardless of encoding, to all sparse formats.
Thanks to Colin Walters (walters@verbum.org),
Uuganbayar Lkhamsuren (https://github.com/uug4na),
and Jakub Ciolek for reporting this issue.
Fixes #78301
Fixes CVE-2026-32288
CVE: CVE-2026-32288
Upstream-Status: Backport [https://github.com/golang/go/commit/82b0cdb7411ea2cf02d3a45e6983cc7c8c009d9e]
Change-Id: I84877345d7b41cc60c58771860ba70e16a6a6964
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3901
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/4003
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Neal Patel <nealpatel@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/763554
TryBot-Bypass: Gopher Robot <gobot@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 82b0cdb7411ea2cf02d3a45e6983cc7c8c009d9e)
Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
---
src/archive/tar/format.go | 6 ++++++
src/archive/tar/reader.go | 28 ++++++++++++++++++++++++----
src/archive/tar/reader_test.go | 11 +++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/src/archive/tar/format.go b/src/archive/tar/format.go
index 9954b4d9f55..32e58a9d9b4 100644
--- a/src/archive/tar/format.go
+++ b/src/archive/tar/format.go
@@ -147,6 +147,12 @@ const (
// Max length of a special file (PAX header, GNU long name or link).
// This matches the limit used by libarchive.
maxSpecialFileSize = 1 << 20
+
+ // Maximum number of sparse file entries.
+ // We should never actually hit this limit
+ // (every sparse encoding will first be limited by maxSpecialFileSize),
+ // but this adds an additional layer of defense.
+ maxSparseFileEntries = 1 << 20
)
// blockPadding computes the number of bytes needed to pad offset up to the
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
index 71d0b20b76d..3bb8d62106c 100644
--- a/src/archive/tar/reader.go
+++ b/src/archive/tar/reader.go
@@ -490,7 +490,8 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
}
s := blk.toGNU().sparse()
spd := make(sparseDatas, 0, s.maxEntries())
- for {
+ totalSize := len(s)
+ for totalSize < maxSpecialFileSize {
for i := 0; i < s.maxEntries(); i++ {
// This termination condition is identical to GNU and BSD tar.
if s.entry(i).offset()[0] == 0x00 {
@@ -501,7 +502,11 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
if p.err != nil {
return nil, p.err
}
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ var err error
+ spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
+ if err != nil {
+ return nil, err
+ }
}
if s.isExtended()[0] > 0 {
@@ -510,10 +515,12 @@ func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, err
return nil, err
}
s = blk.toSparse()
+ totalSize += len(s)
continue
}
return spd, nil // Done
}
+ return nil, errSparseTooLong
}
// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format
@@ -586,7 +593,10 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
if err1 != nil || err2 != nil {
return nil, ErrHeader
}
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
+ if err != nil {
+ return nil, err
+ }
}
return spd, nil
}
@@ -620,12 +630,22 @@ func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
if err1 != nil || err2 != nil {
return nil, ErrHeader
}
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ spd, err = appendSparseEntry(spd, sparseEntry{Offset: offset, Length: length})
+ if err != nil {
+ return nil, err
+ }
sparseMap = sparseMap[2:]
}
return spd, nil
}
+func appendSparseEntry(spd sparseDatas, ent sparseEntry) (sparseDatas, error) {
+ if len(spd) >= maxSparseFileEntries {
+ return nil, errSparseTooLong
+ }
+ return append(spd, ent), nil
+}
+
// Read reads from the current file in the tar archive.
// It returns (0, io.EOF) when it reaches the end of that file,
// until [Next] is called to advance to the next file.
diff --git a/src/archive/tar/reader_test.go b/src/archive/tar/reader_test.go
index 7e0462c3f88..4a527766ba8 100644
--- a/src/archive/tar/reader_test.go
+++ b/src/archive/tar/reader_test.go
@@ -1126,6 +1126,17 @@ func TestReadOldGNUSparseMap(t *testing.T) {
input: makeInput(FormatGNU, "",
makeSparseStrings(sparseDatas{{10 << 30, 512}, {20 << 30, 512}})...),
wantMap: sparseDatas{{10 << 30, 512}, {20 << 30, 512}},
+ }, {
+ input: makeInput(FormatGNU, "",
+ makeSparseStrings(func() sparseDatas {
+ var datas sparseDatas
+ // This is more than enough entries to exceed our limit.
+ for i := range int64(1 << 20) {
+ datas = append(datas, sparseEntry{i * 2, (i * 2) + 1})
+ }
+ return datas
+ }())...),
+ wantErr: errSparseTooLong,
}}
for i, v := range vectors {
--
2.35.6