Protecting C Programs from Attacks via Invalid Pointer Dereferences

Preview:

DESCRIPTION

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 - PowerPoint PPT Presentation

Citation preview

Protecting C Programsfrom Attacks via

Invalid Pointer Dereferences

Suan Hsi Yong, Susan HorwitzUniversity 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’);

bufp

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

aescacmcfr

ac

grobn

er

matxmult

ppm tile bh

bisortem

3dhe

althmst

perim

eter

power

treead

d tsp

compre

ss gcc goijp

eg li

m88ksi

mperl

vorte

xam

mp artbz

ip2cra

fty

equa

kegzipmcf

parse

rtw

olf vpr

Cyclone Olden Spec 95 Spec 2000

Performance• Runtime Overhead (average 1.97×)

0

1

2

3

4

5

6

7

8

9

cacm

treead

d

perim

eter

em3dmst tsp

bisorthe

alth

power art

matxmult

ppmeq

uakeaesmcf bh

compre

sscfr

acbz

ip2

grobn

er tile ligz

ippa

rser

ammp vp

r

m88ksi

mtw

olfcra

ftyperl goijp

egvo

rtexgc

c

increasing size (LOC)

Comparing with CCured/Cyclone

0123456789

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×)

012

34567

89

10

cacm

treead

d

perim

eter

em3dmst tsp

bisorthe

alth

power art

matxmult

ppmeq

uakeaesmcf bh

compre

sscfr

acbz

ip2

grobn

er tile ligz

ippa

rser

ammp vp

r

m88ksi

mtw

olfcra

ftyperl goijp

egvo

rtexgc

c

increasing size (LOC)

Future WorkGoal: 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 via

Invalid Pointer Dereferences

Suan Hsi Yong, Susan HorwitzUniversity of Wisconsin – Madison

– The End –

Related Work

• Dynamic Debugging Tools– Purify– Valgrind– Safe-C

• Static techniques– LCLint– ESC– PREfix

Recommended