tmpa-2013 vert krikun: finding defects in c and c++ pointers using static analysis and logical...
DESCRIPTION
Vert, Т., Krikun, Т. и Glukhih, М., St. Petersburg State Polytechnic University, Clausthal Technical University Finding Defects in C and C++ Pointers Using Static Analysis and Logical InferenceTRANSCRIPT
Обнаружение дефектов работы с указателями в программах на языках C/C++ с использованием статического
анализа и логического вывода
Татьяна Верт, Татьяна Крикун (Санкт-Петербургскийгосударственный политехнический университет)
Михаил Глухих (Технический университет Клаусталя)
Программное обеспечение содержит ошибки
Функциональные ошибки
o Программа не соответствует спецификации
Нефункциональные ошибки (программные дефекты)
o Использование неинициализированных переменных
o Некорректное использование указателей
o Выходы за границы массивов
2
Полнота – доля истинных обнаруженных дефектовсреди всех дефектов, имеющихся в программе
Точность – доля истинных обнаруженных дефектовсреди всех обнаруженных дефектов
3
Два из Трех
Высокая полнота
Высокая точность
Низкая ресурсоемкость
4
Анализ всех путей программы
Раздельный анализ путей (высокая точность и высокая ресурсоёмкость)
Совместный анализ путей (приемлемая ресурсоёмкость и низкая точность)
5
Зависимость – произвольная связь междузначениями двух и более переменныхпрограммы
Математически, зависимость может бытьпредставлена в виде предиката
Анализ зависимостей позволяеткомпенсировать погрешность, вызваннуюслиянием путей в ходе статического анализа
6
Использование средств логического выводадля доказательства различных утвержденийв ходе статического анализа, в частности,утверждений о наличии либо отсутствиидефектов в отдельных операторахпрограммы
7
8
9
Предикаты
Точные значения (i=const, p=&obj+shift)
Предикаты общего вида(type(obj1, obj2, ...) is
true)
Анализ точных значений
Анализ зависимостей
Хранение состояния анализируемой программы ввиде множества предикатов логики первого порядка
10
Извлечение предикатов при интерпретации операторов
Типы предикатов:
– арифметические (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
Переменными предикатов являются другие предикаты
Примеры:
– 𝑜𝑛𝑒𝑜𝑓 𝑝1, 𝑝2 – истинен хотя бы один из двух предикатов 𝑝1, 𝑝2
– 𝑜𝑝𝑝𝑜𝑠(𝑝) – предикат 𝑝 ложен
– 𝑒𝑞𝑢𝑖𝑣 𝑝1, 𝑝2 – предикаты 𝑝1 и 𝑝2 одновременно истинны или одновременно ложны
Сложные предикаты также могут быть описаны в
терминах логики первого порядка
12
Представление переменных на основе статическогооднократного присваивания (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
Выявление зависимостей при интерпретации:
– операторов определения переменной
– операторов прямого присваивания lvar=…
• Присваивания lvar=rvar
• Присваивания lvar=binary(arg1, arg2)
• Присваивания lvar=unary(rvar)
• Присваивания адреса lvar=&rvar
• Присваивания через косвенную адресациюlvar=*rvar
– операторов косвенного присваивания *lvar=rvalue
– операторов ветвления if (cond)
– операторов выделения/освобождения памяти
14
Объединение состояний программы в точках слиянияпутей
Любое условие сохраняется на выходе фи-функциитолько в том случае, если оно имелось на всех еёвходах
Если некоторой переменной программы𝑣 соответствуют разные предикатные переменные𝑣1 и 𝑣2 во входных состояниях, то для неё создаетсяновая предикатная переменная 𝑣3, при этом ввыходное состояние добавляется предикат𝑜𝑛𝑒𝑜𝑓(𝑒𝑞𝑢𝑎𝑙𝑠(𝑣3, 𝑣1), 𝑒𝑞𝑢𝑎𝑙𝑠(𝑣3, 𝑣2))
15
Если объект имеет разные версии в разных ветвях условного оператора, предикат, описывающий его значение, следует привязать к условию оператора 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 )
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]; //выход за границу массива
Корректность указателя
p = (void*)(&t)+s; v = sizeof(t);
𝑝𝑡𝑟 𝑡, 𝑝, 𝑠 , 𝑠𝑖𝑧𝑒𝑜𝑓 𝑡, 𝑣 , 𝑔𝑟𝑒𝑎𝑡𝑒𝑟_𝑒𝑞𝑢𝑎𝑙𝑠(𝑠, 0), 𝑙𝑒𝑠𝑠(𝑠, 𝑣)
𝑐𝑜𝑟𝑟𝑒𝑐𝑡_𝑝𝑡𝑟(𝑝)
Разадресация указателя v = *p;
1) Указатель на простую переменную
p = (void*)(&t);𝑝𝑡𝑟 𝑡,𝑝,0 ,𝑑𝑒𝑟𝑒𝑓(𝑝,𝑣)
𝑒𝑞𝑢𝑎𝑙𝑠(𝑡,𝑣)
2) Указатель на элемент составного объекта
p = (void*)(&a)+s; t = *(&a +s);
𝑝𝑡𝑟 𝑎, 𝑝, 𝑠 , 𝑎𝑟𝑟 𝑎, 𝑡, 𝑠 , 𝑑𝑒𝑟𝑒𝑓(𝑝, 𝑣)
𝑒𝑞𝑢𝑎𝑙𝑠(𝑡, 𝑣)
18
Сложение указателя с целочисленной константойp = (void*)(&a)+s; t=s+b; q = p+b;
𝑝𝑡𝑟 𝑎, 𝑝, 𝑠 , 𝑠𝑢𝑚 𝑡, 𝑠, 𝑏 , 𝑠𝑢𝑚(𝑞, 𝑝, 𝑏)
𝑝𝑡𝑟(𝑎, 𝑞, 𝑡)
19
Присутствие дефекта – доказательство
разрешимости предикатов:
– нулевой указатель:𝑒𝑞𝑢𝑎𝑙𝑠(𝑝𝑡𝑟, 0)
– некорректный указатель: 𝑜𝑝𝑝𝑜𝑠(𝑐𝑜𝑟𝑟𝑒𝑐𝑡_𝑝𝑡𝑟(𝑝𝑡𝑟))
Отсутствие дефекта – неразрешимость предикатов
20
… Предикаты
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
Доказатели теорем
– HOL Theorem Prover
Языки логического программирования
– Bprolog
SMT-решатели
– Z3
22
Средство-прототип
23
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 сек.
Применение алгоритмов сборки мусора
Применение алгоритмов упрощениясостояния программы
Разработка механизма выделенияинвариантов цикла
Обнаружение более широкого классапрограммных дефектов
25
Рассмотрен подход к статическому анализу сиспользованием средств логического вывода.
Приведены правила извлечения предикатов изразличных операторов анализируемой программы.
Разработаны логические правила вывода для анализауказателей и обнаружения дефектов работы суказателями.
Приведённые алгоритмы анализа реализованы висследовательском прототипе на базе анализатораAegis и SMT-решателя Microsoft Z3.
Показано значительное повышение точности посравнению с базовым анализатором.
26
27
Предикат – логическое утверждение, котороеможет быть как истинно, так и ложно, зависящее отряда предикатных объектов.
Зависимость – связь между значениями двух иболее программных объектов.
Фи-функция – точка слияния двух и более потоковвыполнения программы.
Абстрактная интерпретация – общая теория,которая задает способ аппроксимации семантикидинамических дискретных систем, в том числе -компьютерных программ.
28
Логика первого порядка (исчисление предикатов) –формальное исчисление, допускающее высказыванияотносительно переменных, фиксированных функций ипредикатов.
Граф потока управления – модель программы,представляющая в виде ориентированного графапотоки управления программы. Дуги графаотображают возможный ход вычислительногопроцесса, вершины графа соответствуют инструкциямпрограммы.
29