]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.12] cmd/compile: guard against loads with negative offset from...
authorCherry Zhang <cherryyz@google.com>
Fri, 15 Feb 2019 20:01:29 +0000 (15:01 -0500)
committerIan Lance Taylor <iant@golang.org>
Mon, 25 Feb 2019 05:17:28 +0000 (05:17 +0000)
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>
src/cmd/compile/internal/ssa/rewrite.go
test/fixedbugs/issue29215.go

index a154249371a29117e4f429645895e07d9aa0fc65..65d5098f89a2eccb2cce9948e35f1e5bb9deff55 100644 (file)
@@ -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 {
index df703aa25d7e8e3ad3cf8c8338ab061f78d54c38..4e8f107aee585b7a6e87354ac7dcffbb96c43c79 100644 (file)
@@ -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
+}