]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/gob: prevent a decoder state overflow
authorDaniel Martí <mvdan@mvdan.cc>
Thu, 22 Sep 2022 12:35:08 +0000 (13:35 +0100)
committerDaniel Martí <mvdan@mvdan.cc>
Tue, 4 Oct 2022 13:27:35 +0000 (13:27 +0000)
When decoding a struct, if a positive delta is large enough to overflow
when added to fieldnum, we would panic due to the resulting negative index.

Instead, catch this problem and produce an error like we do with
negative delta integers. If fieldnum ends up being negative or smaller
than state.fieldnum, the addition overflowed.

While here, remove an unnecessary break after an error call,
since those error functions cause a panic.

Fixes #55337.

Change-Id: I7a0e4f43e5c81a703e79c1597e3bb3714cc832c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/432715
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/encoding/gob/decode.go
src/encoding/gob/encoder_test.go

index 480832ca4f2680f4e3b72b8e84ffba721aa8b97a..316565adb21548fa480d8f9e41065fe97388b411 100644 (file)
@@ -450,11 +450,10 @@ func (dec *Decoder) decodeStruct(engine *decEngine, value reflect.Value) {
                if delta == 0 { // struct terminator is zero delta fieldnum
                        break
                }
-               fieldnum := state.fieldnum + delta
-               if fieldnum >= len(engine.instr) {
+               if state.fieldnum >= len(engine.instr)-delta { // subtract to compare without overflow
                        error_(errRange)
-                       break
                }
+               fieldnum := state.fieldnum + delta
                instr := &engine.instr[fieldnum]
                var field reflect.Value
                if instr.index != nil {
index 6934841b3af8c2cb24508c29a9bcc708fa7d877c..484be43c47bbe113e6c37df9f7dbc743880042b6 100644 (file)
@@ -1265,3 +1265,16 @@ func TestDecodePartial(t *testing.T) {
                }
        }
 }
+
+func TestDecoderOverflow(t *testing.T) {
+       // Issue 55337.
+       dec := NewDecoder(bytes.NewReader([]byte{
+               0x12, 0xff, 0xff, 0x2, 0x2, 0x20, 0x0, 0xf8, 0x7f, 0xff, 0xff, 0xff,
+               0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20,
+       }))
+       var r interface{}
+       err := dec.Decode(r)
+       if err == nil {
+               t.Fatalf("expected an error")
+       }
+}