tmpa-2013 vert krikun: finding defects in c and c++ pointers using static analysis and logical...

29
Обнаружение дефектов работы с указателями в программах на языках C/C++ с использованием статического анализа и логического вывода Татьяна Верт, Татьяна Крикун (Санкт-Петербургский государственный политехнический университет) Михаил Глухих (Технический университет Клаусталя)

Upload: iosif-itkin

Post on 05-Dec-2014

492 views

Category:

Documents


0 download

DESCRIPTION

Vert, Т., Krikun, Т. и Glukhih, М., St. Petersburg State Polytechnic University, Clausthal Technical University Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

TRANSCRIPT

Page 1: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Обнаружение дефектов работы с указателями в программах на языках C/C++ с использованием статического

анализа и логического вывода

Татьяна Верт, Татьяна Крикун (Санкт-Петербургскийгосударственный политехнический университет)

Михаил Глухих (Технический университет Клаусталя)

Page 2: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Программное обеспечение содержит ошибки

Функциональные ошибки

o Программа не соответствует спецификации

Нефункциональные ошибки (программные дефекты)

o Использование неинициализированных переменных

o Некорректное использование указателей

o Выходы за границы массивов

2

Page 3: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Полнота – доля истинных обнаруженных дефектовсреди всех дефектов, имеющихся в программе

Точность – доля истинных обнаруженных дефектовсреди всех обнаруженных дефектов

3

Два из Трех

Высокая полнота

Высокая точность

Низкая ресурсоемкость

Page 4: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

4

Page 5: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Анализ всех путей программы

Раздельный анализ путей (высокая точность и высокая ресурсоёмкость)

Совместный анализ путей (приемлемая ресурсоёмкость и низкая точность)

5

Page 6: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Зависимость – произвольная связь междузначениями двух и более переменныхпрограммы

Математически, зависимость может бытьпредставлена в виде предиката

Анализ зависимостей позволяеткомпенсировать погрешность, вызваннуюслиянием путей в ходе статического анализа

6

Page 7: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Использование средств логического выводадля доказательства различных утвержденийв ходе статического анализа, в частности,утверждений о наличии либо отсутствиидефектов в отдельных операторахпрограммы

7

Page 8: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

8

Page 9: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

9

Предикаты

Точные значения (i=const, p=&obj+shift)

Предикаты общего вида(type(obj1, obj2, ...) is

true)

Анализ точных значений

Анализ зависимостей

Хранение состояния анализируемой программы ввиде множества предикатов логики первого порядка

Page 10: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

10

Page 11: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Извлечение предикатов при интерпретации операторов

Типы предикатов:

– арифметические (A=B+C, A=B*C, A=B%C, и т. д.)

– логические (A=¬B, A=B∨D, A=B∧D, A→B)

– сравнения (A>B, A<B, A≥B, A≤B, A≠B)

– работа с указателями(A=&B+C, A=*B)

– обращение к составному объекту(A=B[C], A=B.C)

– размер объекта(A = sizeof B, A ≤ sizeof B)

– …

Представление: 𝑝(𝑣1, 𝑣2, … , 𝑣𝑛), где 𝑝 -функциональный символ, 𝑣𝑖 , 𝑖 = 1…𝑛 – предикатныепеременные 11

Page 12: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Переменными предикатов являются другие предикаты

Примеры:

– 𝑜𝑛𝑒𝑜𝑓 𝑝1, 𝑝2 – истинен хотя бы один из двух предикатов 𝑝1, 𝑝2

– 𝑜𝑝𝑝𝑜𝑠(𝑝) – предикат 𝑝 ложен

– 𝑒𝑞𝑢𝑖𝑣 𝑝1, 𝑝2 – предикаты 𝑝1 и 𝑝2 одновременно истинны или одновременно ложны

Сложные предикаты также могут быть описаны в

терминах логики первого порядка

12

Page 13: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Представление переменных на основе статическогооднократного присваивания (SSA):

– Каждой переменной значение присваиваетсятолько один раз;

– В случае присвоения нескольких значенийиспользуется версионирование переменных.

x = a + b; x.1 = a.1 + b.1;

y = x * x; y.1 = x.1 * x.1;

x = c + d; x.2 = c.1 + d.1;

𝑠𝑢𝑚 𝑥1, 𝑎1, 𝑏1mult 𝑦1, 𝑥1, 𝑥1s𝑢𝑚 𝑥2, 𝑐1, 𝑑1

