From: Cherry Zhang Date: Fri, 15 Feb 2019 20:01:29 +0000 (-0500) Subject: [release-branch.go1.12] cmd/compile: guard against loads with negative offset from... X-Git-Tag: go1.12~5 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a718f939d258f184709e95e581657fb8f1a6f8a8;p=gostls13.git [release-branch.go1.12] cmd/compile: guard against loads with negative offset from readonly constants CL 154057 adds guards agaist out-of-bound reads from readonly constants. It turns out that in dead code, the offset can also be negative. Guard against negative offset as well. Fixes #30257. Change-Id: I47c2a2e434dd466c08ae6f50f213999a358c796e Reviewed-on: https://go-review.googlesource.com/c/162819 Reviewed-by: Keith Randall (cherry picked from commit dca707b2a040642bb46aa4da4fb4eb6188cc2502) Reviewed-on: https://go-review.googlesource.com/c/162827 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index a154249371..65d5098f89 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -1141,7 +1141,7 @@ func symIsRO(sym interface{}) bool { // read8 reads one byte from the read-only global sym at offset off. func read8(sym interface{}, off int64) uint8 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P)) { + if off >= int64(len(lsym.P)) || off < 0 { // Invalid index into the global sym. // This can happen in dead code, so we don't want to panic. // Just return any value, it will eventually get ignored. @@ -1154,7 +1154,7 @@ func read8(sym interface{}, off int64) uint8 { // read16 reads two bytes from the read-only global sym at offset off. func read16(sym interface{}, off int64, bigEndian bool) uint16 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-1 { + if off >= int64(len(lsym.P))-1 || off < 0 { return 0 } if bigEndian { @@ -1167,7 +1167,7 @@ func read16(sym interface{}, off int64, bigEndian bool) uint16 { // read32 reads four bytes from the read-only global sym at offset off. func read32(sym interface{}, off int64, bigEndian bool) uint32 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-3 { + if off >= int64(len(lsym.P))-3 || off < 0 { return 0 } if bigEndian { @@ -1180,7 +1180,7 @@ func read32(sym interface{}, off int64, bigEndian bool) uint32 { // read64 reads eight bytes from the read-only global sym at offset off. func read64(sym interface{}, off int64, bigEndian bool) uint64 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-7 { + if off >= int64(len(lsym.P))-7 || off < 0 { return 0 } if bigEndian { diff --git a/test/fixedbugs/issue29215.go b/test/fixedbugs/issue29215.go index df703aa25d..4e8f107aee 100644 --- a/test/fixedbugs/issue29215.go +++ b/test/fixedbugs/issue29215.go @@ -16,3 +16,20 @@ func f() { } _ = s == "bbb" } + +// Another case: load from negative offset of a symbol +// in dead code (issue 30257). +func g() { + var i int + var s string + + if true { + s = "a" + } + + if f := 0.0; -f < 0 { + i = len(s[:4]) + } + + _ = s[i-1:0] != "bb" && true +}