Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making Bounded Model Checking Interprocedural in (Static Analysis) Style

Exactpro
November 09, 2019

Making Bounded Model Checking Interprocedural in (Static Analysis) Style

Daniil Stepanov, Marat Akhin and Mikhail Belyaev

International Conference on Software Testing, Machine Learning and Complex Process Analysis (TMPA-2019)
7-9 November 2019, Tbilisi

Video: https://youtu.be/kVsQJnSlgfI

TMPA Conference website https://tmpaconf.org/
TMPA Conference on Facebook https://www.facebook.com/groups/tmpaconf/

Exactpro

November 09, 2019
Tweet

More Decks by Exactpro

Other Decks in Technology

Transcript

  1. 1 / 23 Making Bounded Model Checking Interprocedural in (Static

    Analysis) Style Daniil Stepanov, Marat Akhin, and Mikhail Belyaev Saint Petersburg Polytechnic University, Russia Jetbrains Research, Russia Novemver 9, 2019
  2. 2 / 23 Static analysis Static program analysis is the

    analysis of computer software which is performed without actually executing programs
  3. 3 / 23 Interprocedural analysis One of the hardest problems

    in BMC is interprocedural analysis Standard approach is function inlining An alternative to function inlining is context-sensitive analyses
  4. 4 / 23 Related work Craig interpolant for an inconsistent

    pair of formulas (B, Q) is a formula I such that: • B → I • (I, Q) is also an inconsistent pair of formulae • I contains only uninterpreted symbols common to B and Q External specications • specialized annotation comments • embedded domain-specic language (DSL) • external DSL Another tools: • Saturn - function summaries
  5. 6 / 23 Verication example Program: int x; int y=8,z=0,w=0;

    if (x) z = y - 1; else w = y + 1; assert (z == 7 || w == 9) Constraints: y = 8, z = x ? y -1 : 0, w = x ? 0 : y + 1, z != 7, w != 9 UNSAT. Assert always true
  6. 7 / 23 Verication example Program: int x; int y=8,z=0,w=0;

    if (x) z = y - 1; else w = y + 1; assert (z == 5 || w == 9) Constraints: y = 8, z = x ? y -1 : 0, w = x ? 0 : y + 1, z != 5, w != 9 SAT. Program contains a bug Counterexample: y = 8, x = 1, w = 0, z = 7
  7. 10 / 23 Problem void print_element(int* arr , int num){

    printf("arr=%i\n", arr[num]); // Check } void print_next_element(int* arr , int num){ print_element(arr , num + 1); } int main(int argc , char* argv []) { int a[] = {1, 2, 3}; print_element(a, 0); print_next_element(a, 0); return 0; }
  8. 11 / 23 Solution Call graph traversal Extraction of information

    which aects variables from security properties Combining of extracted information
  9. 12 / 23 Call graph for program example void print_element(int*

    arr , int num){ printf("arr=%i\n", arr[num]); } void print_next_element(int* arr , int num){ print_element(arr , num + 1); } int main(int argc , char* argv []) { int a[] = {1, 2, 3}; print_element(a, 0); print_next_element(a, 0); return 0; }
  10. 13 / 23 Collect phase Given a function F and

    its safety property Q, we collecting argument-specic information, which is relevant to Q, from all call sites of F Slicing function w.r.t current query Dealing with recursion Handling of nested calls
  11. 14 / 23 Nested call inuence example int get_next_index(int a)

    { return a + 1; } void print_element(int* arr , int num) { printf("arr=%i\n", arr[num]); } void print_next_element(int* arr , int num) { int idx = get_next_index(num); print_element(arr , idx); } int main(int argc , char* argv []) { int a[] = {1, 2, 3}; print_element(a, 0); print_next_element(a, 0); return 0; }
  12. 15 / 23 Merging information void print_element(int* arr , int

    num){ printf("arr=%i\n", arr[num]); // Check } int main(int argc , char* argv []) { int a[] = {1, 2, 3}; print_element(a, 0); return 0; } Equality predicates at junctions arr = a; num = 0
  13. 16 / 23 Resulting PS for example int get_next_index(int a)

    { return a + 1; } void print_element(int* arr , int num) { printf("arr=%i\n", arr[num]); } void print_next_element(int* arr , int num) { int idx = get_next_index(num); print_element(arr , idx); } int main(int argc , char* argv []) { int a[] = {1, 2, 3}; print_element(a, 0); print_next_element(a, 0); return 0; } main_ %0= alloca (3,(3 * 1)), @I arraydecay1=gep[inbounds ](main_ %0 ,0+0+0), print_next_element_num =0 print_next_element_arr=arraydecay1 )->( @I next_index =( print_next_element_num + 1), print_next_element_call=next_index )->( num=print_next_element_call arr=print_next_element_arr )->( @I idxprom=cast(+ Integer (64), num), @I arrayidx=gep(arr ,0+ idxprom))
  14. 17 / 23 Combining phase PS corresponds to a formula

    of the form P0 ∨ P1 ∨ . . . ∨ Pn Pi - distinct calling context For PS we have to create synthetic variable free_var
  15. 18 / 23 Resulting PS example (BEGIN <OR >( @P

    free_var =0 )->( main_ %0= alloca (3,(3 * 1)), @I main_arraydecay=gep[inbounds ]( main_ %0 ,0+0+0), num=0 arr=main_arraydecay )->( @I idxprom=cast(+ Integer (64), num), @I arrayidx=gep(arr ,0+ idxprom) ), <OR >( @P free_var =1 )->( main_ %0= alloca (3,(3 * 1)), @I main_arraydecay1=gep[inbounds ]( main_ %0 ,0+0+0), print_next_element_num =0 print_next_element_arr=main_arraydecay1 )->( @I get_next_index_add =( print_next_element_num + 1), print_next_element_call=get_next_index_add )->( num=print_next_element_call arr=print_next_element_arr )->( @I idxprom=cast(+ Integer (64), num), @I arrayidx=gep(arr ,0+ idxprom) ) END)
  16. 19 / 23 Processing to solver There are 2 equivalent

    ways of processing it via an SMT solver As one large formula Each small disjunct separately
  17. 20 / 23 Testing We tested the prototype in the

    following congurations: Basic intraprocedural BMC (intra) BMC with full inlining (inline) Our interprocedural BMC approach (inter)
  18. 22 / 23 Conclusion Our main takeaways are as follows:

    Interprocedural analysis is a bottleneck for BMC The speed of the algorithm depends not so much on the size of the project as the complexity of its internal connections