]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/internal/atomic: fix wasm's StorepNoWB implementation
authorMatthew Dempsky <mdempsky@google.com>
Tue, 2 Apr 2019 21:14:51 +0000 (14:14 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 2 Apr 2019 21:42:07 +0000 (21:42 +0000)
Package unsafe's safety rules require that pointers converted to
uintptr must be converted back to pointer-type before being stored
into memory. In particular, storing a pointer into a non-pointer-typed
expression does not guarantee the pointer stays valid, even if the
expression refers to a pointer-typed variable.

wasm's StorepNoWB implementation violates these rules by storing a
pointer through a uintptr-typed expression.

This happens to work today because esc.go is lenient in its
implementation of package unsafe's rules, but my escape analysis
rewrite follows them more rigorously, which causes val to be treated
as a non-leaking parameter.

This CL fixes the issue by using a *T-typed expression, where T is
marked //go:notinheap so that the compiler still omits the write
barrier as appropriate.

Updates #23109.

Change-Id: I49bc5474dbaa95729e5c93201493afe692591bc8
Reviewed-on: https://go-review.googlesource.com/c/go/+/170323
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/runtime/internal/atomic/atomic_wasm.go

index 71288e9003dce44ff6b4ff220c2001e3388ded91..9c2193fa1b76a6953d7ec41f59b38134c3b9ad4f 100644 (file)
@@ -123,10 +123,13 @@ func Store64(ptr *uint64, val uint64) {
        *ptr = val
 }
 
+//go:notinheap
+type noWB struct{}
+
 //go:noinline
 //go:nosplit
 func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) {
-       *(*uintptr)(ptr) = uintptr(val)
+       *(**noWB)(ptr) = (*noWB)(val)
 }
 
 //go:nosplit