Advanced Dynamic Analysis for Leak Detection (Apple Internship 2008)

Preview:

DESCRIPTION

 

Citation preview

Advanced dynamic analysis for leak detection

Jim ClauseChris Friesen - ManagerAnalysis Tools Group

Current analysis tools

Shark Instruments

≈X-ray

Current analysis tools

Shark Instruments

≈X-ray

MRI

Current analysis tools

Shark Instruments

≈X-ray

MRI

Current analysis tools

Shark Instruments

≈?

≈X-ray

MRI

Current analysis tools

Shark Instruments

C

A

B

31

2

Z

3

Dynamic taint analysis

Dynamic taint analysis

C

A

B Z

Dynamic taint analysis

1 Assign

taint marks

C

A

B Z

Dynamic taint analysis

1 Assign

taint marks

C

A

B

31

2

Z

Dynamic taint analysis

1 Assign

taint marks2 Propagate

taint marks

C

A

B

31

2

Z

Dynamic taint analysis

1 Assign

taint marks2 Propagate

taint marks

C

A

B

31

2

Z

Dynamic taint analysis

1 Assign

taint marks3 Check

taint marks2 Propagate

taint marks

C

A

B

31

2

Z

Dynamic taint analysis

1 Assign

taint marks3 Check

taint marks2 Propagate

taint marks

C

A

B

31

2

Z

C

A

B

31

2

Z

3

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errors

Attack detection / preventionPrevent stack smashing, SQL injection, buffer overruns, etc.Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errors

Information policy enforcementensure classified information does not leave the system

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errors

TestingCoverage metrics, test data generation heuristic, etc.

✔/✘

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errors

Data lifetimetrack how long sensitive data remain in the application

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errors

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errorsMemory errorsDetect illegal memory access, leak detection, etc.

Attack detection / prevention

Information policy enforcement

Testing

Data lifetime

Applications of dynamic tainting

Memory errorsMemory errorsDetect illegal memory access, leak detection, etc. leak detection

Detecting leaks is easy, fixing them is hard

Detecting leaks is easy, fixing them is hard

@interface Container:NSObject { id _object;}@end

