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:
committed by
Paul Barker
parent
3401fba731
commit
7d782f3ed0
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user