aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental/webtry/DESIGN.md
blob: 66c7f1f7986537a33f4d099e8e1aab257756a6c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
Design
======


Overview
--------
Allows trying out Skia code in the browser.


Security
--------
We're putting a C++ compiler on the web, and promising to run the results of
user submitted code, so security is a large concern. Security is handled in a
layered approach, using a combination of seccomp-bpf, chroot jail and rlimits.

*seccomp-bpf* - Used to limit the types of system calls that the user code can
make. Any attempts to make a system call that isn't allowed causes the
application to terminate immediately.

*chroot jail* - The code is run in a chroot jail, making the rest of the
operating system files unreachable from the running code.

*rlimits* - Used to limit the resources the running code can get access to,
for example runtime is limited to 5s of CPU.

User submitted code is also restricted in the following ways:
  * Limited to 10K of code total.
  * No preprocessor use is allowed (no lines can begin with #includes).


Architecture
------------

The server runs on GCE, and consists of a Go Web Server that calls out to the
c++ compiler and executes code in a chroot jail. See the diagram below:

                             
     +–––––––––––––+         
     |             |         
     |  Browser    |         
     |             |         
     +––––––+––––––+         
            |                
     +––––––+––––––+         
     |             |         
     |             |         
     | Web Server  |         
     |             |         
     |   (Go)      |         
     |             |         
     |             |         
     +–––––––+–––––+         
             |               
     +–––––––+––––––––––+    
     | chroot jail      |    
     |  +––––––––––––––+|    
     |  | seccomp      ||    
     |  |  +––––––––––+||    
     |  |  |User code |||    
     |  |  |          |||    
     |  |  +––––––––––+||    
     |  +––––––––––––––+|    
     |                  |    
     +––––––––––––––––––+    
                             

The user code is expanded into a simple template and linked against libskia
and a couple other .o files that contain main() and the code that sets up the
seccomp and rlimit restrictions. This code also sets up the SkCanvas that is
handed to the user code. Any code the user submits is restricted to running in
a single function that looks like this:


    void draw(SkCanvas* canvas) {
      // User code goes here.
    }

The user code is tracked by taking an MD5 hash of the code The template is
expanded out into <hash>.cpp, which is compiled into <hash>.o, which is then
linked together with all the other libs and object files to create an
executable named <hash>.  That executable is copied into a directory
/home/webtry/inout, that is accessible to both the web server and the schroot
jail. The application is then run in the schroot jail, writing its response,
<hash>.png, out into the same directory, /home/webtry/inout/, where is it read
by the web server and returned to the user.

Startup and config
------------------
The server is started and stopped via:

    sudo /etc/init.d/webtry [start|stop|restart]

By sysv init only handles starting and stopping a program once, so we use
Monit to monitor the application and restart it if it crashes. The config
is in:

    /etc/monit/conf.d/webtry

The chroot jail is implemented using schroot, its configuration
file is found in:

    /etc/schroot/chroot.d/webtry

The seccomp configuration is in main.cpp and only allows the following system
calls:

    exit_group
    exit
    fstat
    read
    write
    close
    mmap
    munmap
    brk

Installation
------------
See the README file.