github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2014/playground.slide (about) 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 [[http://play.golang.org][play.golang.org]] 23 24 * De facto pastebin of the Go community 25 26 .image playground/img/share.png 500 _ 27 .caption [[http://play.golang.org/p/bJYnajZ6Kp]] 28 29 * The Go tour 30 31 .image playground/img/tour.png 500 _ 32 .caption [[http://tour.golang.org][tour.golang.org]] 33 34 * Executable examples on documentation 35 36 .image playground/img/examples.png 500 _ 37 .caption [[http://golang.org/pkg/strings/#example_Fields][golang.org/pkg/strings]] 38 39 * Executable code on blog posts 40 41 .image playground/img/blog.png 500 _ 42 .caption [[http://blog.golang.org/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 [[http://play.golang.org/p/3fv0L3-z0s]] 292 293 * And people were happy 294 295 .image playground/img/brad.png _ 1000 296 .caption [[http://play.golang.org/p/rX_3WcpUOZ]] 297 298 * Very happy 299 300 .image playground/img/jan.png _ 1000 301 .caption [[http://play.golang.org/p/P-Dk0NH_vf]] 302 303 .image playground/img/mattn.png _ 1000 304 .caption [[http://play.golang.org/p/NOycgN2i6b]] 305 306 * References 307 308 These slides: [[http://talks.golang.org/2014/playground.slide]] 309 310 More about the Go tour: 311 312 - Inside the Go playground: [[http://blog.golang.org/playground]] 313 314 - The Go tour: [[http://tour.golang.org]] 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: [[http://golang.org/s/go13nacl]]