From: Sudhir Dumbhare <[email protected]>

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

Signed-off-by: Sudhir Dumbhare <[email protected]>
---
 meta/recipes-devtools/go/go-1.22.12.inc       |   1 +
 .../go/go/CVE-2026-32288.patch                | 162 ++++++++++++++++++
 2 files changed, 163 insertions(+)
 create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32288.patch

diff --git a/meta/recipes-devtools/go/go-1.22.12.inc 
b/meta/recipes-devtools/go/go-1.22.12.inc
index 7dd1c021cb..b3cb3b58b4 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -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"
 
diff --git a/meta/recipes-devtools/go/go/CVE-2026-32288.patch 
b/meta/recipes-devtools/go/go/CVE-2026-32288.patch
new file mode 100644
index 0000000000..7b838db345
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-32288.patch
@@ -0,0 +1,162 @@
+From 12bbeb57c20d32519c3f891b428c6f7765db8f55 Mon Sep 17 00:00:00 2001
+From: Damien Neil <[email protected]>
+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 ([email protected]),
+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 <[email protected]>
+Reviewed-by: Roland Shoemaker <[email protected]>
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/4003
+Reviewed-by: Nicholas Husin <[email protected]>
+Reviewed-by: Neal Patel <[email protected]>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/763554
+TryBot-Bypass: Gopher Robot <[email protected]>
+Auto-Submit: Gopher Robot <[email protected]>
+Reviewed-by: Junyang Shao <[email protected]>
+Reviewed-by: David Chase <[email protected]>
+(cherry picked from commit 82b0cdb7411ea2cf02d3a45e6983cc7c8c009d9e)
+Signed-off-by: Sudhir Dumbhare <[email protected]>
+---
+ 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
+
-- 
2.35.6

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#238620): 
https://lists.openembedded.org/g/openembedded-core/message/238620
Mute This Topic: https://lists.openembedded.org/mt/119773247/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to