CVE-2021-39293
authorRoland Shoemaker <roland@golang.org>
Wed, 18 Aug 2021 18:49:29 +0000 (11:49 -0700)
committerShengjing Zhu <zhsj@debian.org>
Fri, 4 Mar 2022 13:48:18 +0000 (13:48 +0000)
Origin: backport, https://github.com/golang/go/commit/bacbc334

Gbp-Pq: Name 0007-CVE-2021-39293.patch

src/archive/zip/reader.go
src/archive/zip/reader_test.go

index 2d5151af3da39b769e4c13832cad36232534d1d8..a6957739d67dc8f27279e3c8129758175cedecf4 100644 (file)
@@ -90,7 +90,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
        // 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 {
+       if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
                z.File = make([]*File, 0, end.directoryRecords)
        }
        z.Comment = end.comment
index 6f67d2e4a9415d9400a0a0ea179698b528d0b8aa..ef6ff5f68b999e28cb82c6043d677690c7af7a6b 100644 (file)
@@ -1129,3 +1129,21 @@ func TestCVE202133196(t *testing.T) {
                t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
        }
 }
+
+func TestCVE202139293(t *testing.T) {
+       // directory size is so large, that the check in Reader.init
+       // overflows when subtracting from the archive size, causing
+       // the pre-allocation check to be bypassed.
+       data := []byte{
+               0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
+               0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+               0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
+               0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+               0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+               0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
+       }
+       _, err := NewReader(bytes.NewReader(data), int64(len(data)))
+       if err != ErrFormat {
+               t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
+       }
+}