|
| 1 | +From 56075937df952d2369510b4544c8a7debe800f2d Mon Sep 17 00:00:00 2001 |
| 2 | +From: AllSpark < [email protected]> |
| 3 | +Date: Sat, 15 Nov 2025 06:17:24 +0000 |
| 4 | +Subject: [PATCH] archive/tar: limit GNU sparse 1.0 map size using |
| 5 | + maxSpecialFileSize; add errSparseTooLong error and test fixture |
| 6 | + |
| 7 | +Signed-off-by: Azure Linux Security Servicing Account < [email protected]> |
| 8 | +Upstream-reference: AI Backport of https://github.com/vbatts/tar-split/commit/55da7d6b43bd806ee785d783bdf66bcf302af118.patch |
| 9 | +--- |
| 10 | + .../github.com/vbatts/tar-split/archive/tar/common.go | 1 + |
| 11 | + .../github.com/vbatts/tar-split/archive/tar/reader.go | 10 ++++++++-- |
| 12 | + 2 files changed, 9 insertions(+), 2 deletions(-) |
| 13 | + |
| 14 | +diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/common.go b/vendor/github.com/vbatts/tar-split/archive/tar/common.go |
| 15 | +index dee9e47..e687a08 100644 |
| 16 | +--- a/vendor/github.com/vbatts/tar-split/archive/tar/common.go |
| 17 | ++++ b/vendor/github.com/vbatts/tar-split/archive/tar/common.go |
| 18 | +@@ -34,6 +34,7 @@ var ( |
| 19 | + errMissData = errors.New("archive/tar: sparse file references non-existent data") |
| 20 | + errUnrefData = errors.New("archive/tar: sparse file contains unreferenced data") |
| 21 | + errWriteHole = errors.New("archive/tar: write non-NUL byte in sparse hole") |
| 22 | ++ errSparseTooLong = errors.New("archive/tar: sparse map too long") |
| 23 | + ) |
| 24 | + |
| 25 | + type headerError []string |
| 26 | +diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/reader.go b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go |
| 27 | +index 40f6c86..e508f5a 100644 |
| 28 | +--- a/vendor/github.com/vbatts/tar-split/archive/tar/reader.go |
| 29 | ++++ b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go |
| 30 | +@@ -576,12 +576,18 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) { |
| 31 | + cntNewline int64 |
| 32 | + buf bytes.Buffer |
| 33 | + blk block |
| 34 | ++ totalSize int |
| 35 | + ) |
| 36 | + |
| 37 | + // feedTokens copies data in blocks from r into buf until there are |
| 38 | + // at least cnt newlines in buf. It will not read more blocks than needed. |
| 39 | + feedTokens := func(n int64) error { |
| 40 | + for cntNewline < n { |
| 41 | ++ // Limit the amount of sparse map data read to avoid unbounded memory usage. |
| 42 | ++ totalSize += len(blk) |
| 43 | ++ if totalSize > maxSpecialFileSize { |
| 44 | ++ return errSparseTooLong |
| 45 | ++ } |
| 46 | + if _, err := mustReadFull(r, blk[:]); err != nil { |
| 47 | + return err |
| 48 | + } |
| 49 | +@@ -614,8 +620,8 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) { |
| 50 | + } |
| 51 | + |
| 52 | + // Parse for all member entries. |
| 53 | +- // numEntries is trusted after this since a potential attacker must have |
| 54 | +- // committed resources proportional to what this library used. |
| 55 | ++ // numEntries is trusted after this since feedTokens limits the number of |
| 56 | ++ // tokens based on maxSpecialFileSize. |
| 57 | + if err := feedTokens(2 * numEntries); err != nil { |
| 58 | + return nil, err |
| 59 | + } |
| 60 | +-- |
| 61 | +2.45.4 |
| 62 | + |
0 commit comments