Skip to content

Commit a718f93

Browse files
cherrymuiianlancetaylor
authored andcommitted
[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 dca707b) 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>
1 parent da1f5d3 commit a718f93

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ func symIsRO(sym interface{}) bool {
11411141
// read8 reads one byte from the read-only global sym at offset off.
11421142
func read8(sym interface{}, off int64) uint8 {
11431143
lsym := sym.(*obj.LSym)
1144-
if off >= int64(len(lsym.P)) {
1144+
if off >= int64(len(lsym.P)) || off < 0 {
11451145
// Invalid index into the global sym.
11461146
// This can happen in dead code, so we don't want to panic.
11471147
// Just return any value, it will eventually get ignored.
@@ -1154,7 +1154,7 @@ func read8(sym interface{}, off int64) uint8 {
11541154
// read16 reads two bytes from the read-only global sym at offset off.
11551155
func read16(sym interface{}, off int64, bigEndian bool) uint16 {
11561156
lsym := sym.(*obj.LSym)
1157-
if off >= int64(len(lsym.P))-1 {
1157+
if off >= int64(len(lsym.P))-1 || off < 0 {
11581158
return 0
11591159
}
11601160
if bigEndian {
@@ -1167,7 +1167,7 @@ func read16(sym interface{}, off int64, bigEndian bool) uint16 {
11671167
// read32 reads four bytes from the read-only global sym at offset off.
11681168
func read32(sym interface{}, off int64, bigEndian bool) uint32 {
11691169
lsym := sym.(*obj.LSym)
1170-
if off >= int64(len(lsym.P))-3 {
1170+
if off >= int64(len(lsym.P))-3 || off < 0 {
11711171
return 0
11721172
}
11731173
if bigEndian {
@@ -1180,7 +1180,7 @@ func read32(sym interface{}, off int64, bigEndian bool) uint32 {
11801180
// read64 reads eight bytes from the read-only global sym at offset off.
11811181
func read64(sym interface{}, off int64, bigEndian bool) uint64 {
11821182
lsym := sym.(*obj.LSym)
1183-
if off >= int64(len(lsym.P))-7 {
1183+
if off >= int64(len(lsym.P))-7 || off < 0 {
11841184
return 0
11851185
}
11861186
if bigEndian {

test/fixedbugs/issue29215.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,20 @@ func f() {
1616
}
1717
_ = s == "bbb"
1818
}
19+
20+
// Another case: load from negative offset of a symbol
21+
// in dead code (issue 30257).
22+
func g() {
23+
var i int
24+
var s string
25+
26+
if true {
27+
s = "a"
28+
}
29+
30+
if f := 0.0; -f < 0 {
31+
i = len(s[:4])
32+
}
33+
34+
_ = s[i-1:0] != "bb" && true
35+
}

0 commit comments

Comments
 (0)