13

Page 14: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Выявление зависимостей при интерпретации:

– операторов определения переменной

– операторов прямого присваивания lvar=…

• Присваивания lvar=rvar

• Присваивания lvar=binary(arg1, arg2)

• Присваивания lvar=unary(rvar)

• Присваивания адреса lvar=&rvar

• Присваивания через косвенную адресациюlvar=*rvar

– операторов косвенного присваивания *lvar=rvalue

– операторов ветвления if (cond)

– операторов выделения/освобождения памяти

14

Page 15: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Объединение состояний программы в точках слиянияпутей

Любое условие сохраняется на выходе фи-функциитолько в том случае, если оно имелось на всех еёвходах

Если некоторой переменной программы𝑣 соответствуют разные предикатные переменные𝑣1 и 𝑣2 во входных состояниях, то для неё создаетсяновая предикатная переменная 𝑣3, при этом ввыходное состояние добавляется предикат𝑜𝑛𝑒𝑜𝑓(𝑒𝑞𝑢𝑎𝑙𝑠(𝑣3, 𝑣1), 𝑒𝑞𝑢𝑎𝑙𝑠(𝑣3, 𝑣2))

15

Page 16: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Если объект имеет разные версии в разных ветвях условного оператора, предикат, описывающий его значение, следует привязать к условию оператора if

Пример: Предикатное состояние

if (size > 0)

q = malloc(size);

else

q = 0;

16

Истинная ветвь Ложная ветвь

𝑔𝑟𝑒𝑎𝑡𝑒𝑟 𝑠𝑖𝑧𝑒1, 0 𝑙𝑒𝑠𝑠_𝑒𝑞𝑢𝑎𝑙𝑠 𝑠𝑖𝑧𝑒1, 0

𝑠𝑖𝑧𝑒𝑜𝑓 𝑑𝑦𝑛, 𝑠𝑖𝑧𝑒1 𝑒𝑞𝑢𝑎𝑙𝑠 𝑞2, 0

𝑝𝑡𝑟 𝑑𝑦𝑛, 𝑞1, 0

Выходное состояние

𝑜𝑛𝑒𝑜𝑓(𝑒𝑞𝑢𝑎𝑙𝑠(𝑞3, 𝑞1), 𝑒𝑞𝑢𝑎𝑙𝑠(𝑞3, 𝑞2))

𝑒𝑞𝑢𝑖𝑣(𝑙𝑒𝑠𝑠_𝑒𝑞𝑢𝑎𝑙𝑠 𝑠𝑖𝑧𝑒1, 0 , 𝑒𝑞𝑢𝑎𝑙𝑠 𝑞3, 0 )

Page 17: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

17

Обнаружение дефектов при анализе операцииразадресации *ptr и операции обращения по индексуptr[i]

• Некорректное использование указателей:int* ptr = 0;

if (array[0]>0)

ptr=array;

int val=*ptr; //разадресация нулевого указателя

• Выход за границу объектаint a, i;

int array[9];

i = 10;

a = array[i]; //выход за границу массива

Page 18: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Корректность указателя

p = (void*)(&t)+s; v = sizeof(t);

𝑝𝑡𝑟 𝑡, 𝑝, 𝑠 , 𝑠𝑖𝑧𝑒𝑜𝑓 𝑡, 𝑣 , 𝑔𝑟𝑒𝑎𝑡𝑒𝑟_𝑒𝑞𝑢𝑎𝑙𝑠(𝑠, 0), 𝑙𝑒𝑠𝑠(𝑠, 𝑣)

𝑐𝑜𝑟𝑟𝑒𝑐𝑡_𝑝𝑡𝑟(𝑝)

Разадресация указателя v = *p;

1) Указатель на простую переменную

p = (void*)(&t);𝑝𝑡𝑟 𝑡,𝑝,0 ,𝑑𝑒𝑟𝑒𝑓(𝑝,𝑣)

𝑒𝑞𝑢𝑎𝑙𝑠(𝑡,𝑣)

2) Указатель на элемент составного объекта

p = (void*)(&a)+s; t = *(&a +s);

𝑝𝑡𝑟 𝑎, 𝑝, 𝑠 , 𝑎𝑟𝑟 𝑎, 𝑡, 𝑠 , 𝑑𝑒𝑟𝑒𝑓(𝑝, 𝑣)

