go: math/big: panic in big.ParseFloat (off by one access)

What version of Go are you using (go version)?

$ go version
go version go1.14 linux/amd64

Does this issue reproduce with the latest release?

Yes but this is rgression, does not reproduce with go1.13.8 darwin/amd64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/root/.go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/root/.go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build640944533=/tmp/go-build -gno-record-gcc-switches"
uname -sr: Linux 4.19.76-linuxkit
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC 2.23-0ubuntu11) stable release version 2.23, by Roland McGrath et al.

What did you do?

I ran the following program

https://play.golang.org/p/rNIIVshF9_2

import (
	"fmt"
	"math/big"
)

func main() {
	str := "000000000000000010200000000000000.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
	prec := 64
	if len(str) > prec {
		prec = len(str)
	}
	val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero)
	fmt.Printf("Hello, playground %#+v %#+v", val, err)
}

This input was found by fuzzing project jsoniter with oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20885

What did you expect to see?

No crash and output `Hello, playground +1.01999999999999999999999999999999999999999999999999999999

What did you see instead?

A panic

panic: runtime error: index out of range [101] with length 101

goroutine 1 [running]:
math/big.nat.divBasic(0xc000098a80, 0x64, 0x68, 0xc0000c8570, 0x65, 0x9c, 0xc0000b5688, 0x33, 0xff)
	/root/.go/src/math/big/nat.go:790 +0x4ee
math/big.nat.divRecursiveStep(0xc000098a80, 0x64, 0x68, 0xc0000c8570, 0x65, 0x9c, 0xc0000b5688, 0x33, 0xff, 0x1, ...)
	/root/.go/src/math/big/nat.go:840 +0x12c2
math/big.nat.divRecursiveStep(0xc0000b4a80, 0xe2, 0x146, 0xc0000c8000, 0x145, 0x14a, 0xc0000b5500, 0x64, 0x130, 0x0, ...)
	/root/.go/src/math/big/nat.go:880 +0x796
math/big.nat.divRecursive(0xc0000b4a80, 0xe2, 0x146, 0xc0000c8000, 0x146, 0x14a, 0xc0000b5500, 0x64, 0x130)
	/root/.go/src/math/big/nat.go:821 +0x17e
math/big.nat.divLarge(0xc0000b4a80, 0x145, 0x146, 0x0, 0x0, 0x0, 0xc0000b4a80, 0x145, 0x146, 0xc0000c2000, ...)
	/root/.go/src/math/big/nat.go:727 +0x3fd
math/big.nat.div(0xc0000b4a80, 0x145, 0x146, 0x0, 0x0, 0x0, 0xc0000b4a80, 0x145, 0x146, 0xc0000c2000, ...)
	/root/.go/src/math/big/nat.go:672 +0x401
math/big.(*Float).uquo(0xc0000621b0, 0xc0000621b0, 0xc000049de8)
	/root/.go/src/math/big/float.go:1358 +0xd5
math/big.(*Float).Quo(0xc0000621b0, 0xc0000621b0, 0xc00006cde8, 0x15)
	/root/.go/src/math/big/float.go:1638 +0xbf
math/big.(*Float).scan(0xc0000621b0, 0x4f97a0, 0xc00000c060, 0xa, 0x590800, 0x7f348642f108, 0x0, 0x1)
	/root/.go/src/math/big/floatconv.go:143 +0x2f0
math/big.(*Float).Parse(0xc0000621b0, 0x4e13c6, 0x1881, 0xa, 0x4008000000000000, 0xc000062180, 0xc00006cf18, 0x4a83c5)
	/root/.go/src/math/big/floatconv.go:273 +0x1a5
math/big.ParseFloat(0x4e13c6, 0x1881, 0xa, 0x1881, 0x57ac02, 0xc000038778, 0xc00006cf78, 0x40514f, 0xc0000260b8)
	/root/.go/src/math/big/floatconv.go:290 +0x81
main.main()
	/src/fuzz/lol.go:14 +0x51
exit status 2

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (14 by maintainers)

Most upvoted comments

Thanks for reporting this issue.

This is a Go1.14 regression, introduced by CL 172018 (math/big: implement recursive algorithm for division).

cc @remyoudompheng @griesemer