1
0
mirror of https://github.com/golang/go synced 2024-11-11 18:21:40 -07:00

[release-branch.go1.17] math/big: check buffer lengths in GobDecode

In Float.GobDecode and Rat.GobDecode, check buffer sizes before
indexing slices.

Updates #53871
Fixes #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 055113ef36)
Reviewed-on: https://go-review.googlesource.com/c/go/+/419814
Reviewed-by: Julie Qiu <julieqiu@google.com>
This commit is contained in:
Roland Shoemaker 2022-07-15 10:43:44 -07:00 committed by Cherry Mui
parent d9242f7a8c
commit 703c8ab7e5
4 changed files with 37 additions and 0 deletions

View File

@ -8,6 +8,7 @@ package big
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
) )
@ -67,6 +68,9 @@ func (z *Float) GobDecode(buf []byte) error {
*z = Float{} *z = Float{}
return nil return nil
} }
if len(buf) < 6 {
return errors.New("Float.GobDecode: buffer too small")
}
if buf[0] != floatGobVersion { if buf[0] != floatGobVersion {
return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0]) return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
@ -83,6 +87,9 @@ func (z *Float) GobDecode(buf []byte) error {
z.prec = binary.BigEndian.Uint32(buf[2:]) z.prec = binary.BigEndian.Uint32(buf[2:])
if z.form == finite { 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.exp = int32(binary.BigEndian.Uint32(buf[6:]))
z.mant = z.mant.setBytes(buf[10:]) z.mant = z.mant.setBytes(buf[10:])
} }

View File

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

View File

@ -45,12 +45,18 @@ func (z *Rat) GobDecode(buf []byte) error {
*z = Rat{} *z = Rat{}
return nil return nil
} }
if len(buf) < 5 {
return errors.New("Rat.GobDecode: buffer too small")
}
b := buf[0] b := buf[0]
if b>>1 != ratGobVersion { if b>>1 != ratGobVersion {
return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1) return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
} }
const j = 1 + 4 const j = 1 + 4
i := j + binary.BigEndian.Uint32(buf[j-4:j]) 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.neg = b&1 != 0
z.a.abs = z.a.abs.setBytes(buf[j:i]) z.a.abs = z.a.abs.setBytes(buf[j:i])
z.b.abs = z.b.abs.setBytes(buf[i:]) z.b.abs = z.b.abs.setBytes(buf[i:])

View File

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