95 строки
3.7 KiB
Diff
95 строки
3.7 KiB
Diff
From 042465900fcbb246c602c856ccd924ddf093947e Mon Sep 17 00:00:00 2001
|
|
From: Muhammad Falak R Wani <falakreyaz@gmail.com>
|
|
Date: Tue, 9 Jul 2024 19:27:30 +0530
|
|
Subject: [PATCH] archive/tar: limit size of headers
|
|
|
|
Set a 1MiB limit on special file blocks (PAX headers, GNU long names,
|
|
GNU link names), to avoid reading arbitrarily large amounts of data
|
|
into memory.
|
|
|
|
Thanks to Adam Korczynski (ADA Logics) and OSS-Fuzz for reporting
|
|
this issue.
|
|
|
|
Fixes CVE-2022-2879
|
|
Updates #54853
|
|
Fixes #55925
|
|
|
|
Signed-off-by: Muhammad Falak R Wani <falakreyaz@gmail.com>
|
|
---
|
|
.../vbatts/tar-split/archive/tar/format.go | 4 ++++
|
|
.../vbatts/tar-split/archive/tar/reader.go | 14 ++++++++++++--
|
|
.../vbatts/tar-split/archive/tar/writer.go | 3 +++
|
|
3 files changed, 19 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/format.go b/vendor/github.com/vbatts/tar-split/archive/tar/format.go
|
|
index 1f89d0c..6097798 100644
|
|
--- a/vendor/github.com/vbatts/tar-split/archive/tar/format.go
|
|
+++ b/vendor/github.com/vbatts/tar-split/archive/tar/format.go
|
|
@@ -143,6 +143,10 @@ const (
|
|
blockSize = 512 // Size of each block in a tar stream
|
|
nameSize = 100 // Max length of the name field in USTAR format
|
|
prefixSize = 155 // Max length of the prefix field in USTAR format
|
|
+
|
|
+ // Max length of a special file (PAX header, GNU long name or link).
|
|
+ // This matches the limit used by libarchive.
|
|
+ maxSpecialFileSize = 1 << 20
|
|
)
|
|
|
|
// blockPadding computes the number of bytes needed to pad offset up to the
|
|
diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/reader.go b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go
|
|
index af006fc..2baa0d5 100644
|
|
--- a/vendor/github.com/vbatts/tar-split/archive/tar/reader.go
|
|
+++ b/vendor/github.com/vbatts/tar-split/archive/tar/reader.go
|
|
@@ -139,7 +139,7 @@ func (tr *Reader) next() (*Header, error) {
|
|
continue // This is a meta header affecting the next header
|
|
case TypeGNULongName, TypeGNULongLink:
|
|
format.mayOnlyBe(FormatGNU)
|
|
- realname, err := io.ReadAll(tr)
|
|
+ realname, err := readSpecialFile(tr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
@@ -333,7 +333,7 @@ func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
|
|
// parsePAX parses PAX headers.
|
|
// If an extended header (type 'x') is invalid, ErrHeader is returned
|
|
func parsePAX(r io.Reader) (map[string]string, error) {
|
|
- buf, err := io.ReadAll(r)
|
|
+ buf, err := readSpecialFile(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
@@ -884,6 +884,16 @@ func tryReadFull(r io.Reader, b []byte) (n int, err error) {
|
|
return n, err
|
|
}
|
|
|
|
+// readSpecialFile is like io.ReadAll except it returns
|
|
+// ErrFieldTooLong if more than maxSpecialFileSize is read.
|
|
+func readSpecialFile(r io.Reader) ([]byte, error) {
|
|
+ buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
|
|
+ if len(buf) > maxSpecialFileSize {
|
|
+ return nil, ErrFieldTooLong
|
|
+ }
|
|
+ return buf, err
|
|
+}
|
|
+
|
|
// discard skips n bytes in r, reporting an error if unable to do so.
|
|
func discard(tr *Reader, n int64) error {
|
|
var seekSkipped, copySkipped int64
|
|
diff --git a/vendor/github.com/vbatts/tar-split/archive/tar/writer.go b/vendor/github.com/vbatts/tar-split/archive/tar/writer.go
|
|
index e80498d..893eac0 100644
|
|
--- a/vendor/github.com/vbatts/tar-split/archive/tar/writer.go
|
|
+++ b/vendor/github.com/vbatts/tar-split/archive/tar/writer.go
|
|
@@ -199,6 +199,9 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
|
|
flag = TypeXHeader
|
|
}
|
|
data := buf.String()
|
|
+ if len(data) > maxSpecialFileSize {
|
|
+ return ErrFieldTooLong
|
|
+ }
|
|
if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {
|
|
return err // Global headers return here
|
|
}
|
|
--
|
|
2.40.1
|
|
|