aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-02-15 15:01:29 -0500
committerIan Lance Taylor <iant@golang.org>2019-02-25 05:17:28 +0000
commita718f939d258f184709e95e581657fb8f1a6f8a8 (patch)
tree1d8d72d8c43947be97781686ee057831e5e9c3ea
parentda1f5d376a74dc75b641ae0beb4b98519d57c59a (diff)
downloadgo-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.go8
-rw-r--r--test/fixedbugs/issue29215.go17
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
+}