1
0
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:
Tatiana Bradley 2022-05-06 11:25:06 -04:00 committed by Michael Knyszek
parent ba8788ebce
commit 0117dee7dc
2 changed files with 48 additions and 34 deletions

View File

@ -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.

View File

@ -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)
}
}