1 Efficient Memory Safety for TinyOS Nathan Cooprider Will Archer Eric Eide David Gay † John...
-
date post
19-Dec-2015 -
Category
Documents
-
view
212 -
download
0
Transcript of 1 Efficient Memory Safety for TinyOS Nathan Cooprider Will Archer Eric Eide David Gay † John...
1
Efficient Memory Safety for TinyOS
Nathan Cooprider Will Archer Eric Eide David Gay† John Regehr
University of Utah School of Computing
†Intel ResearchBerkeley
2
● What happened?– State got corrupted– Hard to debug
● Limited visibility into executing systems● Difficult to replicate complex bugs
Suppose we have a WSN…
3
Goal
● Catch all pointer and array bounds errors– Before they corrupt state
● Provide a choice of recovery action
● Put WSN software development on a solid foundation
4
Expand
into system safety
Our contribution: Safe TinyOS
• Modify TinyOS to work with Deputy
• Enforce Deputy’s safety model under concurrency
• Reduce overhead– 5.2% duty cycle increase– 13% code size increase
Deputy: existing solution for making C safe
Practical fordeployment
5
Example builds
$ make mica2
$ make mica2 safe
$ make mica2 safe optimize
6
Language safety
● Deputy is the starting point– Safe C dialect developed at Berkeley– Annotations exploit values present in code to
specify bounds/etc information– Translates a C program into a safe C program
by inserting safety checks
Language safety
Deputy
System safety
Safe TinyOSOur work
7
Annotations in nesC
Example interface from TinyOS 2/* Buffered high data rate reading, usually from sensor devices */
interface ReadStream<val_t> {
command error_t postBuffer(val_t* buf, uint16_t n);
command error_t read(uint32_t usPeriod);
event void bufferDone(error_t result, val_t* buf, uint16_t n);
event void readDone(error_t result, uint32_t usActualPeriod);
}
8
Annotations in nesC
COUNT Either null or array
/* Buffered high data rate reading, usually from sensor devices */
interface ReadStream<val_t> {
command error_t postBuffer(val_t* COUNT(n) buf, uint16_t n);
command error_t read(uint32_t usPeriod);
event void bufferDone(error_t result, val_t* COUNT(n) buf, uint16_t n);
event void readDone(error_t result, uint32_t usActualPeriod);
}
9
Few lines changed
● 253 nesC files – 26,022 loc
● 0.74% changed– 1 in 135 lines
8%
69%
23%
ApplicationsTinyOS ComponentsTinyOS Interfaces
16/2541 or 0.63% Application lines
133/20455 or 0.65% TinyOS Component lines
44/3026 or 1.5% TinyOS Interface lines
10
Concurrency
run modifiednesC compiler
enforce safetyusing Deputy
deal withconcurrency
Potentially unsafe readIf ( )
Deputy checkInterrupt
Potentially unsafe read
to local
Read localA
tom
ic b
lock
● Deputy enforces safety in sequential code
● Static analysis to avoid extraneous protection– Few actually need protection
11
Compress error messages
run modifiednesC compiler
enforce safetyusing Deputy
compresserror messages
deal withconcurrency
● Deputy’s verbose messages – Use precious memory– No screen on the mote
● Replaced with integer ID– Fault location identifiers, FLIDs– FLIDs blinked on LEDs or sent
to network
0x0773
tos/chips/cc2420/CC2420ReceiveP.nc:241:CC2420ReceiveP$receiveDone_task$runTask:Assertion failed in upper bound coercion:CC2420ReceiveP$m_p_rx_buf->data + length
<=CC2420ReceiveP$m_p_rx_buf + 28
decodeFLID
12
Code improvements
run modifiednesC compiler
enforce safetyusing Deputy
compresserror messages
whole-programoptimization
deal withconcurrency
● Dataflow analysis– Interprocedural and whole-
program– Simultaneous pointer analysis– Handles concurrent programs
● Propagate data through globals● More aggressive than gcc is, or
can be:– Inlining– Dead code elimination – Value propagation– Synchronization removal
13
Safe TinyOS toolchain
run modifiednesC compiler
enforce safetyusing Deputy
compresserror messages
whole-programoptimization
deal withconcurrency
AnnotateSafe
TinyOScode
TinyOScode
run modifiednesC compiler
enforce safetyusing Deputy
deal withconcurrency
compresserror messages
whole-programoptimization
Safe TinyOS
app
Modify TinyOS to work with Deputy
Enforce Deputy’s safety model under concurrency
Reduce overhead
14
Resource usage
● Six TinyOS 2 benchmarks– 3,561 to 25,773 lines of C code
● No RAM usage increase– Deputy exploits existing bounds info.– Optimizer saves a little RAM
● Duty cycle obtained with Avrora simulator– Duty cycle = % of time processor is on
15
Code size
16
Code size
35%
13%
-11%
17
Duty cycle
24%
5.2%
-9.7%
18
On to bug hunting
● Ran Safe TinyOS applications on motes● Found four bugs● Will talk about three of them
19
A bug
Buffer length
SerialDispatche
r
● Serial stack – passed in a buffer– Passes along one byte at a time
● Problem: given buffer length too large● Out-of-bounds index for buffer
Safety violationcaught by
Safe TinyOSReporte
d to TinyOS 2
maintainers and
FIXED
20
Another bug
● Active Message Queue– Scheduling of network link
● Queue moves on to next client on send done event
● With no clients– Spurious report of
completion– Invalid array index
● Difficult to replicate– Several minutes, many
nodes
Send done
Safety violationcaught by
Safe TinyOS
0
Current
Send done
Send done
123Reporte
d to TinyOS 2
maintainers and
FIXED
21
Yet another bug
● Time synchronization and leader election● Array out-of-bounds access● Difficult to locate
– After 20 minutes– In “third-party” networking code
for (i = 0; i < NUM_BUFFERS; i++) { if (m_pool[i].msg == NULL) break;}
if (m_pool[i].msg == NULL) { m_pool[i].msg = _msg;}
i can point to one past end of buffer
Upon discovery
Bug already fixed in latest release of third-party component
22
Increased availability
Array Out-of-bounds
Array Out-of-bounds
Reboot
NormalTinyOS
SafeTinyOS
RebuildSoft state
Normal TinyOS:0% average availability
Safe TinyOS:95% average
availability
23
Conclusion
● Type and memory safety is practical for tiny embedded systems– Safety for entire system– Low run-time cost compared to original
unsafe applications– Can easily fit into existing programming
practice
We plan to make it available soon…