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)
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