Verifying the seL4 Microkernel Formal Proof in Mathematics and - - PowerPoint PPT Presentation
Verifying the seL4 Microkernel Formal Proof in Mathematics and - - PowerPoint PPT Presentation
Verifying the seL4 Microkernel Formal Proof in Mathematics and Computer Science Lukas Stevens 21st June 2018 Outline 2. Design process of seL4 3. Formal methods of the correctness proof 4. Layers of the correctness proof 5. Conclusion 1 1.
Outline
- 1. What is a µ-kernel?
- 2. Design process of seL4
- 3. Formal methods of the correctness proof
- 4. Layers of the correctness proof
- 5. Conclusion
1
What is a µ-kernel?
What is a kernel anyway?
- Necessary abstractions for applications
- Interaction via system calls
- Loaded into protected memory region
Bugs are potentially fatal
2
What is a kernel anyway?
- Necessary abstractions for applications
- Interaction via system calls
- Loaded into protected memory region
Bugs are potentially fatal
2
What is a kernel anyway?
- Necessary abstractions for applications
- Interaction via system calls
- Loaded into protected memory region
Bugs are potentially fatal
2
What is a kernel anyway?
- Necessary abstractions for applications
- Interaction via system calls
- Loaded into protected memory region
Bugs are potentially fatal
2
What is a kernel anyway?
- Necessary abstractions for applications
- Interaction via system calls
- Loaded into protected memory region
⇒ Bugs are potentially fatal
2
Defjnition: Microkernel
A concept is tolerated inside the µ-kernel only if mov- ing it outside the kernel, i.e. permitting competing implementations, would prevent the implementation
- f the system’s required functionality.
— Jochen Liedtke
3
Monolithic kernels and µ-kernels
Device Drivers File System IPC, Virtual Memory, Scheduling etc. Basic IPC, Virtual Memory, Scheduling UNIX- Server Device Drivers File System Application IPC Applications Hardware Hardware
OS based on Monolithic Kernel OS based on Microkernel
Applications User Mode Kernel mode
4
The seL4 µ-kernel
- Member of the L4
- kernel family
- Correctness verifjed with Isabelle
- High performance
5
The seL4 µ-kernel
- Member of the L4 µ-kernel family
- Correctness verifjed with Isabelle
- High performance
5
The seL4 µ-kernel
- Member of the L4 µ-kernel family
- Correctness verifjed with Isabelle
- High performance
5
The seL4 µ-kernel
- Member of the L4 µ-kernel family
- Correctness verifjed with Isabelle
- High performance
5
Design process of seL4
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Design process for verifjcation
Requirements Haskell Prototype Executable Specifjcation Abstract Specifjcation C imple- mentation Proof Proof Implementation Implementation Design Improvement Automatic Translation Stage 1 Stage 2 6
Formal methods of the correctness proof
Hoare logic
P {x = 1} C
- x := x + 1
Q {x = 2}
7
More Hoare logic
{x = 0 ∧ x = 1} y := 2 ∗ x { x and y are even }
8
More Hoare logic
{x is even} y := 2 ∗ x { x and y are even }
8
More Hoare logic
{x is even} y := 2 ∗ x {x and y are even}
8
Partial correctness of Hoare logic
{ } WHILE true DO c { }
9
Data refjnement
A concrete system C refjnes an abstract specifjcation A if the behaviour of C is contained in that of A.
10
Data refjnement
A concrete system C refjnes an abstract specifjcation A if the behaviour of C is contained in that of A.
10
Data refjnement: Examples
- The scheduler selects runnable threads
- System calls return non-zero values on error
11
Layers of the correctness proof
Proof structure
Executable Specifjcation Abstract Specifjcation C implementation (Semantics) Haskell prototype C implementation Isabelle/HOL Proof Automatic translation
12
Abstract specifjcation
The abstract specifjcation is the most high-level layer still fully encapturing the behaviour of the kernel.
13
Scheduler on the abstract level
schedule ≡ do threads ← all_active_tcbs; thread ← select threads; switch_to_thread thread
- d OR switch_to_idle_thread
14
Executable specifjcation
Fill in the details left open by the abstract specifjcation.
15
Haskell implementation of the scheduler
schedule = do action <- getSchedulerAction case action of ChooseNewThread -> do chooseThread setSchedulerAction ResumeCurrentThread ... chooseThread = do r <- findM chooseThread' (reverse [minBound .. maxBound]) when (r == Nothing) $ switchToIdleThread chooseThread' prio = do q <- getQueue prio liftM isJust $ findM chooseThread'' q chooseThread'' thread = do runnable <- isRunnable thread if not runnable then do tcbSchedDequeue thread return False else do switchToThread thread return True
Get runnable thread with highest priority using chooseThread' or schedule idle thread. Call chooseThread to select next thread. Try to fjnd runnable thread in Queue. Check if thread is runnable and act accordingly.
16
Haskell implementation of the scheduler
schedule = do action <- getSchedulerAction case action of ChooseNewThread -> do chooseThread setSchedulerAction ResumeCurrentThread ... chooseThread = do r <- findM chooseThread' (reverse [minBound .. maxBound]) when (r == Nothing) $ switchToIdleThread chooseThread' prio = do q <- getQueue prio liftM isJust $ findM chooseThread'' q chooseThread'' thread = do runnable <- isRunnable thread if not runnable then do tcbSchedDequeue thread return False else do switchToThread thread return True
Get runnable thread with highest priority using chooseThread' or schedule idle thread. Call chooseThread to select next thread. Try to fjnd runnable thread in Queue. Check if thread is runnable and act accordingly.
16
Haskell implementation of the scheduler
schedule = do action <- getSchedulerAction case action of ChooseNewThread -> do chooseThread setSchedulerAction ResumeCurrentThread ... chooseThread = do r <- findM chooseThread' (reverse [minBound .. maxBound]) when (r == Nothing) $ switchToIdleThread chooseThread' prio = do q <- getQueue prio liftM isJust $ findM chooseThread'' q chooseThread'' thread = do runnable <- isRunnable thread if not runnable then do tcbSchedDequeue thread return False else do switchToThread thread return True
Get runnable thread with highest priority using chooseThread' or schedule idle thread. Call chooseThread to select next thread. Try to fjnd runnable thread in Queue. Check if thread is runnable and act accordingly.
16
Haskell implementation of the scheduler
schedule = do action <- getSchedulerAction case action of ChooseNewThread -> do chooseThread setSchedulerAction ResumeCurrentThread ... chooseThread = do r <- findM chooseThread' (reverse [minBound .. maxBound]) when (r == Nothing) $ switchToIdleThread chooseThread' prio = do q <- getQueue prio liftM isJust $ findM chooseThread'' q chooseThread'' thread = do runnable <- isRunnable thread if not runnable then do tcbSchedDequeue thread return False else do switchToThread thread return True
Get runnable thread with highest priority using chooseThread' or schedule idle thread. Call chooseThread to select next thread. Try to fjnd runnable thread in Queue. Check if thread is runnable and act accordingly.
16
Haskell implementation of the scheduler
schedule = do action <- getSchedulerAction case action of ChooseNewThread -> do chooseThread setSchedulerAction ResumeCurrentThread ... chooseThread = do r <- findM chooseThread' (reverse [minBound .. maxBound]) when (r == Nothing) $ switchToIdleThread chooseThread' prio = do q <- getQueue prio liftM isJust $ findM chooseThread'' q chooseThread'' thread = do runnable <- isRunnable thread if not runnable then do tcbSchedDequeue thread return False else do switchToThread thread return True
Get runnable thread with highest priority using chooseThread' or schedule idle thread. Call chooseThread to select next thread. Try to fjnd runnable thread in Queue. Check if thread is runnable and act accordingly.
16
C implementation
Translate the Haskell implementation to C.
17
Machine Model
invalidateTLB :: unit machine_m => unit machine_m invalidateCacheRange :: unit machine_m => word => word => unit machine_m
18
Data refjnement for state machines
σ1 σ2 σn s1 s2 sn · · · Abstract operations in M1 State relation State relation · · · Concrete operations in M2
19
Data refjnement for state machines
σ1 σ2 σn s1 s2 sn · · · Abstract operations in M1 State relation State relation · · · Concrete operations in M2
19
Data refjnement for state machines
σ1 σ2 σn s1 s2 sn · · · Abstract operations in M1 State relation State relation · · · Concrete operations in M2
19
Data refjnement for state machines
σ1 σ2 σn s1 s2 sn · · · Abstract operations in M1 State relation State relation · · · Concrete operations in M2
19
Refjnement by forward simulation
σ σ′ s s′
State Relation State Relation Abstract Operation in M1 Concrete Operation in M2
20
Example for forward simulation
On the Board
21
Types of state transitions
Kernel Mode User Mode Idle Mode
22
Main result
MA ME MC refjnes refjnes refjnes
23
Main result
MA ME MC refjnes refjnes refjnes
23
Main result
MA ME MC refjnes refjnes refjnes
23
Conclusion
Expenditure of time
Artefact Efgort (py) Total (py) Haskell impl. 2.0 2.2 C impl. 0.2 Generic framework 9.0 20.5 Abstract spec. 0.3 Executable spec. 0.2 Refjnement MA ↔ ME 8.0 Refjnement ME ↔ MC 3.0
24
How does the efgort compare?
- EAL7: 1000$/LOC
seL4: 370$/LOC
- L4 Pistachio kernel: 6 py
seL4 kernel: 2.2 py
25
How does the efgort compare?
- EAL7: 1000$/LOC ↔ seL4: 370$/LOC
- L4 Pistachio kernel: 6 py
seL4 kernel: 2.2 py
25
How does the efgort compare?
- EAL7: 1000$/LOC ↔ seL4: 370$/LOC
- L4 Pistachio kernel: 6 py ↔ seL4 kernel: 2.2 py
25
Changes due to verifjcation
100 200 300 400 500 600 C Spec 16 54 34 144 44 250 250 Bugs VC Bugs VC Bugs Refjnement 1 Refjnement 2 Testing
26
What was achieved?
- Correctness proof down to binary level
- Trust in hardware
- What about Spectre and Meltdown?
27
What was achieved?
- Correctness proof down to binary level
- Trust in hardware
- What about Spectre and Meltdown?
27
The future of seL4
- More architectures
- Multicore support
- Exclude timing-channel attacks
28
The future of seL4
- More architectures
- Multicore support
- Exclude timing-channel attacks
28
Questions?
28