]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: use saferio to read large buffer
authorIan Lance Taylor <iant@golang.org>
Sat, 25 Jun 2022 00:00:24 +0000 (17:00 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 19 Aug 2022 16:03:42 +0000 (16:03 +0000)
Avoid allocating large amounts of memory for corrupt input.

No test case because the problem can only happen for invalid data.
Let the fuzzer find cases like this.

Fixes #53369

Change-Id: I67c5e75bf181ad84988d6d6da12507df0e6df8e8
Reviewed-on: https://go-review.googlesource.com/c/go/+/413979
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/encoding/gob/decode.go
src/encoding/gob/decoder.go
src/go/build/deps_test.go

index 7bca13c957a92b45a175ec9b880a946641f22b3e..470e357b10ac4d8e1c3c9effd0c9f65f9796c4bd 100644 (file)
@@ -57,17 +57,6 @@ func (d *decBuffer) Drop(n int) {
        d.offset += n
 }
 
-// Size grows the buffer to exactly n bytes, so d.Bytes() will
-// return a slice of length n. Existing data is first discarded.
-func (d *decBuffer) Size(n int) {
-       d.Reset()
-       if cap(d.data) < n {
-               d.data = make([]byte, n)
-       } else {
-               d.data = d.data[0:n]
-       }
-}
-
 func (d *decBuffer) ReadByte() (byte, error) {
        if d.offset >= len(d.data) {
                return 0, io.EOF
@@ -85,6 +74,12 @@ func (d *decBuffer) Bytes() []byte {
        return d.data[d.offset:]
 }
 
+// SetBytes sets the buffer to the bytes, discarding any existing data.
+func (d *decBuffer) SetBytes(data []byte) {
+       d.data = data
+       d.offset = 0
+}
+
 func (d *decBuffer) Reset() {
        d.data = d.data[0:0]
        d.offset = 0
index 9c4257eb3b57ee00319a20228391ddd35710399b..5b77adc7e85679bdf4a5f4f9074dcc2153520405 100644 (file)
@@ -7,6 +7,7 @@ package gob
 import (
        "bufio"
        "errors"
+       "internal/saferio"
        "io"
        "reflect"
        "sync"
@@ -98,8 +99,9 @@ func (dec *Decoder) readMessage(nbytes int) {
                panic("non-empty decoder buffer")
        }
        // Read the data
-       dec.buf.Size(nbytes)
-       _, dec.err = io.ReadFull(dec.r, dec.buf.Bytes())
+       var buf []byte
+       buf, dec.err = saferio.ReadData(dec.r, uint64(nbytes))
+       dec.buf.SetBytes(buf)
        if dec.err == io.EOF {
                dec.err = io.ErrUnexpectedEOF
        }
index 07bac04dcb4136857b7038736808c4b7427b3b01..19b886875c9c659affe1050470db91fd998cbb82 100644 (file)
@@ -187,6 +187,9 @@ var depsRules = `
          text/scanner,
          text/tabwriter;
 
+       io, reflect
+       < internal/saferio;
+
        # encodings
        # core ones do not use fmt.
        io, strconv
@@ -200,7 +203,7 @@ var depsRules = `
 
        fmt !< encoding/base32, encoding/base64;
 
-       FMT, encoding/base32, encoding/base64
+       FMT, encoding/base32, encoding/base64, internal/saferio
        < encoding/ascii85, encoding/csv, encoding/gob, encoding/hex,
          encoding/json, encoding/pem, encoding/xml, mime;
 
@@ -239,9 +242,6 @@ var depsRules = `
        encoding/binary, regexp
        < index/suffixarray;
 
-       io, reflect
-       < internal/saferio;
-
        # executable parsing
        FMT, encoding/binary, compress/zlib, internal/saferio
        < runtime/debug