mirror of
https://github.com/golang/go
synced 2024-11-14 06:10:24 -07:00
[release-branch.go1.17] compress/gzip: fix stack exhaustion bug in Reader.Read
Replace recursion with iteration in Reader.Read to avoid stack exhaustion when there are a large number of files. Fixes CVE-2022-30631 Fixes #53717 Updates #53168 Change-Id: I47d8afe3f2d40b0213ab61431df9b221794dbfe0 Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1455673 Reviewed-by: Roland Shoemaker <bracewell@google.com> Reviewed-by: Julie Qiu <julieqiu@google.com> (cherry picked from commit cf498969c8a0bae9d7a24b98fc1f66c824a4775d) Reviewed-on: https://go-review.googlesource.com/c/go/+/417071 Reviewed-by: Heschi Kreinick <heschi@google.com> Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
ba8788ebce
commit
0117dee7dc
@ -248,6 +248,7 @@ func (z *Reader) Read(p []byte) (n int, err error) {
|
|||||||
return 0, z.err
|
return 0, z.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for n == 0 {
|
||||||
n, z.err = z.decompressor.Read(p)
|
n, z.err = z.decompressor.Read(p)
|
||||||
z.digest = crc32.Update(z.digest, crc32.IEEETable, p[:n])
|
z.digest = crc32.Update(z.digest, crc32.IEEETable, p[:n])
|
||||||
z.size += uint32(n)
|
z.size += uint32(n)
|
||||||
@ -278,12 +279,9 @@ func (z *Reader) Read(p []byte) (n int, err error) {
|
|||||||
if _, z.err = z.readHeader(); z.err != nil {
|
if _, z.err = z.readHeader(); z.err != nil {
|
||||||
return n, z.err
|
return n, z.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from next file, if necessary.
|
|
||||||
if n > 0 {
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
return z.Read(p)
|
|
||||||
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the Reader. It does not close the underlying io.Reader.
|
// Close closes the Reader. It does not close the underlying io.Reader.
|
||||||
|
@ -515,3 +515,19 @@ func TestTruncatedStreams(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCVE202230631(t *testing.T) {
|
||||||
|
var empty = []byte{0x1f, 0x8b, 0x08, 0x00, 0xa7, 0x8f, 0x43, 0x62, 0x00,
|
||||||
|
0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
|
r := bytes.NewReader(bytes.Repeat(empty, 4e6))
|
||||||
|
z, err := NewReader(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewReader: got %v, want nil", err)
|
||||||
|
}
|
||||||
|
// Prior to CVE-2022-30631 fix, this would cause an unrecoverable panic due
|
||||||
|
// to stack exhaustion.
|
||||||
|
_, err = z.Read(make([]byte, 10))
|
||||||
|
if err != io.EOF {
|
||||||
|
t.Errorf("Reader.Read: got %v, want %v", err, io.EOF)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user