Text file
talks/2014/playground.slide
1 Inside the Go playground
2
3 Francesc Campoy Flores
4 Developer Advocate, Gopher
5 @francesc
6 campoy@golang.org
7 http://campoy.cat
8
9 * Agenda
10
11 - What is the Go playground
12
13 - What could go wrong
14
15 - What did we do to avoid it
16
17 - An animated ASCII train
18
19 * The Go playground
20
21 .image playground/img/play.png 500 _
22 .caption [[/play/][go.dev/play]]
23
24 * De facto pastebin of the Go community
25
26 .image playground/img/share.png 500 _
27 .caption [[/play/p/bJYnajZ6Kp][go.dev/play/p/bJYnajZ6Kp]]
28
29 * The Go tour
30
31 .image playground/img/tour.png 500 _
32 .caption [[/tour/][go.dev/tour]]
33
34 * Executable examples on documentation
35
36 .image playground/img/examples.png 500 _
37 .caption [[/pkg/strings/#example_Fields][go.dev/pkg/strings]]
38
39 * Executable code on blog posts
40
41 .image playground/img/blog.png 500 _
42 .caption [[/blog/slices][go.dev/blog/slices]]
43
44 * Executable slides
45
46 .play playground/hello.go
47
48 These slides are driven by the `present` Go tool
49
50 go get code.google.com/go.tools/cmd/present
51
52 * Naive implementation
53
54 * Architecture
55
56 .image playground/img/arch.png 500 _
57
58 * Backend
59
60 Let's start with something simple
61
62 - receive code
63 - compile it
64 - run it
65
66 * What could go wrong?
67
68 .image playground/img/areyousure.png 500 _
69
70 ###########
71 ## Issues #
72 ###########
73
74 * Resource exhaustion
75
76 * Exhausting memory on the stack
77
78 `stack`overflow`
79
80 .play playground/stack.go
81
82 The runtime catches the error and panics.
83
84 * Too much memory on the heap
85
86 `out`of`memory`
87
88 .play playground/heap.go
89
90 Again the runtime catches the error and panics.
91
92 * Too much CPU time
93
94 .play playground/loop.go
95
96 * Stealing resources by sleeping
97
98 .play playground/sleep.go
99
100 A sleeping program still consumes resources.
101
102 Easy way of having a Denial of Service attack.
103
104 * Accessing things you shouldn't
105
106 * File system access
107
108 User code shouldn't be able to modify the backend's file system.
109
110 - Reading sensitive information
111
112 - Installing backdoors
113
114 - General mayhem
115
116 .play playground/removeall.go /func main/,/^}/
117
118 * Network access
119
120 .play playground/http.go /func main/,/^}/
121
122 * Use your imagination
123
124 .image playground/img/cat.jpg 500 _
125
126 ###################
127 # Countermeasures #
128 ###################
129
130 * Countermeasures
131
132 * Restricting resource usage with ulimit
133
134 Default limits are not safe enough.
135
136 `ulimit` could solve this.
137
138 -d maximum size of data segment or heap (in kbytes)
139
140 -s maximum size of stack segment (in kbytes)
141
142 -t maximum CPU time (in seconds)
143
144 -v maximum size of virtual memory (in kbytes)
145
146 * Native Client
147
148 Originally designed to execute native code in Chrome safely.
149
150 NaCl defines restrictions on the binaries being executed.
151
152 The code runs in a sandbox isolated from the underlying OS.
153
154 - No file access
155 - No network access
156
157 .image playground/img/nacl.png 300 _
158
159 * Isolating process execution with NaCl
160
161 We use NaCl to:
162
163 - limit CPU time
164
165 - limit memory
166
167 - isolate from the filesystem
168
169 - isolate from the network
170
171 Process can only write to stdout/stderr.
172
173 * Limiting user time
174
175 "No sleeping in the playground."
176
177 Custom runtime with a fake `time` package.
178
179 func Sleep(d time.Duration) {
180 panic("No sleeping in the playground")
181 }
182
183 * Restoring functionality
184
185 * Faking the file system
186
187 The `syscall` package is the only link between user code and the OS kernel.
188
189 The playground runtime has a custom `syscall` package.
190
191 File system operations operate on a fake in-memory file system.
192
193 .play playground/file.go /func main/,
194
195 * Faking the network
196
197 All network operations also use the `syscall` package.
198
199 The network stack is also faked in-memory.
200
201 .play playground/net.go /func main/,/^}/
202
203 * Faking the network (continued)
204
205 .play playground/net.go /func dial/,/^}/
206
207 ##########
208 ## TIME ##
209 ##########
210
211 * Sleeping in the playground
212
213 Go is about concurrency.
214
215 We need to demonstrate concurrency in blog posts and talks.
216
217 And demonstrating concurrency without `time` is hard.
218
219 * What to do if an open source project lacks a feature?
220
221 .image playground/img/gopherbw.png 500 _
222
223 * File a bug!
224
225 .image playground/img/bug.png 500 _
226 .caption [[https://code.google.com/p/go/issues/detail?id=4280][bug 4280]]
227
228 * Normal behavior
229
230 There's a special goroutine managing timers `T`.
231
232 A goroutine `G` calls `time.Sleep`:
233
234 1. `G` adds a timer to the timer heap.
235
236 2. `G` puts itself to sleep.
237
238 3. `T` tells the OS to wake it when the next timer expires and puts itself to sleep.
239
240 4. When `T` is woken up it looks at the timer on the top of the heap, and wakes the corresponding goroutine.
241
242 * Intermission: deadlocks
243
244 .play playground/deadlock.go
245
246 Many flavors of deadlocks.
247
248 One common property: all goroutines are asleep.
249
250 * New behavior
251
252 A goroutine `G` calls `time.Sleep`:
253
254 1. `G` adds a timer to the timer heap.
255
256 2. `G` puts itself to sleep.
257
258 3. The scheduler detects a deadlock, checks the timer heap for pending timers.
259
260 4. The internal clock is advanced to the next timer expiration.
261
262 5. The corresponding goroutines are woken up.
263
264 * Sleeping fast
265
266 Faking time allows precise sleep durations.
267
268 .play playground/sleepfast.go
269
270 * So there's no actual sleep?
271
272 The playground's `write` syscall inserts a timestamp before each write.
273
274 The front end translates that into a series of "events" that the browser can play back.
275
276 .play playground/sleep.go /func main/,
277
278 Returns directly
279
280 {
281 "Errors":"",
282 "Events":[
283 {"Message":"Good night\n","Delay":0},
284 {"Message":"Good morning\n","Delay":28800000000000}
285 ]
286 }
287
288 * So the bug was fixed
289
290 .image playground/img/andrew.png _ 1000
291 .caption [[/play/p/3fv0L3-z0s][go.dev/play/p/3fv0L3-z0s]]
292
293 * And people were happy
294
295 .image playground/img/brad.png _ 1000
296 .caption [[/play/p/rX_3WcpUOZ][go.dev/play/p/rX_3WcpUOZ]]
297
298 * Very happy
299
300 .image playground/img/jan.png _ 1000
301 .caption [[/play/p/P-Dk0NH_vf][go.dev/play/p/P-Dk0NH_vf]]
302
303 .image playground/img/mattn.png _ 1000
304 .caption [[/play/p/NOycgN2i6b][go.dev/play/p/NOycgN2i6b]]
305
306 * References
307
308 These slides: [[/talks/2014/playground.slide]]
309
310 More about the Go tour:
311
312 - Inside the Go playground: [[/blog/playground][go.dev/blog/playground]]
313
314 - The Go tour: [[/tour/][go.dev/tour]]
315
316 More about Go on NaCl:
317
318 - Running Go under Native Client: [[https://code.google.com/p/go-wiki/wiki/NativeClient]]
319
320 - Go 1.3 Native Client Support: [[/s/go13nacl]]
321
View as plain text