]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile,runtime: panic when unsafe.Slice param is nil and > 0
authorcuiweixie <cuiweixie@gmail.com>
Mon, 8 Aug 2022 16:07:05 +0000 (16:07 +0000)
committerKeith Randall <khr@google.com>
Mon, 8 Aug 2022 16:37:49 +0000 (16:37 +0000)
Fixes #54092

Change-Id: Ib917922ed36ee5410e5515f812737203c44f46ae
GitHub-Last-Rev: dfd0c3883cf8b10479d9c5b389baa1a04c52dd34
GitHub-Pull-Request: golang/go#54107
Reviewed-on: https://go-review.googlesource.com/c/go/+/419755
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/walk/builtin.go
src/runtime/crash_test.go
src/runtime/slice.go
src/runtime/testdata/testprog/unsafe.go [new file with mode: 0644]

index 7e84f28217fd078ac63fbc3f96c1736efee773db..5a649c0951277ec8a5a791c2eb440ab9c6d2f6f4 100644 (file)
@@ -682,6 +682,25 @@ func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
                nif.Body.Append(mkcall("panicunsafeslicelen", nil, &nif.Body))
                appendWalkStmt(init, nif)
 
+               if sliceType.Elem().Size() == 0 {
+                       // if ptr == nil && len > 0  {
+                       //      panicunsafesliceptrnil()
+                       // }
+                       nifPtr := ir.NewIfStmt(base.Pos, nil, nil, nil)
+                       isNil := ir.NewBinaryExpr(base.Pos, ir.OEQ, unsafePtr, typecheck.NodNil())
+                       gtZero := ir.NewBinaryExpr(base.Pos, ir.OGT, typecheck.Conv(len, lenType), ir.NewInt(0))
+                       nifPtr.Cond =
+                               ir.NewLogicalExpr(base.Pos, ir.OANDAND, isNil, gtZero)
+                       nifPtr.Body.Append(mkcall("panicunsafeslicenilptr", nil, &nifPtr.Body))
+                       appendWalkStmt(init, nifPtr)
+
+                       h := ir.NewSliceHeaderExpr(n.Pos(), sliceType,
+                               typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
+                               typecheck.Conv(len, types.Types[types.TINT]),
+                               typecheck.Conv(len, types.Types[types.TINT]))
+                       return walkExpr(typecheck.Expr(h), init)
+               }
+
                // mem, overflow := runtime.mulUintptr(et.size, len)
                mem := typecheck.Temp(types.Types[types.TUINTPTR])
                overflow := typecheck.Temp(types.Types[types.TBOOL])
index 01d7cbeb2904b9ebcfda36978cf3b71bd883d8dc..02604595acb6dc1d5899a36c91728f9a57ec0cc8 100644 (file)
@@ -844,3 +844,11 @@ func TestPanicWhilePanicking(t *testing.T) {
                }
        }
 }
+
+func TestPanicOnUnsafeSlice(t *testing.T) {
+       output := runTestProg(t, "testprog", "panicOnNilAndEleSizeIsZero")
+       want := "panic: runtime error: unsafe.Slice: ptr is nil and len is not zero"
+       if !strings.Contains(output, want) {
+               t.Errorf("output does not contain %q:\n%s", want, output)
+       }
+}
\ No newline at end of file
index 2413a46d6a28fa49e5c44763db4e02cfc95f7a48..8a0ce49fad87ab03db493d91b4f78e8fd60e1842 100644 (file)
@@ -129,6 +129,12 @@ func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
                panicunsafeslicelen()
        }
 
+       if et.size == 0 {
+               if ptr == nil && len > 0  {
+                       panicunsafeslicenilptr()
+               }
+       }
+
        mem, overflow := math.MulUintptr(et.size, uintptr(len))
        if overflow || mem > -uintptr(ptr) {
                if ptr == nil {
diff --git a/src/runtime/testdata/testprog/unsafe.go b/src/runtime/testdata/testprog/unsafe.go
new file mode 100644 (file)
index 0000000..d6dddf2
--- /dev/null
@@ -0,0 +1,12 @@
+package main
+
+import "unsafe"
+
+func init() {
+       register("panicOnNilAndEleSizeIsZero", panicOnNilAndEleSizeIsZero)
+}
+
+func panicOnNilAndEleSizeIsZero() {
+       var p *struct{}
+       _ = unsafe.Slice(p, 5)
+}
\ No newline at end of file