Commit dc72a2f9 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: detect unsafe conversions from smaller to larger types

This CL extends the runtime instrumentation for (*T)(ptr) to also
check that the first and last bytes of *(*T)(ptr) are part of the same
heap object.

Updates #22218.
Updates #34959.

Change-Id: I2c8063fe1b7fe6e6145e41c5654cb64dd1c9dd41
Reviewed-on: https://go-review.googlesource.com/c/go/+/201778
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
Reviewed-by: default avatarCuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4edd78d9
...@@ -3910,7 +3910,7 @@ func isRuneCount(n *Node) bool { ...@@ -3910,7 +3910,7 @@ func isRuneCount(n *Node) bool {
} }
func walkCheckPtrAlignment(n *Node, init *Nodes) *Node { func walkCheckPtrAlignment(n *Node, init *Nodes) *Node {
if n.Type.Elem().Alignment() == 1 { if n.Type.Elem().Alignment() == 1 && n.Type.Elem().Size() == 1 {
return n return n
} }
......
...@@ -7,14 +7,20 @@ package runtime ...@@ -7,14 +7,20 @@ package runtime
import "unsafe" import "unsafe"
type ptrAlign struct { type ptrAlign struct {
ptr unsafe.Pointer ptr unsafe.Pointer
align uintptr elem *_type
} }
func checkptrAlignment(p unsafe.Pointer, elem *_type) { func checkptrAlignment(p unsafe.Pointer, elem *_type) {
// Check that (*T)(p) is appropriately aligned.
// TODO(mdempsky): What about fieldAlign? // TODO(mdempsky): What about fieldAlign?
if uintptr(p)&(uintptr(elem.align)-1) != 0 { if uintptr(p)&(uintptr(elem.align)-1) != 0 {
panic(ptrAlign{p, uintptr(elem.align)}) panic(ptrAlign{p, elem})
}
// Check that (*T)(p) doesn't straddle multiple heap objects.
if elem.size != 1 && checkptrBase(p) != checkptrBase(add(p, elem.size-1)) {
panic(ptrAlign{p, elem})
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment