github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/gohacks/gohacks_test.go (about) 1 // Copyright 2021 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gohacks 16 17 import ( 18 "io/ioutil" 19 "math/rand" 20 "os" 21 "runtime/debug" 22 "testing" 23 24 "golang.org/x/sys/unix" 25 ) 26 27 func randBuf(size int) []byte { 28 b := make([]byte, size) 29 for i := range b { 30 b[i] = byte(rand.Intn(256)) 31 } 32 return b 33 } 34 35 // Size of a page in bytes. Cloned from hostarch.PageSize to avoid a circular 36 // dependency. 37 const pageSize = 4096 38 39 func testCopy(dst, src []byte) (panicked bool) { 40 defer func() { 41 if r := recover(); r != nil { 42 panicked = true 43 } 44 }() 45 debug.SetPanicOnFault(true) 46 copy(dst, src) 47 return panicked 48 } 49 50 func TestSegVOnMemmove(t *testing.T) { 51 // Test that SIGSEGVs received by runtime.memmove when *not* doing 52 // CopyIn or CopyOut work gets propagated to the runtime. 53 const bufLen = pageSize 54 a, err := unix.Mmap(-1, 0, bufLen, unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE) 55 if err != nil { 56 t.Fatalf("Mmap failed: %v", err) 57 58 } 59 defer unix.Munmap(a) 60 b := randBuf(bufLen) 61 62 if !testCopy(b, a) { 63 t.Fatalf("testCopy didn't panic when it should have") 64 } 65 66 if !testCopy(a, b) { 67 t.Fatalf("testCopy didn't panic when it should have") 68 } 69 } 70 71 func TestSigbusOnMemmove(t *testing.T) { 72 // Test that SIGBUS received by runtime.memmove when *not* doing 73 // CopyIn or CopyOut work gets propagated to the runtime. 74 const bufLen = pageSize 75 f, err := ioutil.TempFile("", "sigbus_test") 76 if err != nil { 77 t.Fatalf("TempFile failed: %v", err) 78 } 79 os.Remove(f.Name()) 80 defer f.Close() 81 82 a, err := unix.Mmap(int(f.Fd()), 0, bufLen, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED) 83 if err != nil { 84 t.Fatalf("Mmap failed: %v", err) 85 86 } 87 defer unix.Munmap(a) 88 b := randBuf(bufLen) 89 90 if !testCopy(b, a) { 91 t.Fatalf("testCopy didn't panic when it should have") 92 } 93 94 if !testCopy(a, b) { 95 t.Fatalf("testCopy didn't panic when it should have") 96 } 97 }