𝑒𝑞𝑢𝑎𝑙𝑠(𝑡, 𝑣)

18

Page 19: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Сложение указателя с целочисленной константойp = (void*)(&a)+s; t=s+b; q = p+b;

𝑝𝑡𝑟 𝑎, 𝑝, 𝑠 , 𝑠𝑢𝑚 𝑡, 𝑠, 𝑏 , 𝑠𝑢𝑚(𝑞, 𝑝, 𝑏)

𝑝𝑡𝑟(𝑎, 𝑞, 𝑡)

19

Page 20: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Присутствие дефекта – доказательство

разрешимости предикатов:

– нулевой указатель:𝑒𝑞𝑢𝑎𝑙𝑠(𝑝𝑡𝑟, 0)

– некорректный указатель: 𝑜𝑝𝑝𝑜𝑠(𝑐𝑜𝑟𝑟𝑒𝑐𝑡_𝑝𝑡𝑟(𝑝𝑡𝑟))

Отсутствие дефекта – неразрешимость предикатов

20

Page 21: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

… Предикаты

int x,b; sizeof(arr, 20),

std::cin >> x; equals(arr[0]_0, 0),

int arr[5]={0,1,2,3,4}; equals(arr[1]_0, 1),

if (x>0){ equals(arr[2]_0, 2),

b = arr[x]; equals(arr[3]_0, 3),

} equals(arr[4]_0, 4),

… greater(x_0, 0),

ptr(arr, tmp1_0, 0)),

mult(tmp2_0, x_0, 4),

sum(tmp3_0, tmp1_0,tmp2_0)

ptr(arr, tmp3, tmp2), sizeof(arr, 20), or(less(tmp2, 0),

greater_equals(tmp2, 20)) = > oppos(correct_ptr(tmp3))

21

Page 22: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Доказатели теорем

– HOL Theorem Prover

Языки логического программирования

– Bprolog

SMT-решатели

– Z3

22

Page 23: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Средство-прототип

23

Page 24: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

24

Пример Истинных

дефектов

Разработанная

система

Aegis

(Digitek Labs)

FlexeLint

(Gimpel Software)

дефектов

найдено

ложных

дефектов

найдено

дефектов

найдено

ложных

дефектов

найдено

дефектов

найдено

ложных

дефектов

найдено

1 1 1 0 1 0 1 0

2 2 2 0 0 0 0 0

3 1 1 0 1 0 0 0

4 2 2 0 3 1 3 1

5 0 0 0 1 1 1 1

6 2 2 0 3 1 1 1

7 0 0 0 2 2 1 1

8 2 1 0 1 0 1 0

Полнота 95% 75% 45%

Точность 95% 68% 60%

Среднее время 53 сек. 5 сек. 4 сек.

Page 25: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Применение алгоритмов сборки мусора

Применение алгоритмов упрощениясостояния программы

Разработка механизма выделенияинвариантов цикла

Обнаружение более широкого классапрограммных дефектов

25

Page 26: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Рассмотрен подход к статическому анализу сиспользованием средств логического вывода.

Приведены правила извлечения предикатов изразличных операторов анализируемой программы.

Разработаны логические правила вывода для анализауказателей и обнаружения дефектов работы суказателями.

Приведённые алгоритмы анализа реализованы висследовательском прототипе на базе анализатораAegis и SMT-решателя Microsoft Z3.

Показано значительное повышение точности посравнению с базовым анализатором.

26

Page 27: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

27

Page 28: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Предикат – логическое утверждение, котороеможет быть как истинно, так и ложно, зависящее отряда предикатных объектов.

Зависимость – связь между значениями двух иболее программных объектов.

Фи-функция – точка слияния двух и более потоковвыполнения программы.

Абстрактная интерпретация – общая теория,которая задает способ аппроксимации семантикидинамических дискретных систем, в том числе -компьютерных программ.

28

Page 29: TMPA-2013 Vert Krikun: Finding Defects in C and C++ Pointers Using Static Analysis and Logical Inference

Логика первого порядка (исчисление предикатов) –формальное исчисление, допускающее высказыванияотносительно переменных, фиксированных функций ипредикатов.

Граф потока управления – модель программы,представляющая в виде ориентированного графапотоки управления программы. Дуги графаотображают возможный ход вычислительногопроцесса, вершины графа соответствуют инструкциямпрограммы.

29