light-weight bounds checking ashish misra secure systems laboratory, stony brook university a thesis...
TRANSCRIPT
Light-weight Bounds Checking
Ashish MisraSecure Systems Laboratory,
Stony Brook University
A Thesis Presentation in Partial Fulfillment of the
Requirements for the Degree ofMaster of Science
inComputer Science
ADVISORProf. R.C. Sekar
COMMITTEEProf. Rob Johnson Prof. C.R. Ramkrishnan
Many popular bounds checkers currently deployed
Insure++, IBM Purify, Valgrind ...
Performance overhead is 100X.
Doesn’t matter . These are debuggers
With such tools available surely memory errors would have reduced..
Not really ...
Pointers and arrays accesses tops the list .... [Patil and Fischer, 1995]
Errors in the use of Pointers and array subscript still dominate ... [Miller, 2006]
Microsoft fixes 1800 bugs in Office 2010... [May 2010]
We do need a better bounds checker!
Why a new bounds checker?
1/20
Lots of research has been done.
Some of the latest papers:
Baggy Bounds Checking, 2009
PARicheck, 2009
SoftBounds, 2009
Are these better?
What’s better?
1) Catches as many errors as possible
2) Fast
3) Compatible with any program. Works with un-instrumented libraries
In search of better bounds checker..
2/20
However, Patil and Fischer [1995] argue that: Runtime instrumentation is a must Adds overhead to the normal safe run
May be better means:
1) Fast
2) Compatible with any C program.
3) Catches as many errors as possible So....
Baggy Bounds Check (60% overhead Bzip2, Not compatible) PARicheck (144.7% overhead, Not compatible) Softbounds (60% overhead, Wrappers needed for uninstrumented
library functions)
Are these good enough?
What’s better?
3/20
How do current Bounds checking techniques work?
Language-based approaches.
Eg: CCured, Cyclone.
Advantage: Can provide complete memory safety.
Disadvantage: Programmer annotations are required.
Cannot interact with uninstrumented libraries
Object Based Approach:
Track all allocated memory regions in a separate data-structure
Advantages: All pointers share object-data, compatibility with un-instrumented libraries.
Disadvantages: Special handling of out-of-bounds pointers, performance overhead, Intra-object overflow cannot be detected.
Current Approaches
4/20
Pointer Based Approach
Bounds information maintained per pointer. Pointer dereference is instrumented with bounds check. e.g. Fat pointers.
Advantages: Can provide complete spatial safety, Can prevent intra-object overflows, Can detect temporal errors.
Disadvantages: Changes memory layout of programs, cannot interact with un-instrumented libraries without wrappers.
But neither one is simultaneously:
Capable of all working with all C programs
Complete backwards compatibility
Fast performance reasonable enough to be deployed.
Current Approaches
5/20
So let’s start designing one…
6/20
p
value = *p;
bounds_check(p);
if (fast_check (*p)) if (slow_check(p))
flag_error ( );
Memory
Redzone(Fixed byte pattern)
But what if the fast redzone check fails?
Maintain the locations of redzones in separate data-structure (a redzone map)
The redzone map is updated
Before main is called, for global variables
At function entry and exit for local variables
At object allocation, de-allocation time for heap objects
Thus, fast_check compares pointer dereference against a fixed byte (redzone value).
slow_check(p) can verify pointer against the redzone map.
…
7/20
Apparent disadvantages of this approach
Not all errors can be caught.
Write instrumentation introduces additional memory access.
…
8/20
Using Redzones is not a new concept. Even commercial tools use redzones.
Rational Purify.
Mpatrol library.
FreeBSD kernel.
No. This is not the old redzone.
Wait a minute!
9/20
Our approach Traditional
Objects instrumented All unsafe objects Heap objects only
Runtime instrumentation For every memory access At heap free operation only
Redzone pattern used Yes No for Purify
Targeted for Production Debugging
How do we decide redzone size? Where are they initialized?
Global variables
Local variables
Heap variables
Extern variables and global variable initialization.
Aligned Memory objects.
How do we free a memory object?
Extern variables with only type declarations.
Its not that simple ….
10/20
Consists of compile time component and runtime component
Prototype is made up of the following
Source to source transformation module using CIL
Static libraries for redzone map
Glibc instrumentation for heap objects.
Source Transformation used CIL’s Visitor class. Two passes performed over the file
Object Transformation Pass
Runtime instrumentation Pass
Implementation required roughly 5000 lines of Ocaml code, about 1000 lines of C code including Glibc instrumentation.
Prototype Implementation
11/20
Performance evaluation was conducted on a system with 2.00 GHz Core 2 Duo Processor with 3 GB RAM running 32 bit Ubuntu 9.10.
The performance overheads were as follows
Uh, oh .... Lets optimize:
Strength reduction. Reduce function calls Loop unrolling.
Lets do this again ..... Oops
That was easy!
12/20
Our Technique Baggy Bounds
Gzip 40% 50%
Bzip2 75% 60%
Our technique Baggy Bounds
Gzip 35% 50%
Bzip2 70 60%
Optimized Fast redzone check
Cannot cast into void ptr and back. Otherwise code generated compares redzone value against memory
The fun stuff ….
13/20
Naive Approach
intredzone_fast_check(void *ptr) { return (*(char *)ptr) ==
redzone_value ;}
Current Approach
#define redzone_fast_check(value, ptr) {
int flag; flag = (value == redzone_value); if (flag) redzone_slow_check(ptr);}
Optimized slow redzone check function call.
Cannot directly call slow redzone check
This preserves register allocation.
Using Array Bounds where-ever possible.
The fun stuff ….
14/20
Naive Approach
if (flag) redzone_slow_check(ptr);
Current Approach
if (flag) { asm ( “pushl %%eax\n” “pushl %%ecx\n” “pushl %%edx\n” “call slow_redzone_check” “popl %%edx” “popl %%ecx” “popl %%eax” );}
15/20
mcf bzip sjeng hmmer perl0
50
100
150
200
250
Specint 2006 Overhead
LBC
Evaluation Performance testing on 2.00 GHz Intel core 2 Duo processor and 3 GB
RAM running Ubuntu 9.10 Performance tested using Specint 2006 C benchmarks.
We could also instrument Libpng – 30% overhead OpenSSL NullHttpd – Caught two out of bounds errors.
Specint Comparison
16/20
Baggy Bounds Check reports only Specint 2000 benchmarks
gzip bzip perlbmk0
50
100
150
200
250
5060
100
2535
200
Baggy Bounds
LBC
Function contributing to 75% of runtime was structured as:
Original code: Most variables declared in block. Instrumented code: All block variables pulled to outermost block. Feature of CIL infrastructure. Stack variables instrumentation needs to be enhanced
What is wrong with Perl?
17/20
Before Instrumentation
switch (var) {
case 1 : int a; int b; …. case 2: int c; int d; …}
After Instrumentation{…init_redzone(a);init_redzone(b)init_redzone(c);Init_redzone(d);
switch (var) {
case 1 : …. case 2 : …}
Nope.
Static Analysis is heavily emphasized in bounds checking. We haven’t utilized it yet.
Replace redzone check with bounds check for unaliased pointers
Technique 1: Decide dynamically whether a redzone or bounds check is to be enforced
Technique 2: Decide at compile time to employ either redzone or bounds check
Unsafe Stack variables need optimization
Redzone map layout of stack frame.
Is this the best we can do?
18/20
Advantages of our approach
Relatively fast. It can be improved further
Compatible with un-instrumented libraries. Can instrument any C program
Separate compilation helps integration with build process.
Thus we believe it represents a potent approach to bounds checking problem.
The Aftermath ….
19/20