Exactpro
PRO
November 09, 2019
170

# 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

TMPA Conference website https://tmpaconf.org/

## ExactproPRO

November 09, 2019

## 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
• embedded domain-specic language (DSL)
• external DSL
Another tools:
• Saturn - function summaries

5. 5 / 23
Bounded model checking algorithm

6. 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

7. 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

8. 8 / 23
Borealis

9. 9 / 23
Program representation

10. 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;
}

11. 11 / 23
Solution
Call graph traversal
Extraction of information which aects variables from security
properties
Combining of extracted information

12. 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;
}

13. 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

14. 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;
}

15. 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

16. 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))

17. 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

18. 18 / 23
Resulting PS example
(BEGIN
(
@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)
),
(
@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),
)->(
num=print_next_element_call
arr=print_next_element_arr
)->(
@I idxprom=cast(+ Integer (64), num),
@I arrayidx=gep(arr ,0+ idxprom)
)
END)

19. 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

20. 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)

21. 21 / 23
Testing

22. 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

23. 23 / 23
Contact information
{stepanov, akhin, belyaev}@kspt.icc.spbstu.ru
Borealis repository:
https://bitbucket.org/vorpal-research/borealis