1
2
3
4
5 package main
6
7 import (
8 "bytes"
9 "fmt"
10 "os"
11 "runtime"
12 "runtime/debug"
13 "runtime/secret"
14 "sync"
15 "syscall"
16 "time"
17 _ "unsafe"
18 "weak"
19 )
20
21
22 var secretStore = [8]byte{
23 0x00,
24 0x81,
25 0xa0,
26 0xc6,
27 0xb3,
28 0x01,
29 0x66,
30 0x53,
31 }
32
33 func main() {
34 enableCore()
35 useSecretProc()
36
37
38
39 clear(secretStore[:])
40 panic("terminate")
41 }
42
43
44 func enableCore() {
45 debug.SetTraceback("crash")
46
47 var lim syscall.Rlimit
48 err := syscall.Getrlimit(syscall.RLIMIT_CORE, &lim)
49 if err != nil {
50 panic(fmt.Sprintf("error getting rlimit: %v", err))
51 }
52 lim.Cur = lim.Max
53 fmt.Fprintf(os.Stderr, "Setting RLIMIT_CORE = %+#v\n", lim)
54 err = syscall.Setrlimit(syscall.RLIMIT_CORE, &lim)
55 if err != nil {
56 panic(fmt.Sprintf("error setting rlimit: %v", err))
57 }
58 }
59
60
61
62 func useSecretProc() {
63 stop := make(chan bool)
64 var wg sync.WaitGroup
65
66 for i := 0; i < 4; i++ {
67 wg.Add(1)
68 go func() {
69 time.Sleep(1 * time.Second)
70 for {
71 select {
72 case <-stop:
73 wg.Done()
74 return
75 default:
76 secret.Do(func() {
77
78
79
80
81
82 s := bytes.Repeat(secretStore[:], 1+i*2)
83
84 useSecret(s)
85 })
86 }
87 }
88 }()
89 }
90
91
92
93
94 c := make(chan []byte)
95 wg.Add(2)
96 go func() {
97 for {
98 select {
99 case <-stop:
100 wg.Done()
101 return
102 case c <- make([]byte, 256):
103 }
104 }
105 }()
106 go func() {
107 for {
108 select {
109 case <-stop:
110 wg.Done()
111 return
112 case <-c:
113 }
114 }
115 }()
116
117 time.Sleep(5 * time.Second)
118 close(stop)
119 wg.Wait()
120
121
122 w := weak.Make(new([2048]byte))
123
124 for i := 0; i < 20; i++ {
125 runtime.GC()
126 if w.Value() == nil {
127 fmt.Fprintf(os.Stderr, "number of GCs %v\n", i+1)
128 return
129 }
130 }
131 fmt.Fprintf(os.Stderr, "GC didn't clear out in time\n")
132
133
134 panic("fault")
135 }
136
View as plain text