diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-02-15 15:01:29 -0500 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-02-25 05:17:28 +0000 |
commit | a718f939d258f184709e95e581657fb8f1a6f8a8 (patch) | |
tree | 1d8d72d8c43947be97781686ee057831e5e9c3ea | |
parent | da1f5d376a74dc75b641ae0beb4b98519d57c59a (diff) | |
download | go-a718f939d258f184709e95e581657fb8f1a6f8a8.tar.gz go-a718f939d258f184709e95e581657fb8f1a6f8a8.zip |
[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 <khr@golang.org>
(cherry picked from commit dca707b2a040642bb46aa4da4fb4eb6188cc2502)
Reviewed-on: https://go-review.googlesource.com/c/162827
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r-- | src/cmd/compile/internal/ssa/rewrite.go | 8 | ||||
-rw-r--r-- | test/fixedbugs/issue29215.go | 17 |
2 files changed, 21 insertions, 4 deletions
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 +} |