360 likes | 493 Views
Protecting C Programs from Attacks via Invalid Pointer Dereferences. Suan Hsi Yong, Susan Horwitz University of Wisconsin – Madison. Invalid Pointer Dereferences. Buffer overruns via pointers or arrays Stale pointers (pointers to freed memory) Undesirable because incorrect results
E N D
Protecting C Programsfrom Attacks viaInvalid Pointer Dereferences Suan Hsi Yong, Susan Horwitz University of Wisconsin – Madison
Invalid Pointer Dereferences • Buffer overruns • via pointers or arrays • Stale pointers (pointers to freed memory) • Undesirable because • incorrect results • crash / corrupt data • security risk a[i] *(a+i)
Security Risk • Gain control • stack smashing (return address on stack) • function pointers, setjmp buffers, GOT • Gain unauthorized access • e.g. changing argument to fopen • Corrupt data / Disrupt service
Stack Smashing char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); p buf return address
Our Approach, for C • Dynamically detect invalid writes via pointers • halt execution when detected • Efficient (low overhead) • No false positives • No source code modification needed
Outline • Introduction • Previous Approaches • Description of Approach • Experiments • Conclusion
Previous Approaches • StackGuard: protects return addresses only • efficient • automatic • does not protect other memory locations • platform dependent • StackShield: similar, but also protects function pointers
Fat Pointers • Record information about what a pointer should point to • CCured, Cyclone • detects all invalid accesses • less flexibility in memory management:requires garbage collection(or region-based model, for Cyclone) • doesn’t handle all of C(rejects some legal C programs) • requires programmer changes to source
Fat Pointers • associate information with pointer: address and size of referent p buf 12 char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); buf return address
Our Approach • associates information with target rather than pointer p char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); buf return address
Which Locations to Mark? • naively: Mark All User-defined Locations char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); p buf return address
Which Locations to Mark? FN_PTRfp= &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp • Static Analysis, to permit marking fewer locations
Unsafe Pointers • a pointer p that may point to invalid memory: • p is assigned a non-pointer value, or • p is the result of pointer arithmetic, or • p may become stale • only writes via unsafe pointers are checked at runtime • safe pointer dereferences are not checked • for efficiency, we don’t check reads a[i] *(a+i)
pointers: unsafe p safe fp Example: Unsafe Pointers FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)();
Tracked Locations • a location that an unsafe pointer may point to • mirror is marked ok () when allocated, and forbidden () when freed. • untracked locations always forbidden () • never pointed-to by unsafe pointer • points-to analysis needed
locations: pointers: points-to graph: untracked unsafe p p p fp untracked safe fp fp tracked buf foo buf Example: Tracked Locations FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)();
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Allocation FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)();
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Allocation FN_PTRfp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Allocation FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); buf fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Allocation FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Checking Writes FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Checking Writes FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Checking Writes FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp
locations: pointers: untracked unsafe p p untracked safe fp fp tracked buf Example: Checking Writes FN_PTR fp = &foo; char buf[12]; char *p = &buf[0]; do { *p = getchar(); } while(*p++ != ‘\0’); (*fp)(); p buf fp
Tool Overview Csourcefile instru-mentedClibrary Static Analysis Instrumenter CCompiler unsafe pointers tracked variables instru-mentedC sourcefile instru-mentedexec-utable
Implementation Details • Flow-insensitive Points-to Analysis [Das00] • near-linear time, good precision • C source-to-source instrumenter [Ckit] • ANSI C compliant, portable • Uninstrumented library functions may cause false positives or false negatives • write wrappers to be more precise
Outline • Introduction • Previous Approaches • Description of Approach • Experiments • Conclusion
Experiments • Tool successfully detected two simulated attacks via known vulnerabilities • cfingerd: buffer overrun attack • traceroute: modifying Global Offset Table entry via multiple-free bug
Performance • Runtime Overhead (average 1.97×) Cyclone Olden Spec 95 Spec 2000
increasing size (LOC) Performance • Runtime Overhead (average 1.97×)
Analysis/Instrument/Compile Time • Slowdown vs. Compile Time (average 5×) increasing size (LOC)
Future Work Goal: Less unsafe pointers and tracked locations (for better performance and coverage) • Array-bounds Check Elimination • 98% of dereferences are array accesses • Escape Analysis • currently all pointers to stack objects are unsafe • Flow-Sensitive Analyses • better points-to analysis • dereferencing uninitialized pointer
Conclusion • We present a tool for detecting invalid pointer dereferences that • has low runtime overhead • does not report false positives • is portable, and does not require programmer changes to source code • protects against a wide range of vulnerabilities, including stack smashing and using freed memory
Protecting C Programsfrom Attacks viaInvalid Pointer Dereferences – The End – Suan Hsi Yong, Susan Horwitz University of Wisconsin – Madison
Related Work • Dynamic Debugging Tools • Purify • Valgrind • Safe-C • Static techniques • LCLint • ESC • PREfix