specifying and verifying device drivers
DESCRIPTION
Specifying and Verifying Device Drivers. Wes Weimer George Necula Gregoire Sutre. Overview. Background and Motivation Safety Properties Events and History Registers Driver States Specifications Verification Implementation. Background and Motivation. Why bother? PCC-style background - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/1.jpg)
Specifying and VerifyingDevice Drivers
Wes Weimer
George Necula
Gregoire Sutre
![Page 2: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/2.jpg)
Overview
• Background and Motivation
• Safety Properties
• Events and History Registers
• Driver States
• Specifications
• Verification
• Implementation
![Page 3: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/3.jpg)
Background and Motivation
• Why bother?• PCC-style background
– Want a sound analysis
• Decided on an all-paths analysis– Similar to PREfix, ESC, Slam, Magick– Check pre- and post-conditions, kernel API– But also specify resource management, etc.
• Greg will recast as model checking later
![Page 4: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/4.jpg)
Safety Properties
• We aim to verify that …– Allocated resources are freed
• Over the lifetime of the driver
• Enforce acquire order: no deadlocks
– Kernel functions are called correctly• Also includes ordering requirements and
obligations, like schedule() and signal_pending().
– Certain minimum actions are performed
![Page 5: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/5.jpg)
Events
• Three broad types:+ allocation, - deallocation, ! event
• Applied to uninterpreted constructors:irq, dma, memory, schedule
• And given program values as arguments:+irq(5), -dma(3), !schedule
• Function call and return may be treated as events
![Page 6: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/6.jpg)
History Register
• Abstract register used to verify programs– Like the “memory register” in PCC/VCGen– Never appears in user-written code
• Keeps an ever-increasing list of events– E.g., [ +irq(7) ; !schedule ; +misc(&qpmouse) ]
• May refer to it in conditions– E.g., PRE(!historyContains(+irq(i)))
![Page 7: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/7.jpg)
Driver States
S0: Uninitialized
S1: Initialized
S2: Opened
init_module=0cleanup_module=0
misc_open=0 misc_release=0
misc_read=*
misc_write=*Inv(S0) = trueInv(S1) = historyContains(+misc(any))
![Page 8: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/8.jpg)
Driver States (cont’d)
• Kernel API guarantees a certain state-like behavior for device drivers– E.g., misc_open will only be called if the driver is in S1
• We associate an invariant with each state– Captures history register values– And global variables in the driver
• Must check all paths from S0 to S0.– For resource leaks, etc. – Similar to data-flow analysis
![Page 9: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/9.jpg)
Specifications
• Write spec in C, just like driver– May use data and control non-determinism– May use pre-conditions: like assert(), but will not fail
• Spec is minimal– List only things that must be done– Looks like a “template” device driver– Normal device drivers often written by copying others
• Side-conditions govern optional behavior– Like matching alloc/free– Or checking signals after sleeping
![Page 10: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/10.jpg)
Specification Example
int init_module() { /* user code must look like this */PRE(!historyContains(+misc(any)));switch (__rand_int_range(0,3)) {
case 0: misc_register(any); /* use kernel API */ return 0;
case 1: return –5; /* EIO */case 2: return –6; /* ENXIO */case 3: return –19; /* ENODEV */
}}
![Page 11: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/11.jpg)
Specification Example (2)
int misc_fasync(void *fd, void *filp, int on) {PRE(fd != 0 && filp && (on == 1 || on == 0)
&& current->state == TASK_RUNNING&& historyCount(!misc_open) >
historyCount(!misc_release));int retval = fasync_helper(fd, filp, on, any);if (retval < 0) return retval;else return 0;}
![Page 12: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/12.jpg)
Kernel API Spec
• Model behavior of kernel functions– Like kmalloc(), schedule(), kfree()– May modify history register
• Example:int request_irq(int i, void *f, …) {PRE(historyCount(+irq(i)) == historyCount(-irq(i)) &&
implements(f, irq_handler) && …);if (__rand_int_range(0,1)) { return –5; } else { historyAdd(+irq(i)); return 0; }}
![Page 13: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/13.jpg)
Kernel API Spec (2)int kmalloc(int size, int prio) {PRE(size > 0 && size < (128*1024) && (prio & GFP_KERNEL || prio & GFP_ATOMIC)
&& !(prio & GFP_KERNEL && prio & GFP_ATOMIC));if (prio & GFP_KERNEL) {
int old_state = current->state;current->state = TASK_INTERRUPTIBLE;schedule();current->state = old_state;historyAdd(!signal_pending);
}if (__rand_int_range(0,1) {
void *retval = __rand_int_range(1, MAX_INT/4)*4;historyAdd(+memory(retval));return retval;
} else return NULL;}
![Page 14: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/14.jpg)
Side Conditions
• Used to verify optional behavior– Like resource allocation, scheduling– Conditions on the history register
• Examples:– Every !schedule must match a !signal_pending– After !must_return(-512), must return –512– All +irq(…) before any +dma(…)– All +irq(…) occur after !misc_open
![Page 15: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/15.jpg)
Story so far …
• We have the user source code
• We have the history register abstraction– Keep track of the past, etc.
• We have a spec for the user code– Minimal, lists things that must be done
• We have a spec for the kernel API
• We have side conditions
![Page 16: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/16.jpg)
Verification
• When does the user code meet the spec?– Each user function F “matches up” (defined
next) with our spec for function F– If the user calls a kernel function with a pre-
condition, the condition will always be satisfied– All of the side conditions hold over the life of
the device driver
![Page 17: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/17.jpg)
“Matching Up”
• Can be phrased as a trace inclusion problem– More on that with the next speaker
• We’ll do it as an all-paths analysis
• Symbolically execute all paths in user code
• Keep track of history register
• Remove +resource(X) and –resource(X)
• Make sure other important events match
![Page 18: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/18.jpg)
How to Verify
• Symbolically execute all paths in user code– End up with a set of final states U– Verify pre-conditions, use theorem prover
• Symbolically execute all paths in spec– End up with a set of final states S
• For every uU, find an sS such that– They have the same return value– Their history registers match up– If s proves T then u proves T (for a few global T’s)
![Page 19: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/19.jpg)
How to Verify: States
• Start in S0, then check init_module()– Match each final state against the spec– Check all side-conditions in each final state
• Gather all states R with return value 0– Their LUB becomes the invariant for S1– Analyze all paths out of S1 (= symbolically
execute those functions with that invariant)
• Repeat until this terminates.
![Page 20: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/20.jpg)
What can go wrong?
• User code can call a kernel function and fail to meet the pre-condition
• User code can fail to meet a side condition
• User code can fail to match up to the spec
• If so, report an error!
• And hope that it’s not a false positive.
![Page 21: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/21.jpg)
Loop Invariants
• Used in symbolic execution to model loops
• Currently, we guess “true”– or use any other heuristic (e.g., on “for” loops)
• Except for the history register
• Gather all history changes in the loop body
• Add a special history element:• X_copies_of(history_element_list)
![Page 22: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/22.jpg)
Does it work?
• Sample implementation
• Tested on init_module() in 46 misc device drivers (about 300k post-processed each)
• 30 successful terminations (25 meet spec)– Others look fine, spec needs to be refined
• 16 “no answer after 45 seconds” – All-paths analysis is expensive: O(2n)
![Page 23: Specifying and Verifying Device Drivers](https://reader036.vdocuments.us/reader036/viewer/2022062309/56815075550346895dbe72d9/html5/thumbnails/23.jpg)
Conclusions and Future Work
• Method for specifying and verifying– Spec looks like original code– Sound, incomplete, expensive– Uses abstract events
• Captures allocation, function ordering, other API and behavioral restrictions
• Next steps: – folding similar paths– handling concurrency (e.g., irq handlers)