aboutsummaryrefslogtreecommitdiff
path: root/src/archive/zip/reader.go
diff options
context:
space:
mode:
authorRoland Shoemaker <roland@golang.org>2021-05-11 11:31:31 -0700
committerKatie Hockman <katie@golang.org>2021-05-28 13:47:27 +0000
commitc92adf420a3d9a5510f9aea382d826f0c9216a10 (patch)
tree5e52903603ba8fd0445b8fe2c4943ee4c45d5b46 /src/archive/zip/reader.go
parent31d60cda1f58b7558fc5725d2b9e4531655d980e (diff)
downloadgo-c92adf420a3d9a5510f9aea382d826f0c9216a10.tar.gz
go-c92adf420a3d9a5510f9aea382d826f0c9216a10.zip
[release-branch.go1.15] archive/zip: only preallocate File slice if reasonably sized
Since the number of files in the EOCD record isn't validated, it isn't safe to preallocate Reader.Files using that field. A malformed archive can indicate it contains up to 1 << 128 - 1 files. We can still safely preallocate the slice by checking if the specified number of files in the archive is reasonable, given the size of the archive. Thanks to the OSS-Fuzz project for discovering this issue and to Emmanuel Odeke for reporting it. Updates #46242 Fixes #46396 Fixes CVE-2021-33196 Change-Id: I3c76d8eec178468b380d87fdb4a3f2cb06f0ee76 Reviewed-on: https://go-review.googlesource.com/c/go/+/318909 Trust: Roland Shoemaker <roland@golang.org> Trust: Katie Hockman <katie@golang.org> Trust: Joe Tsai <thebrokentoaster@gmail.com> Run-TryBot: Roland Shoemaker <roland@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com> (cherry picked from commit 74242baa4136c7a9132a8ccd9881354442788c8c) Reviewed-on: https://go-review.googlesource.com/c/go/+/322949 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Diffstat (limited to 'src/archive/zip/reader.go')
-rw-r--r--src/archive/zip/reader.go10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index 13ff9ddcf4..2d5151af3d 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -84,7 +84,15 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
return err
}
z.r = r
- z.File = make([]*File, 0, end.directoryRecords)
+ // Since the number of directory records is not validated, it is not
+ // safe to preallocate z.File without first checking that the specified
+ // number of files is reasonable, since a malformed archive may
+ // indicate it contains up to 1 << 128 - 1 files. Since each file has a
+ // header which will be _at least_ 30 bytes we can safely preallocate
+ // if (data size / 30) >= end.directoryRecords.
+ if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+ z.File = make([]*File, 0, end.directoryRecords)
+ }
z.Comment = end.comment
rs := io.NewSectionReader(r, 0, size)
if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil {