timotej kapus cristian cadar imperial college london
play

Timotej Kapus Cristian Cadar Imperial College London 1 Symbolic - PowerPoint PPT Presentation

Timotej Kapus Cristian Cadar Imperial College London 1 Symbolic Execution Program analysis technique Active research area Used in industry IntelliTest, SAGE Angr KLOVER 2 Why symbolic execution? No


  1. Timotej Kapus Cristian Cadar Imperial College London 1

  2. Symbolic Execution ● Program analysis technique ● Active research area ● Used in industry ○ IntelliTest, SAGE Angr ○ KLOVER 2

  3. Why symbolic execution? ● No false-positives! ○ Every bug found has a concrete input triggering it ● Can interact with the environment ○ I/O, unmodeled libraries ● Only relevant code executed “symbolically”, the rest is fast “native” execution 3

  4. Why (not) symbolic execution? ● Scalability, scalability, scalability ○ Constraint solving is hard ○ Path explosion 4

  5. This talk Show a segmented memory model that tackles path explosion due to dereferences of symbolic pointers through the use of static pointer alias analysis 5

  6. 1D symbolic pointers int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; if (vector[i] > 8) printf("big element\n"); else printf("small element"); 6

  7. 1D Symbolic pointers i = symbolic int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; if (vector[i] > 8) printf("big element\n"); else printf("small element"); 7

  8. 1D Symbolic pointers i = symbolic int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; vector = {1,2,...} if (vector[i] > 8) printf("big element\n"); else printf("small element"); 8

  9. 1D Symbolic pointers i = symbolic int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; vector = {1,2,...} if (vector[i] > 8) printf("big element\n"); else printf("small element"); vector[i] > 8 9

  10. 1D Symbolic pointers i = symbolic int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; vector = {1,2,...} if (vector[i] > 8) printf("big element\n"); else printf("small element"); vector[i] > 8 printf("big element\n"); 10

  11. 1D Symbolic pointers i = symbolic int i; make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; vector = {1,2,...} if (vector[i] > 8) printf("big element\n"); else printf("small element"); vector[i] > 8 printf("big element\n"); printf("small element"); 11

  12. 1D Symbolic pointers ● vector[i] is a dereference of a i = symbolic symbolic pointer char i; make_symbolic(i); ○ Concrete base address int vector[10] = {1,2,3,4,5,6,7,8,9,10}; ○ Some symbolic offset i vector = {1,2,...} if (vector[i] > 8) printf("big element\n"); ● I.e. if vector is at 0xdeedbeef else vector[i] is a printf("small element"); load (0xdeedbeef + i) vector[i] > 8 printf("big element\n"); printf("small element"); 12

  13. Constraints over memory ● Theory of arrays: ○ read: array × index → value ○ write: array × index × value → array ○ read(write(a, p, v), r) = v if p = r read(write(a, p, v), r) = read(a,r) if p ≠ r ○ ● Simply map C arrays to solver arrays ● Use concrete addresses to resolve C arrays to solver arrays 13

  14. 1D Symbolic pointers: constraints in theory of arrays int i; i = symbolic make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; if (vector[i] > 8) printf("big element"); else printf("small element"); 14

  15. 1D Symbolic pointers: constraints in theory of arrays int i; i = symbolic make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; array vector [10] = [1 2 3 4 5 6 7 8 9 10] if (vector[i] > 8) printf("big element"); else printf("small element"); 15

  16. 1D Symbolic pointers: constraints in theory of arrays int i; i = symbolic make_symbolic(i); int vector[10] = {1,2,3,4,5,6,7,8,9,10}; array vector [10] = [1 2 3 4 5 6 7 8 9 10] if (vector[i] > 8) printf("big element"); else (Read i vector ) printf("small element"); 16

  17. 2D Symbolic pointers int i, j; make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, sizeof ( int )); matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 17

  18. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 18

  19. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 19

  20. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] array matrix_1 [3] = [0 0 42] matrix[1][2] = 42; array matrix_2 [3] = [0 0 0] if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 20

  21. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] array matrix_1 [3] = [0 0 42] matrix[1][2] = 42; array matrix_2 [3] = [0 0 0] if (matrix[i][j] > 8) printf("big element\n"); else (Read i matrix ) printf("zero"); 21

  22. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] array matrix_1 [3] = [0 0 42] matrix[1][2] = 42; array matrix_2 [3] = [0 0 0] if (matrix[i][j] > 8) printf("big element\n"); else (Read j (Read i matrix )) printf("zero"); 22

  23. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] array matrix_1 [3] = [0 0 42] matrix[1][2] = 42; array matrix_2 [3] = [0 0 0] if (matrix[i][j] > 8) printf("big element\n"); else (Read j 0xdeedbeef) printf("zero"); 23

  24. 2D Symbolic pointers: constraints in theory of arrays i = symbolic int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) array matrix [3] = [0xdeedbeef 0xdeedbef0 0xdeedbef1] matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] array matrix_1 [3] = [0 0 42] matrix[1][2] = 42; array matrix_2 [3] = [0 0 0] if (matrix[i][j] > 8) printf("big element\n"); else (Read j 0xdeedbeef) printf("zero"); 24

  25. So what now? ● Forking (KLEE) ○ Concretize and fork for each possible value of matrix[i] ● State Merging / OR Expression (SAGE) ○ Create a disjunction over all possible values of matrix[i] ● Flat Memory (considered by EXE, not implemented) ○ Have the whole memory as a single array 25

  26. 2D Symbolic pointers: Forking int i, j; i = 0 make_symbolic(i, j); j = symbolic int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 26

  27. 2D Symbolic pointers: Forking int i, j; i = 0 make_symbolic(i, j); j = symbolic int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 27

  28. 2D Symbolic pointers: Forking int i, j; i = 0 make_symbolic(i, j); j = symbolic int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); array matrix_0 [3] = [0 0 0] matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else (Read j matrix_0 ) printf("zero"); 28

  29. 2D Symbolic pointers: Forking int i, j; int i, j; i = 2 make_symbolic(i, j); int i, j; j = symbolic make_symbolic(i, j); int *matrix[3]; make_symbolic(i, j); int *matrix[3]; for ( int k = 0; k < 3; k++) int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); matrix[i] = calloc(3, 4); array matrix_2 [3] = [0 0 0] matrix[1][2] = 42; matrix[1][2] = 42; matrix[1][2] = 42; if (matrix[i][j] > 8) if (matrix[i][j] > 8) if (matrix[i][j] > 8) printf("big element\n"); printf("big element\n"); else printf("big element\n"); else (Read j matrix_2 ) else printf("zero"); printf("zero"); 29 printf("zero");

  30. Path explosion 30

  31. 2D Symbolic pointers: State Merging int i, j; i = 0 ∨ 1 ∨ 2 make_symbolic(i, j); j = symbolic int *matrix[3]; for ( int k = 0; k < 3; k++) matrix[i] = calloc(3, 4); matrix[1][2] = 42; if (matrix[i][j] > 8) printf("big element\n"); else printf("zero"); 31

Recommend


More recommend