@implementation Container- (void) dealloc { //[_object release]; [super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Detecting leaks is easy, fixing them is hard

@interface Container:NSObject { id _object;}@end

@implementation Container- (void) dealloc { //[_object release]; [super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

Detecting leaks is easy, fixing them is hard

@interface Container:NSObject { id _object;}@end

@implementation Container- (void) dealloc { //[_object release]; [super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

leaks:This object is leaked

Leakpoint overviewDiscover where the last pointer to un-freed memory is lost

Leakpoint overview

Assign taint marks

Propagate taint marks

Check taint marks

ptr1 = malloc(...) ➔ ptr1

ptr2 = calloc(...) ➔ ptr2

ptr3 = ptr1 ➔ ptr3 , ptr1

ptr1 = NULL ➔ ptr1 , ptr3

ptr4 = ptr2 + 1 ➔ ptr4 , ptr2

Report error if taint mark’s count is zero andmemory has not been freed.

1 1

1

Discover where the last pointer to un-freed memory is lost

Leakpoint overview

Assign taint marks

Propagate taint marks

Check taint marks

ptr1 = malloc(...) ➔ ptr1

ptr2 = calloc(...) ➔ ptr2

ptr3 = ptr1 ➔ ptr3 , ptr1

ptr1 = NULL ➔ ptr1 , ptr3

ptr4 = ptr2 + 1 ➔ ptr4 , ptr2

Report error if taint mark’s count is zero andmemory has not been freed.

2

1 1

1

1 2

2

2

1

1 2 2

Discover where the last pointer to un-freed memory is lost

Leakpoint overview

Assign taint marks

Propagate taint marks

Check taint marks

ptr1 = malloc(...) ➔ ptr1

ptr2 = calloc(...) ➔ ptr2

ptr3 = ptr1 ➔ ptr3 , ptr1

ptr1 = NULL ➔ ptr1 , ptr3

ptr4 = ptr2 + 1 ➔ ptr4 , ptr2

Report error if taint mark’s count is zero andmemory has not been freed.

2

1 1

1

1 2

2

2

1

1 2 2

In general propagation follows standard pointer arithmetic rules

Discover where the last pointer to un-freed memory is lost

Leakpoint overview

Assign taint marks

Propagate taint marks

Check taint marks

ptr1 = malloc(...) ➔ ptr1

ptr2 = calloc(...) ➔ ptr2

ptr3 = ptr1 ➔ ptr3 , ptr1

ptr1 = NULL ➔ ptr1 , ptr3

ptr4 = ptr2 + 1 ➔ ptr4 , ptr2

Report error if taint mark’s count is zero andmemory has not been freed.

2

3

1 1

1

1 2

2

2

1

1 2 2

In general propagation follows standard pointer arithmetic rules

Discover where the last pointer to un-freed memory is lost

@interface Container:NSObject {

id _object;}@end

@implementation Container- (void) dealloc {

[super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

Detecting leaks is easy, fixing them is easier

@interface Container:NSObject {

id _object;}@end

@implementation Container- (void) dealloc {

[super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

leakpoint:This object is leaked

Detecting leaks is easy, fixing them is easier

@interface Container:NSObject {

id _object;}@end

@implementation Container- (void) dealloc {

[super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

leakpoint:Last reference was lost here

leakpoint:This object is leaked

Detecting leaks is easy, fixing them is easier

@interface Container:NSObject {

id _object;}@end

@implementation Container- (void) dealloc {

[super dealloc];}

- (void) setObject:(id)obj { [_object release]; _object = [obj retain];}@end

Container *create() { Container *c = [[Container alloc] init]; NSObject *o = [[NSObject alloc] init]; [c setObject:o]; [o release]; return c;}

int main(...) { Container *c = create(); … [c release];}

[_object release];

leakpoint:Last reference was lost here

leakpoint:This object is leaked

Detecting leaks is easy, fixing them is easier

Leakpoint implementation• Implemented as a Valgrind tool (www.valgrind.org)

■ intercept libc memory management functions■ instrument binary instructions to perform propagation

Lost pointer to 0x1C93AC0 (16 bytes) allocated at:  at calloc+105  by _internal_class_createInstanceFromZone+149  by _internal_class_createInstance+31  by +[NSObject allocWithZone:]+155 (NSObject.m:445)  by +[NSObject alloc]+41 (NSObject.m:432)  by create+97 (main.m:29)  by main+17 (main.m:38) leaked at:  at free+103  by _internal_object_dispose+81  by NSDeallocateObject+223 (NSObject.m:207)  by -[Container dealloc]+53 (container.m:13)  by main+43 (main.m:40)

Leakpoint implementation• Implemented as a Valgrind tool (www.valgrind.org)

■ intercept libc memory management functions■ instrument binary instructions to perform propagation

leak

s

Lost pointer to 0x1C93AC0 (16 bytes) allocated at:  at calloc+105  by _internal_class_createInstanceFromZone+149  by _internal_class_createInstance+31  by +[NSObject allocWithZone:]+155 (NSObject.m:445)  by +[NSObject alloc]+41 (NSObject.m:432)  by create+97 (main.m:29)  by main+17 (main.m:38) leaked at:  at free+103  by _internal_object_dispose+81  by NSDeallocateObject+223 (NSObject.m:207)  by -[Container dealloc]+53 (container.m:13)  by main+43 (main.m:40)

Leakpoint implementation• Implemented as a Valgrind tool (www.valgrind.org)

■ intercept libc memory management functions■ instrument binary instructions to perform propagation

leak

po

int

leak

s

Lost pointer to 0x1C93AC0 (16 bytes) allocated at:  at calloc+105  by _internal_class_createInstanceFromZone+149  by _internal_class_createInstance+31  by +[NSObject allocWithZone:]+155 (NSObject.m:445)  by +[NSObject alloc]+41 (NSObject.m:432)  by create+97 (main.m:29)  by main+17 (main.m:38) leaked at:  at free+103  by _internal_object_dispose+81  by NSDeallocateObject+223 (NSObject.m:207)  by -[Container dealloc]+53 (container.m:13)  by main+43 (main.m:40)

Leakpoint implementation• Implemented as a Valgrind tool (www.valgrind.org)

■ intercept libc memory management functions■ instrument binary instructions to perform propagation

Leakpoint: current status

Leakpoint: current status

Handle basic C / C++ / Objective C

Leakpoint: current status

Handle basic C / C++ / Objective C✔

Leakpoint: current status

Handle basic C / C++ / Objective C✔Handle CoreFoundation

Leakpoint: current status

Handle basic C / C++ / Objective C✔Handle CoreFoundation✔

Leakpoint: current status

Handle basic C / C++ / Objective C

Handle Cocoa

✔Handle CoreFoundation✔

Need to investigate approximately 40false positive (probably) leak reports

• Interface Builder unarchiving

• CoreData

Leakpoint: current status

Handle basic C / C++ / Objective C

Handle Cocoa

✔Handle CoreFoundation✔

Need to investigate approximately 40false positive (probably) leak reports

• Interface Builder unarchiving

• CoreData

Leakpoint: current status

Handle basic C / C++ / Objective C

Handle Cocoa

✔Handle CoreFoundation✔

64bit compatible

Need to investigate approximately 40false positive (probably) leak reports

• Interface Builder unarchiving

• CoreData

Leakpoint: current status

Handle basic C / C++ / Objective C

Handle Cocoa

✔Handle CoreFoundation✔

64bit compatible✔

A real leak?: _NSImageMalloc

void *_NSImageMalloc(NSZone* zone, size_t size) {

// allocate storage aligned to 32 bytes. we do this by// allocating an extra 32 bytes, finding the address in the proper// location and storing the delta in one of the previous 32 bytes.

void *unaligned = NSZoneMalloc(zone, size + BITMAP_DATA_ALIGNMENT);

if(unaligned != NULL) {uintptr_t aligned = ((uintptr_t)unaligned + BITMAP_DATA_ALIGNMENT)

& ~(BITMAP_DATA_ALIGNMENT - 1);

(unsigned char*)aligned[-1] = aligned - (uintptr_t) unaligned;return (void*)aligned;

}else {

return NULL;}

}

Overhead

Powerful but expensive50 -100x overheads are common

Overhead

Powerful but expensive50 -100x overheads are common

Recommended usage:run cheap tools to check for errorsrun expensive tools to diagnose errors

Future work

+ Leakpoint( )

Future work

Impact

+ Leakpoint( )

Future work

• Apple■ new leak detection tool■ experience with dynamic taint analysis

Impact

+ Leakpoint( )

Future work

• Apple■ new leak detection tool■ experience with dynamic taint analysis

• Me■ experience with Valgrind■ experience analyzing large commercial code base

Impact

+ Leakpoint( )

Questions?

Recommended