@@ -43,6 +43,7 @@ SRC_URI += "\
file://CVE-2025-68121_p3.patch \
file://CVE-2025-58183.patch \
file://CVE-2026-25679.patch \
+ file://CVE-2026-32288.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
new file mode 100644
@@ -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
+