Skip to content

Commit

Permalink
[release-branch.go1.17] math/big: check buffer lengths in GobDecode
Browse files Browse the repository at this point in the history
In Float.GobDecode and Rat.GobDecode, check buffer sizes before
indexing slices.

Updates golang#53871
Fixes golang#54094

Change-Id: I1b652c32c2bc7a0e8aa7620f7be9b2740c568b0a
Reviewed-on: https://go-review.googlesource.com/c/go/+/417774
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
(cherry picked from commit 055113e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/419814
Reviewed-by: Julie Qiu <julieqiu@google.com>
  • Loading branch information
rolandshoemaker authored and danbudris committed Sep 14, 2022
1 parent abc0063 commit 2fcd1ec
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/math/big/floatmarsh.go
Expand Up @@ -8,6 +8,7 @@ package big

import (
"encoding/binary"
"errors"
"fmt"
)

Expand Down Expand Up @@ -67,6 +68,9 @@ func (z *Float) GobDecode(buf []byte) error {
*z = Float{}
return nil
}
if len(buf) < 6 {
return errors.New("Float.GobDecode: buffer too small")
}

if buf[0] != floatGobVersion {
return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
Expand All @@ -83,6 +87,9 @@ func (z *Float) GobDecode(buf []byte) error {
z.prec = binary.BigEndian.Uint32(buf[2:])

if z.form == finite {
if len(buf) < 10 {
return errors.New("Float.GobDecode: buffer too small for finite form float")
}
z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
z.mant = z.mant.setBytes(buf[10:])
}
Expand Down
12 changes: 12 additions & 0 deletions src/math/big/floatmarsh_test.go
Expand Up @@ -137,3 +137,15 @@ func TestFloatJSONEncoding(t *testing.T) {
}
}
}

func TestFloatGobDecodeShortBuffer(t *testing.T) {
for _, tc := range [][]byte{
[]byte{0x1, 0x0, 0x0, 0x0},
[]byte{0x1, 0xfa, 0x0, 0x0, 0x0, 0x0},
} {
err := NewFloat(0).GobDecode(tc)
if err == nil {
t.Error("expected GobDecode to return error for malformed input")
}
}
}
6 changes: 6 additions & 0 deletions src/math/big/ratmarsh.go
Expand Up @@ -45,12 +45,18 @@ func (z *Rat) GobDecode(buf []byte) error {
*z = Rat{}
return nil
}
if len(buf) < 5 {
return errors.New("Rat.GobDecode: buffer too small")
}
b := buf[0]
if b>>1 != ratGobVersion {
return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
}
const j = 1 + 4
i := j + binary.BigEndian.Uint32(buf[j-4:j])
if len(buf) < int(i) {
return errors.New("Rat.GobDecode: buffer too small")
}
z.a.neg = b&1 != 0
z.a.abs = z.a.abs.setBytes(buf[j:i])
z.b.abs = z.b.abs.setBytes(buf[i:])
Expand Down
12 changes: 12 additions & 0 deletions src/math/big/ratmarsh_test.go
Expand Up @@ -123,3 +123,15 @@ func TestRatXMLEncoding(t *testing.T) {
}
}
}

func TestRatGobDecodeShortBuffer(t *testing.T) {
for _, tc := range [][]byte{
[]byte{0x2},
[]byte{0x2, 0x0, 0x0, 0x0, 0xff},
} {
err := NewRat(1, 2).GobDecode(tc)
if err == nil {
t.Error("expected GobDecode to return error for malformed input")
}
}
}

0 comments on commit 2fcd1ec

Please sign in to comment.