Upload
jared-harmon
View
218
Download
0
Embed Size (px)
Citation preview
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– 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’);
buf
p
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
• associate information with pointer:address and size of referent
buf
p
Fat Pointers
buf12
char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);
return address
• associates information with target rather than pointer
buf
p
Our Approach
char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);
return address
char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);
buf
p
Which Locations to Mark?
return address
• naively: Mark All User-defined Locations
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
buf
p
fp
Which Locations to Mark?
• 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)
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Unsafe Pointers
pointers:unsafesafe
p
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
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Tracked Locations
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
p
buf
points-tograph:
foo
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Allocation
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Allocation
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Allocation
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
buf fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Allocation
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
buf
p
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Checking Writes
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
buf
p
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Checking Writes
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
buf
p
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Checking Writes
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
buf
p
fp
FN_PTR fp = &foo;char buf[12];char *p = &buf[0];do { *p = getchar();} while(*p++ != ‘\0’);(*fp)();
Example: Checking Writes
buf
p
fp
pointers:unsafesafe
p
fp
p
buf
fp
locations:untrackeduntrackedtracked
Tool OverviewCsource
file
instru-mented
C sourcefile
instru-mentedexec-utable
instru-mented
Clibrary
unsafe pointerstracked variables
StaticAnalysis Instrumenter C
Compiler
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×)
0
1
2
3
4
5
6
7
8
9
aesca
cmcf
rac
grob
ner
matx
multpp
m tile bh
biso
rtem
3dhe
althm
st
perim
eter
power
treea
dd tsp
com
pres
sgc
c goijp
eg li
m88
ksimpe
rl
vorte
x
amm
p art
bzip
2cr
afty
equa
kegz
ipm
cf
parse
rtw
olfvp
r
Cyclone Olden Spec 95 Spec 2000
Performance• Runtime Overhead (average 1.97×)
0
1
2
3
4
5
6
7
8
9
cacm
treea
dd
perim
eter
em3dm
st tspbi
sort
healt
h
power ar
t
matx
multpp
meq
uakeae
sm
cf bh
com
pres
scf
racbz
ip2
grob
ner
tile li
gzip
parse
r
amm
pvp
r
m88
ksimtw
olf
craf
typerl go
ijpeg
vorte
xgc
c
increasing size (LOC)
Comparing with CCured/Cyclone
0
1
2
3
4
5
6
7
8
9
10
aes cacm cfrac grobner matxmult ppm tile
Our Tool (2.2x) CCured (4.7x) Cyclone (1.4x)
Analysis/Instrument/Compile Time
• Slowdown vs. Compile Time (average 5×)
0
1
2
3
4
5
6
7
8
9
10
cacm
treea
dd
perim
eter
em3dm
st tspbi
sort
healt
h
power ar
t
matx
multpp
meq
uakeae
sm
cf bh
com
pres
scf
racbz
ip2
grob
ner
tile li
gzip
parse
r
amm
pvp
r
m88
ksimtw
olf
craf
typerl go
ijpeg
vorte
xgc
c
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 Programs
from Attacks via
Invalid Pointer Dereferences
Suan Hsi Yong, Susan Horwitz
University of Wisconsin – Madison
– The End –
Related Work
• Dynamic Debugging Tools– Purify– Valgrind– Safe-C
• Static techniques– LCLint– ESC– PREfix