Transcript

Checking Memory Safety with BLAST

Dirk Beyer, et al.FASE 2005

KAIST CS750b2006 Fall

Seonggun Kim

2

Outline

• Memory Safety

• Two-step Approach– CCured: a type-based memory safety analyzer– BLAST: a temporal safety property checker

• CCured

• Conclusion– An improvement in the memory safety analysis

3

Memory Safety

• Essential for security systems– Invalid memory access can…

• Cause a process to crash• Produce incorrect results

– Buffer overflows are the basis of many attacks

• Memory bugs– Dereferencing null-pointer– Dereferencing outside of object bounds– Freeing non-pointers– Using freed memory

4

C and Memory Safety

• C is designed and used for efficiency– Allows many ‘unsafe’ operations

• E.g., casting to arbitrary types

– Sacrifices safety for efficiency

• A solution: Run-time checking

int array[10];…if ( (array+i >= array+10) || (array+i < array)) {exit(EXIT_FAILURE);}val = array[i];

Inserted code

5

Run-time Overhead

• Run-time checking causes slow-down– Time spent executing inserted code– E.g., IBM Rational® Purify: 10x slow-down

• But, in many C programs,– Most pointers are used safely– Only small portions are responsible for unsafe

behavior

• Static analysis can eliminate many run-time checking

6

Checking Memory Safety with BLAST

• BLAST can guarantee a pointer is safely used– by checking if the location labeled

__BLAST_ERROR is reachable– If __BLAST_ERROR is not reachable, we can

eliminate the corresponding checking codeOBJ *p = malloc(sizeof(OBJ));…if (p == NULL) { __BLAST_ERROR: ;}val = p->value;

7

Disadvantage of BLAST

• Expensive (takes long time)– Path sensitive– Generates an execution trace

• Overkill for some checksNot good for large programs

• Solution– Combine BLAST with more efficient tool: CCured

8

Combining BLAST and CCured

• CCured– Efficient– More runtime

checks

• BLAST– Expensive– More powerful– Feedback

• Together– Efficient– Fewer runtime checks– Feedback

CCured

BLAST

program code checking code

9

CCured

• The CCured System

CCuredTranslator

Compile &Execute

C ProgramInstrumented

C Program

Halt: MemorySafety Violation

Success

10

A Little More about CCured

• A type-based memory safety analyzer for C

• Classifies the pointers according to usage– Type-inference– SAFE, SEQ, WILD– Transform normal pointers to “fat-pointers”

• Annotates with run-time checks– SAFE: Null-check– SEQ: check array bound– WILD: check non-pointer and bounds and non-null

11

A Little More about CCured

• Classifies the pointers according to usage casting arith. on pointer

– SAFE: NO NO– SEQ: NO YES– WILD: YES YES (roughly)

• Annotates with run-time checks– SAFE: null-check– SEQ: array bound check (implicit null-check)– WILD: null-check + bound check + non-pointer check

• Remove redundant checks by naïve optimizer

12

SAFE Pointer Invariants and Representation

T * SAFE– Prototypical example: FILE *fp = fopen(filename, “r”);– Can be 0 or a pointer to storage containing a T– All aliases agree on the type of the referenced storage– Must do null-check before dereference– Inexpensive to store and to use (just null-check)

p

statically typed home area

T

x:assert(x.p != null);

13

SEQ Pointer Invariants and Representation

T * SEQ– Can be 0– Can be involved in pointer arithmetic: val = array++;– Null check and bounds check before use– Carries the bounds of a home area consisting of a seq

uence of T’s– All SAFE or SEQ aliases agree on the type of the refere

nced areabase p end

statically typed home area

TT … T…

assert(x.b <= x.p);assert(x.p <= x.e – sizeof(T));x:

14

WILD Pointer Invariants and Representation

T * WILD– Can be a non-pointer (any primitive)– Carries the bounds of a dynamic home area– Has only WILD pointer aliases– Must do a non-pointer and a bounds check– Must maintain the tags when writing (1 bit per

word)

dynamically typed home areaend tag bits

base pindicates which words contain base

assert(x.b != null);assert(x.b <= x.p);assert(x.p <= len(x.b) – sizeof(T’));if (typeof(*(x.p)) is *WILD) assert(tag(x.b, x.p+1) == 1);

15

Example

1: OBJ* f (int **a) {2: int **x;3: int **y = a + 10;4: for (x = a; x < y; x++)5: *x = *y;6: return (OBJ*) *y;7: }

1: OBJ *WILD f (int *WILD *SEQ a) {2: int *WILD *SEQ x;3: int *WILD *SAFE y = a + 10;4: for (x = a; x < y; x++)5: *x = *y;6: return (OBJ *WILD) *y;7: }

16

Example (cont)

1: OBJ *WILD f (int *WILD *SEQ a) {2: int *WILD *SEQ x;3: int *WILD *SAFE y = a + 10;4: for (x = a; x < y; x++)5: *x = *y;6: return (OBJ *WILD) *y;7: }

1 : OBJ *WILD f (int *WILD *SEQ a) {2 : int *WILD *SEQ x;3 : int *WILD *SAFE y = a + 10;4 : for (x = a; x < y; x++)5’: __CHECK_SEQ(x);5”; __CHECK_SAFE(y);5 : *x = *y;6 : return (OBJ *WILD) *y;7 : }

17

Experimental Results of CCured

LOC %Safe %Seq %Wild CCured Ratio Purify Ratio

compress

1590 87 12 0 1.25 28

go 29315 96 4 0 2.01 51

ijpeg 31371 36 1 62 2.15 30

li 7761 93 6 0 1.86 50

bh 2053 80 18 0 1.53 94

bisort 707 90 10 0 1.03 42

em3d 557 85 15 0 2.44 7

ks 973 92 8 0 1.47 31

health 725 93 7 0 0.94 25

18

CCured + BLAST

• Null-pointer dereferencing

1. Annotate a program using CCured• __CHECK_NULL(p);

2. Replace the call to __CHECK_NULL to __BLAST_CHECK_NULL• void __BLAST_CHECK_NULL(void *p) {

if (!p) { __BLAST_ERROR: ; }}

3. Check if __BLAST_ERROR: is reachable

19

Experimental Results

Timeout: 200s

20

Conclusion and Discussion

• An improvement in the memory safety analysis– Scalability and precision

• Pros– A kind of coarse-grained refinement– C.E. can be used for debugging

• Cons– Only handles null-pointer check

• Pointers can be regarded as Boolean variables• State explosion for array bound checking?


Top Related