]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix crash when memmove argument is not the right type
authorKeith Randall <keithr@alum.mit.edu>
Fri, 1 Feb 2019 23:27:53 +0000 (15:27 -0800)
committerKeith Randall <khr@golang.org>
Fri, 1 Feb 2019 23:43:09 +0000 (23:43 +0000)
Make sure the argument to memmove is of pointer type before we try to
get the element type.

This has been noticed for code that uses unsafe+linkname so it can
call runtime.memmove. Probably not the best thing to allow, but the
code is out there and we'd rather not break it unnecessarily.

Fixes #30061

Change-Id: I334a8453f2e293959fd742044c43fbe93f0b3d31
Reviewed-on: https://go-review.googlesource.com/c/160826
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/fixedbugs/issue30061.go [new file with mode: 0644]

index 89fbfdc6bd76fe614ef8e0925880e929737c7df0..61451891a57e22edc44377beab8cf415d40267c4 100644 (file)
 // Inline small or disjoint runtime.memmove calls with constant length.
 (StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem))))
        && isSameSym(sym,"runtime.memmove")
+       && t.(*types.Type).IsPtr() // avoids TUINTPTR, see issue 30061
        && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
        && isInlinableMemmove(dst,src,sz,config)
        && clobber(s1) && clobber(s2) && clobber(s3)
index 79f0fd434aee2bb8cd5a00d6688fcbe03b8e0463..f2c7529e024f7dd226f4f825805d982063012d09 100644 (file)
@@ -27397,7 +27397,7 @@ func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
        config := b.Func.Config
        _ = config
        // match: (StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
-       // cond: isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
+       // cond: isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
        // result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
        for {
                sym := v.Aux
@@ -27425,7 +27425,7 @@ func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
                _ = s3.Args[2]
                dst := s3.Args[1]
                mem := s3.Args[2]
-               if !(isSameSym(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
+               if !(isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
                        break
                }
                v.reset(OpMove)
@@ -27437,7 +27437,7 @@ func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
                return true
        }
        // match: (StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem))))
-       // cond: isSameSym(sym,"runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
+       // cond: isSameSym(sym,"runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst,src,sz,config) && clobber(s1) && clobber(s2) && clobber(s3)
        // result: (Move {t.(*types.Type).Elem()} [sz] dst src mem)
        for {
                sym := v.Aux
@@ -27465,7 +27465,7 @@ func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
                _ = s3.Args[2]
                dst := s3.Args[1]
                mem := s3.Args[2]
-               if !(isSameSym(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
+               if !(isSameSym(sym, "runtime.memmove") && t.(*types.Type).IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, sz, config) && clobber(s1) && clobber(s2) && clobber(s3)) {
                        break
                }
                v.reset(OpMove)
diff --git a/test/fixedbugs/issue30061.go b/test/fixedbugs/issue30061.go
new file mode 100644 (file)
index 0000000..5092b01
--- /dev/null
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure we can linkname to memmove with an unsafe.Pointer argument.
+
+package p
+
+import "unsafe"
+
+//go:linkname memmove runtime.memmove
+func memmove(to, from unsafe.Pointer, n uintptr)
+
+var V1, V2 int
+
+func F() {
+       memmove(unsafe.Pointer(&V1), unsafe.Pointer(&V2), unsafe.Sizeof(int(0)))
+}