250 likes | 348 Views
Analyzer for MPSoC Project. Yungbum Jung , Jaehwang Kim, Jaeho Shin, Kwangkeun Yi Programming Research Lab. Seoul National University. 7/12/2005@MPSOC Project Workshop. Airac Static Analyzer for Detecting All Buffer Overrun Errors in C Programs. “ static ” : no test runs
E N D
Analyzer for MPSoC Project Yungbum Jung, Jaehwang Kim, Jaeho Shin, Kwangkeun Yi Programming Research Lab. Seoul National University 7/12/2005@MPSOC Project Workshop
AiracStatic Analyzer for Detecting All Buffer Overrun Errors in C Programs • “static”: no test runs • “all”: no un-noticed overruns • “C”: full ANSI C + (GNU C) int *c = (int *)malloc(sizeof(int)*10); c[i] = 1; c[i + f()] = 1; c[*k + (*g)()] = 1; x = c+5; x[1] = 1; z->a = c; (z->a)[i] = 1; foo(c+2); int foo(int *d) {…d[i] = 1; …}
Airac: internals x1 = F1(x1,…,xN) x2 = F2(x1,…,xN) … xN = FN(x1,…,xN) C files equation solver C’ files bug identification
Technologies in Airac • sound design by abstract interpretation • accuracy improvement by • narrowing, flow-sensitivity, context pruning, static inlining(bounded polyvariance), static loop unrolling • cost reduction by • widening, economic join/partial-order operations • careful worklist order: lazy at join points
Finite Approximation struct node {int x[10]; node *next;}; x = (node *)malloc(sizeof(node)); x->next = NULL; for (i=0;;i++) { y = (node *)malloc(sizeof(node)); y->next = NULL; x->next = y; x = y; } … y x ArrayPtr = Base x Offset x Size Offset = Size = Interval x y
Caveats • soundness • typeful C programs • array sizes remain the same as declared • no semantics for error behavior (e.g. overrun, null deref.) • no semantics for completely unknown buffers • no main() then • analyzing procedure calls in their defined order • alarms • not for completely unknown buffers
Airac: performance (1/3)(commercial softwares) 3.2GHz P4, 4GB RAM
Airac vsSwat(2/2) Airac Bugs Coverity
cdc_acm.c (Linux device driver)
How to Analyze • We collect state at the each program point following semantics of a C program • We must cover all states of program
Example int main() { int i=10; int (*farr[])(int)={incr,decr,incr}; body(farr,i); return 0; } static int incr(int i) { return i+1; } static int decr(int i) { return i-1; } int body(int (*farr[])(int), int i) { int arr[10]; int idx = rand() % 3; int num = farr[idx](i); printf(“num=%d\n”, num); if (num >= 0) then return arr[num]; else body(farr, num); } idx ! [0, 2] Result: array index out of bound at (file: "test/fptr.c", line: 20, column: 21) Array name: arr Overflow (array index: [9, 11], array size: [10, 10])
Fixpoint Algorithm int A[10]; int i; int num = 10; for (i=0; i<num; i++) { A[i] = i; } A[i] = 10; start num [10, 10] i=0; i [0, 0] i<num; i [0, 0] i [0, 1] A[i] = i; i [1, 1] i [1, 2] A[0] [0, 0] A[1] [0, 1] A[0] [0, 1] i++;
Fixpoint Algorithm int A[10]; int i; int num = 10; for (i=0; i<num; i++) { A[i] = i; } A[i] = 10; start num [10, 10] i=0; i [0, 0] i<num; i [10, 10] i [0, 9] A[i] = 10; i [1, 10] A[i] = i; A[0] [0, 9] A[9] [0, 9] end i++;
Fixpoint Algorithm With Widening int A[10]; int i; int num = rand(); for (i=0; i<num; i++) { A[i] = i; } A[i] = 10; start num [-1, +1] i=0; i [0, 0] i<num; i [0, 0] i [0, 1] i [0, 0] i [0, 1] A[i] = 10; A[i] = i; i [1, 2] i [1, 1] A[0] [10, 10] A[0] [10, 10] A[1] [10, 10] A[0] [0, 0] A[1] [0, 1] A[0] [0, 1] end i++;
Fixpoint Algorithm With Widening int A[10]; int i; int num = rand(); for (i=0; i<num; i++) { A[i] = i; } A[i] = 10; start num [-1, +1] i=0; i [0,0] i<num; i [0, 1] i [0,+1] i [0,+1] i [1,+1] A[i] = 10; A[i] = i; A[0] [0, +1] A[9] [0, +1] A[0] [0,+1] A[9] [0,+1] A[0] [10,10] A[1] [10,10] end i++;
cdc_acm.c (Linux device driver)
Better than Airac • faster and more accurate • Implemented with • trace partitioning • error explanation • stack removal • code for open-source
Trace Partitioning main(void) { int arr[10]; int *p = (int *)malloc(sizeof(int)*10); int n, k; scanf(“Type an integer:\n”,&n); if(n <10 && n >=0){ k = 1; arr[n] = n; } else { k = 0; *(p + n)= 10; } if(k){ p[n] = 10; false alarm! } } start num=readInput(); n [-1,+1] n? n [0,9] n [-1,+1] k=1; k=0; k [1,1] k [0,0] arr[n]=n; *(p+n)=10; n [-1,+1] k? k [0,1] p[n]=10; end
Trace Partitioning main(void) { int arr[10]; int *p = (int *)malloc(sizeof(int)*10); int n, k; scanf(“Type an integer:\n”,&n); if(n <10 && n >=0){ k = 1; arr[n] = n; } else { k = 0; *(p + n)= 10; } if(k){ p[n] = 10; } } start num=readInput(); n [-1,+1] n? n [0,9] n [-1,+1] k=1; k=0; k [1,1] k [0,0] arr[n]=n; *(p+n)=10; k? k? p[n]=10; end end
Error Explanation int str_length = 2; inline void double_length() { str_length <<= 1; /* index참조에 사용된 변수값이 변한 지점 */ } static void get_string(char *string) { int counter; for (counter = 0; counter < str_length; counter++) { ...... } double_length(); /* index참조에 사용된 변수값이 변한 호출 */ string[str_length-1] = '\0'; /* Index: [3, 3] */ ...... } main(void) { ...... char *device_string = (char*) malloc(sizeof(char) * str_length); /* alarm이 발생한 buffer가 선언된 지점 */ get_string(device_string); /* alarm이 발생한 호출 */ ...... }
Thank you ropas.snu.ac.kr/airac