aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2025-07-29 18:45:23 +0700
committerGopher Robot <gobot@golang.org>2025-08-05 08:28:50 -0700
commit5ab9f23977694ab87614fd30e081d294eb313efd (patch)
tree3702479ac75143397f09baa0c3fcdfa63231f146 /src
parentfcc036f03b07e58f76ed94bc9a9483ddef96f81c (diff)
downloadgo-5ab9f23977694ab87614fd30e081d294eb313efd.tar.xz
cmd/compile, runtime: add checkptr instrumentation for unsafe.Add
Fixes #74431 Change-Id: Id651ea0b82599ccaff8816af0a56ddbb149b6f89 Reviewed-on: https://go-review.googlesource.com/c/go/+/692015 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: t hepudds <thepudds1460@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/walk/expr.go8
-rw-r--r--src/runtime/checkptr_test.go1
-rw-r--r--src/runtime/testdata/testprog/checkptr.go6
3 files changed, 15 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index fbfc56a39c..b9e226b207 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -131,6 +131,14 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
n := n.(*ir.BinaryExpr)
n.X = walkExpr(n.X, init)
n.Y = walkExpr(n.Y, init)
+ if n.Op() == ir.OUNSAFEADD && ir.ShouldCheckPtr(ir.CurFunc, 1) {
+ // For unsafe.Add(p, n), just walk "unsafe.Pointer(uintptr(p)+uintptr(n))"
+ // for the side effects of validating unsafe.Pointer rules.
+ x := typecheck.ConvNop(n.X, types.Types[types.TUINTPTR])
+ y := typecheck.Conv(n.Y, types.Types[types.TUINTPTR])
+ conv := typecheck.ConvNop(ir.NewBinaryExpr(n.Pos(), ir.OADD, x, y), types.Types[types.TUNSAFEPTR])
+ walkExpr(conv, init)
+ }
return n
case ir.OUNSAFESLICE:
diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
index 811c0f0355..119708be7f 100644
--- a/src/runtime/checkptr_test.go
+++ b/src/runtime/checkptr_test.go
@@ -35,6 +35,7 @@ func TestCheckPtr(t *testing.T) {
{"CheckPtrAlignmentNilPtr", ""},
{"CheckPtrArithmetic", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
{"CheckPtrArithmetic2", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
+ {"CheckPtrArithmeticUnsafeAdd", "fatal error: checkptr: pointer arithmetic result points to invalid allocation\n"},
{"CheckPtrSize", "fatal error: checkptr: converted pointer straddles multiple allocations\n"},
{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
{"CheckPtrSliceOK", ""},
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index 60e71e66d7..ff99fa8c7b 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -16,6 +16,7 @@ func init() {
register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr)
register("CheckPtrArithmetic", CheckPtrArithmetic)
register("CheckPtrArithmetic2", CheckPtrArithmetic2)
+ register("CheckPtrArithmeticUnsafeAdd", CheckPtrArithmeticUnsafeAdd)
register("CheckPtrSize", CheckPtrSize)
register("CheckPtrSmall", CheckPtrSmall)
register("CheckPtrSliceOK", CheckPtrSliceOK)
@@ -79,6 +80,11 @@ func CheckPtrArithmetic2() {
sink2 = unsafe.Pointer(uintptr(p) & ^one)
}
+func CheckPtrArithmeticUnsafeAdd() {
+ data := make([]byte, 128)
+ sink2 = (*byte)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(data)), len(data)))
+}
+
func CheckPtrSize() {
p := new(int64)
sink2 = p