1 <title>Singularity
</title><h2>Singularity
</h2><b>Required reading
</b>:
<a href=
"readings/hunt07singularity.pdf">Singularity
</a><br><b>Useful reading
</b>:
<a href=
"readings/singularity-eurosys2006.pdf">Language support for message passing
</a><p><pre>
2 Singularity is a Microsoft Research experimental O/S
3 many people, many papers, reasonably high profile
4 choice of problems maybe influenced by msft experience w/ windows
5 we can speculate about influence on msft products
8 increase robustness, security
9 particularly w.r.t. extensions
10 decrease unexpected interactions
11 incorporate modern techniques
14 microkernel: kernel, processes, IPC
15 they claim to have factored services into user processes (page
5)
16 NIC, TCP/IP, FS, disk driver (sealing paper)
17 kernel: processes, memory, some IPC, nameserver
18 UNIX compatibility is not a goal, so avoiding some Mach pitfalls
19 on the other hand there are
192 system calls (page
5)
21 Most radical part of design:
22 Only one address space (paging turned off, no use of segments)
23 kernel and all processes
24 User processes run w/ full h/w privs (CPL=
0)
28 Fast process switching: no page table switch
29 Fast system calls: CALL not INT
31 Direct user program access to h/w, for e.g. device drivers
32 Table
1 shows they are a lot faster at microbenchmarks
34 But their main goal wasn't performance!
35 robustness, security, interactions
37 Is *not* using pagetable protection consistent w/ goal of robustness?
38 unreliability comes from *extensions*
39 browser plug-ins, loadable kernel modules, &c
40 typically loaded into host program's address space
41 for speed and convenience
42 so VM h/w already not relevant
43 can we just do without hardware protection?
45 How would an extension work in Singularity?
46 e.g. device driver, new network protocol, browser plug-in
47 Separate process, communicate w/ host process via IPC
49 What do we think the challenges will be for single address space?
50 Prevent evil or buggy programs from writing each other or kernel
51 Support kill and exit -- avoid entangling
53 general SIP philosophy:
55 No modification from outside:
56 none of JOS calls that take target envid argument (except start/stop)
59 No modification from within:
60 no JIT, no class loader, no dynamically loaded libraries
63 only pointers to your own data
64 no pointers to other SIP data or into kernel
65 thus no sharing despite shared address space!
66 limited exception for IPC messages in exchange heap
67 SIP can allocate pages of memory from kernel
68 different allocations are not contiguous
70 Why so crucial that SIPs can't be modified? Can't even modify themselves?
71 What are the benefits?
72 no code insertion attacks
73 probably easier to reason about correctness
74 probably easier to optimize, inline
75 e.g. delete unused functions
76 SIP can be a security principle, own files
79 Why not like Java VM, can share all data?
80 SIPs rule out all inter-process interactions
81 except explicit via IPC
83 SIPs let every process have its own language run-time, GC scheme, &c
84 though they are trusted and better not have bugs
85 equivalent in sensitivity to kernel code
86 so will be much harder for people to cook up their own
87 SIPs make it easy for kernel to clean up after kill or exit
89 How to keep SIPs from reading/writing other SIPs?
90 Only read/write memory the kernel has given you
91 Have compiler generate code to check every access?
92 "does this point to memory the kernel gave us?"
93 Would slow code down (esp since mem isn't contig)
94 We don't trust compiler
96 Why the overall structure:
97 1. compile to bytecodes
98 2. verify bytecodes during install
99 3. compile bytecodes -
> machine code during install
100 4. run the verified machine code w/ trusted runtime
101 Why not compile to machine code?
102 Why not JIT at run time?
103 Why not verify at compile time?
104 Why not verify at run time?
106 What does bytecode verification buy Singularity?
107 Does it verify
"only r/w memory kernel gave us"?
108 Not exactly, but related:
109 Only use reachable pointers [draw diagram]
110 Cannot create a new pointer
111 only trusted runtime can create pointers
112 So if kernel/runtime never supply out-of-SIP pointers
113 verified SIP can only use its own memory
114 What does the verifier have to check to establish that?
115 A. Don't cook up pointers (only use pointers someone gives you)
116 B. Don't change mind about type
117 Would allow violation of A, e.g. interpret int as pointer
118 C. Don't use after free
119 Re-use might change type, violate B
120 Enforced with GC (and exchange heap linearity)
121 D. Don't use uninitialized variables
122 D. In general, don't trick the verifier
133 last mov is OK if via
1st jmp (assuming ptr legitimate)
134 reads first element of SomeClass
135 not OK if via
2nd jmp
136 0x1000 may point into kernel
137 verifier tries to deduce type for every register
138 by pretending to execute along each code path
139 requires that all paths to a reg use result in same type
140 check that all reg uses OK for type
141 would decide R0 has type int, or type SomeClass *
142 either way, verifier would say
"no"
144 Bytecode verification seems to do *more* than Singularity needs
145 e.g. cooking up pointers might be OK, as long as within SIP's memory
146 verifier may forbid some programs that might have been OK on Singularity
147 Benefits of full verification:
148 Fast execution, often don't need runtime checks at all
149 Though some still needed: array bounds, OO casts, stack expansion
151 Need to allow r/w of exchange heap, but it is not SIP's memory
152 Stack page allocation
153 Do sys calls run on stack in SIP's memory?
154 prevent thread X from wrecking thread Y's kernel syscall stack
156 You could put an interpreter in a SIP to evade ban on self-modifying code
157 Would that cause trouble?
159 What parts are trusted vs untrusted?
162 Trusted s/w: if it has bugs, it can crash Singularity or wreck other SIPs
163 Untrusted s/w: if it has bugs, can only wreck itself
164 Let's consider some ordinary app, not a server.
165 compiler. compiler output. verifier. verifier output. GC.
167 Paper also talks about IPC
168 How do SIPs communicate?
170 recv endpoint is a queue of messages
171 message bodies are in
"exchange heap"
174 Exchange heap is shared memory!
175 What are the dangers?
176 send the wrong type of data
177 modify my msg to you while you are using it
178 modify a totally unrelated message
179 use up all exchange heap memory and don't free
181 How do they prevent abuse via exchange heap?
182 verifier ensures SIP bytecodes keep only one ptr to anything in exchange heap
184 and that SIP doesn't keep ptr after send()
185 single-ptr rule helps here
186 verifier knows when last ptr goes away
188 via making another exchange heap obj point to it
190 single ptr rule prevents change-after-send
191 and also ensures delete when done
192 delete is explicit, no GC, but it's OK
193 since verifier guarantees only a single ptr to each block
194 runtime maintains owning-SIP entry in each exchg heap block
196 used to clean up in exit()
198 What are channel contracts for?
199 Are they just nice to have, or do other parts of Singularity rely on them?
200 The type signatures clearly are important.
201 bytecode verifier (or something similar) must check them.
202 The state machine part guarantees finite queues, no blocking send().
203 and also catches protocol implementation errors
204 e.g. sending msg when not expected
206 How does receive work?
207 checks endpoints in shared mem, block on condition variable if no msgs
208 so send must do a wakeup syscall
210 How do system calls into the kernel work?
213 since same stack, how does GC know?
214 can a SIP pass pointers to kernel?
216 Endpoints function as capabilities
218 Can't talk to other SIPs w/o a channel
219 Page
5 says they use channels to restrict access to e.g. files
221 Does evaluation support their claims?
223 Good model for extensions?
225 e.g. real win from single address space, cheap syscall, switch, IPC
226 Table
1, but only microbenchmarks
227 Figure
5: unsafe code tax
228 physical memory -- means paging disabled -- is this Singularity?
229 Add
4KB pages -- means turn on paging, but single page table, all CPL=
0
230 separate domain -- separate page table for one of the SIPs, so switching costs
231 ring
3 -- CPL=
3 thus INT costs (for just one of the SIPs)
232 full microkernel -- pgtable+INT for each of three SIPs