SlideShare a Scribd company logo
Заголовок
ptsecurity.com
Формальная
верификация
кода на языке
Си
м.н.с. Ефремов Д.В. (аспирант ВШЭ)
ИСП РАН efremov@ispras.ru
Заголовок
• Hacker-Proof Code Confirmed (quantamagazine)
• Computer Scientists Close In on Perfect, Hack-Proof Code (wired)
• Kaspersky Launches ‘Unhackable’ OS (guidingtech)
• Unhackable kernel could keep all computers safe from cyberattack
(newscientist)
• Is This Security-Focused Linux Kernel Really UnHackable?
(thehackernews)
• Hack-resilient
• Error-free code
• Yale develops world's first hacker-resistant operating system
(ibtimes)
Немного заголовков
Заголовок
• Crowd Sourced Formal Verification (CSFV) (VERIGAMES)
• High-Assurance Cyber Military Systems (HACMS)
• Formally Verify Blockchain-Based Integrity Monitoring System
• A Diagnostic Approach for Persistent Threat Detection (ADAPT)
• Cyber Fault-tolerant Attack Recovery (CFAR)
• Testing and Modeling of Brandeis Artifacts (TAMBA)
• Clean-slate design of Resilient, Adaptive, Secure Hosts (CRASH)
DARPA
Заголовок
• Orange Book: division A (verified protection) (A1, Beyond A1)
• Common Criteria (EAL7)
• DO-178C/DO-333 "Formal Methods Supplement to DO-178C and
DO-278A”
• IEC 61508 (SIL4)
• ФСТЭК России ГОСТ Р ИСО/МЭК 15408 «Требованиях
безопасности информации к операционным системам» профили
защиты операционных систем общего назначения (типа «А»)
Стандарты
Заголовок
•Verified Software Initiative (2007)
•Dafny
•Whiley
•SPARK/Ada
•The Key Project/Java
•Spec#/Sing#
Академический фронт
Заголовок
• Верификация - проверка соответствия программного
обеспечения предъявляемым к нему требованиям;
• Дедуктивная верификация – представление
корректности программы как набора математических
утверждений, называемых условиями верификации,
выполнение которых проверяется автоматическими или
интерактивными доказателями теорем;
• Спецификация - набор требований и параметров,
которым удовлетворяет некоторый объект
(представлена в виде мат. модели, тестовых наборов,
формальной спецификации)
Верификация
Заголовок
Высшая школа экономики, Москва, 2016
Дедуктивная верификация программ
• Лекция Алана Тьюринга Лондонскому математическому
обществу
• Методы Флойда/Хоара
• Инструменты дедуктивной верификации для Си, Java, С#
• SunRise, ESC/Java, Frama-C, LOOP, Boogie/VCC
• Применение к реальным проектам небольшого размера
• Атомная энергетика (Англия, Франция)
• Авионика (Airbus, NASA)
• Компоненты специализированных ОС (seL4, Hyper-V)
Заголовок
• Компилятор и линковщик работают корректным образом
• В программном обеспечении, использующемся при верификации, не
произошло ошибок
• Компьютер функционирует таким образом, как мы думаем об этом
(rowhammer)
• Нижележащий слой ПО (например, ОС, прошивка сетевой карты,
микрокод процессора) функционирует в рамках нашего
представления о том, что он должен делать и что не должен делать
(и ещё не содержит ошибок)
• Пользователь компьютера, если он есть, специально не «пакостит»
• Выполнены предположения о входных данных программы, о
начальном состоянии
• …
На что опираться vs. Что вы будете с этого иметь (1)
Заголовок
•Гарантии того, что программное
обеспечение функционирует в точном
соответствии с требованиями, к нему
предъявляемыми, на всех входных
данных, начальных состояниях, при
любом поведении окружения * **
• * В предположении что все предположения выполнены
• ** И не осталось предположений, которых мы не занесли в списочек
На что опираться vs. Что вы будете с этого иметь (2)
Заголовок
• Отсутствие деления на ноль
𝑏 ≠ 0 𝑐 ≔
𝑎
𝑏
{𝑎 = 𝑐 ∗ 𝑏}
Примеры требований по безопасности (safety)
Заголовок
• Отсутствие деления на ноль
𝑏 ≠ 0 𝑐 ≔
𝑎
𝑏
{𝑎 = 𝑐 ∗ 𝑏}
Примеры требований по безопасности (safety)
Заголовок
• Отсутствие деления на ноль
𝑏 ≠ 0 𝑐 ≔
𝑎
𝑏
{𝑎 = 𝑐 ∗ 𝑏}
Примеры требований по безопасности (safety)
Заголовок
• Отсутствие деления на ноль
𝑏 ≠ 0 𝑐 ≔
𝑎
𝑏
{𝑎 = 𝑐 ∗ 𝑏}
• Отсутствие целочисленного переполнения
𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX
𝑏 ≔ 𝑎 + 1
𝑎 = 𝑏 − 1
Примеры требований по безопасности (safety)
Заголовок
• Отсутствие деления на ноль
𝑏 ≠ 0 𝑐 ≔
𝑎
𝑏
{𝑎 = 𝑐 ∗ 𝑏}
• Отсутствие целочисленного переполнения
𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX
𝑏 ≔ 𝑎 + 1
𝑎 = 𝑏 − 1
• Отсутствие разыменования нулевого указателя
valid 𝑎 ∗ 𝑎 ≔ 1{∗ 𝑎 = 1}
• …
Примеры требований по безопасности (safety)
Заголовок
• Массив отсортирован
∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1]
• Функция возвращает всегда положительное значение
 𝑟𝑒𝑠𝑢𝑙𝑡 > 0
Примеры требований по функциональности
Заголовок
• Массив отсортирован
∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1]
• Функция возвращает всегда положительное значение
 𝑟𝑒𝑠𝑢𝑙𝑡 > 0
• Функция может менять порядок элементов в массиве, но
не его содержимое 0_0
Примеры требований по функциональности
Заголовок
• Массив отсортирован
∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1]
• Функция возвращает всегда положительное значение
 𝑟𝑒𝑠𝑢𝑙𝑡 > 0
• Функция может менять порядок элементов в массиве, но
не его содержимое 0_0
• Если в дереве присутствует искомый элемент, то
функциях его обязательно найдёт O_O
Примеры требований по функциональности
Заголовок
• Массив отсортирован
∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1]
• Функция возвращает всегда положительное значение
 𝑟𝑒𝑠𝑢𝑙𝑡 > 0
• Функция может менять порядок элементов в массиве, но
не его содержимое 0_0
• Если в дереве присутствует искомый элемент, то
функциях его обязательно найдёт O_O
• Программа не держит в памяти секретные данные
дольше, чем это требуется для их обработки @_@
• …
Примеры требований по функциональности
Заголовок
• CompCert – компилятор языка Clight (Coq > Ocaml)
• seL4 – микроядро L4 (Cparse > Isabelle/HOL)
• CertiKOS – Certified Kit Operating System
• Ironclad – End-to-End Security via Automated Full-
System Verification (Dafny)
• FSCQ – A Formally Certified Crash-proof File System (Coq)
• Quark – веб-браузер с верифицированным ядром (Coq)
Известные проекты
Заголовок
Высшая школа экономики, Москва, 2016
Что можно сказать о функции на языке Си по её коду? (1)
• Она существует и написана на языке Си;
Заголовок
Высшая школа экономики, Москва, 2016
Что можно сказать о функции на языке Си по её коду? (1)
• Она существует и написана на языке Си;
• Это чистая функция;
• Она вычисляет среднее между двумя целыми числами;
Заголовок
Высшая школа экономики, Москва, 2016
Что можно сказать о функции на языке Си по её коду? (1)
• Она существует и написана на языке Си;
• Это чистая функция;
• Она вычисляет среднее между двумя целыми числами;
• При определённых условиях возможно целочисленное переполнение.
Заголовок
Высшая школа экономики, Москва, 2016
Что можно сказать о функции на языке Си по её коду? (2)
• Возможно ли целочисленное переполнение в том контексте,
где функция вызывается?
• Считать ли возможное целочисленное переполнение
ошибкой?
Заголовок
Высшая школа экономики, Москва, 2016
Что можно сказать о функции на языке Си по её коду? (3)
• Контекст: функция двоичного
поиска;
• Индексы l и h неотрицательны,
l не превосходит h;
• Возможна ошибка выхода за
границу массива при
целочисленном
переполнении.
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (1)
•Описать контекст вызова:
𝜙: 𝑍 × 𝑍 → ⊤, ⊥
𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (1)
•Описать контекст вызова:
𝜙: 𝑍 × 𝑍 → ⊤, ⊥
𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏
•Описать требования, которым должны
удовлетворять результаты:
𝜓: 𝑍 × 𝑍 × 𝑍 → {⊤, ⊥}
𝜓 𝑎, 𝑏, 𝑟𝑒𝑠𝑢𝑙𝑡 ≡ 𝑟𝑒𝑠𝑢𝑙𝑡 =
𝑎 + 𝑏
2
ЗаголовокКак доказать что код функции корректен? (2)
• Формализовать понятие ошибки (целочисленное
переполнение):
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥}
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇
ЗаголовокКак доказать что код функции корректен? (2)
• Формализовать понятие ошибки (целочисленное
переполнение):
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥}
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇
• Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая
возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим
программным кодом если завершается и завершается без
ошибки, иначе возвращается специальное значение 𝜔
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (2)
• Формализовать понятие ошибки (целочисленное
переполнение):
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥}
𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇
• Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая
возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим
программным кодом если завершается и завершается без
ошибки, иначе возвращается специальное значение 𝜔
• Доказать полную корректность:
∀𝑎, 𝑏 𝜙 𝑎, 𝑏 ⇒ 𝑀 𝑎𝑣𝑟 𝑎, 𝑏 ≠ 𝜔 && 𝜓 𝑎, 𝑏, 𝑀 𝑎𝑣𝑟 𝑎, 𝑏
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
axiom H1: to_int o1 = 2
axiom H2: to_int o2 = (to_int a + to_int b)
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
axiom H1: to_int o1 = 2
axiom H2: to_int o2 = (to_int a + to_int b)
goal avr_safety:
in_bounds 2 ->
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
axiom H1: to_int o1 = 2
axiom H2: to_int o2 = (to_int a + to_int b)
goal avr_safety:
in_bounds 2 ->
in_bounds(to_int a + to_int b) ->
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
axiom H1: to_int o1 = 2
axiom H2: to_int o2 = (to_int a + to_int b)
goal avr_safety:
in_bounds 2 ->
in_bounds(to_int a + to_int b) ->
not to_int o1 = 0 ->
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (3)
function to_int bint : int
function of_int int : bint
predicate in_bounds (n:int) = -2147483648 <= n && n <=
2147483647
constant a, b, o1, o2: bint
axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
axiom H1: to_int o1 = 2
axiom H2: to_int o2 = (to_int a + to_int b)
goal avr_safety:
in_bounds 2 ->
in_bounds(to_int a + to_int b) ->
not to_int o1 = 0 ->
in_bounds(div (to_int o2) (to_int o1))
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (4)
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (4)
Условие верификации
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (4)
Условие верификации
Исправление кода
Заголовок
Высшая школа экономики, Москва, 2016
Как доказать что код функции корректен? (4)
Условие верификации
Исправление кода
Уточнение спецификаций
Стек
инструментов
дедуктивной
верификации
CIL
CIL with annotations
С program with
ACSL annotations
Frama-C
Высшая школа экономики, Москва, 2016
Стек
инструментов
дедуктивной
верификации
CIL
CIL with annotations
С program with
ACSL annotations
Jessie program
(with annotations built-in)
Jessie translator
Why3 support
Jessie2
CIL
visitors (rewriters)
Frama-C
Jessie plugin
Высшая школа экономики, Москва, 2016
Стек
инструментов
дедуктивной
верификации
CIL
CIL with annotations
С program with
ACSL annotations
Jessie program
(with annotations built-in)
Jessie translator
Why3 support
Why3 VC generator
Why3 WhyML modules
Verification conditions
in Why3MLVC transformations
Why3 encoders + drivers
Logical formulas/scripts in
SMT-LIB/SMT-LIBv2/native format
Coq, PVS, Isabelle
proof templates
Why3
transformation/proof/shapes
database
Alt-Ergo Z3 CVC4 Coq PVS
Why3 IDE
...
Jessie2
CIL
visitors (rewriters)
Frama-C
Jessie plugin
Why3
Isabelle ...
Заголовок
• Код
• Что формальная верификация может проверить и чего не может?
• Формальные спецификации
• Можно ли разработать формальные спецификации до стадии
написания кода?
• Что в них должно быть отображено?
• Что инструмент (его модели и теоретическая основа) позволяет в них
отобразить?
• Насколько полными/точными/непротиворечивыми должны быть
спецификации?
• Код и спецификации
• Можно ли дважды ошибиться и при этом доказать, что всё корректно?
Где может встречаться ошибка?
Заголовок
• Зависит от того, какие модели заложены в инструментах
верификации
• Памяти, целочисленной арифметики, битовой арифметики…
• Чем сложнее модель, тем детальнее она отражает
действительность
• Чем сложнее модель, тем более сложными становятся формулы
условий верификации
• Чем сложнее формулы, тем хуже на них работают
автоматические доказатели логических формул
• Аналогия QEMU⟺BOCHS
Ошибки, которые «ловятся» в коде (1)
Заголовок
• Деление на ноль
• Разыменование указателя
• Некратный сдвиг типизированного указателя
• Выход за границу массива
• Целочисленное переполнение
• Переполнение при операциях с плавающей запятой
• Бесконечные циклы
• …
Ошибки, которые «ловятся» в коде (2)
Заголовок
•А как вы моделируете память (read, write)?
char *p = "побольше цинизма, Киса";
p[0] = 'П';
•А как вы моделируете указатели
(переполнение указателей)?
char *p = UINT_MAX - 1;
strlen(p);
Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)
Заголовок
•А как вы моделируете стек (ограниченный или
безграничный)?
#define STACK_SIZE 1000*0x1000
//@ ensures result == 1;
int main(void) {
int a[STACK_SIZE];
memset(a, 0, STACK_SIZE);
a[STACK_SIZE-1] = 1;
return a[STACK_SIZE-1];
}
Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)
Заголовок
•Что мы пишем в функциональные требования?
ensures result >= 0;
long abs(int a) { return 4; }
Ошибки, специфичные для спецификаций (полнота) (1)
Заголовок
•Что мы пишем в функциональные требования?
ensures result >= 0;
long abs(int a) { return 4; }
•Как мы пишем функциональные требования?
unsigned abs(int a)
return a >= 0 ? a :-((long)a);
ensures result == a || result == -a;
Ошибки, специфичные для спецификаций (полнота) (1)
Заголовок
•Что мы пишем в функциональные требования?
ensures result >= 0;
long abs(int a) { return 4; }
•Как мы пишем функциональные требования?
unsigned abs(int a)
return a >= 0 ? a :-((long)a);
ensures result == a || result == -a;
ensures result == -a <==> a < 0;
Ошибки, специфичные для спецификаций (полнота) (1)
Заголовок
•Что мы пишем в функциональные требования?
ensures result >= 0;
long abs(int a) { return 4; }
•Как мы пишем функциональные требования?
unsigned abs(int a)
return a >= 0 ? a :-((long)a);
ensures result == a || result == -a;
ensures result == -a <==> a < 0;
ensures a>=0 ? result==a : result==-a;
Ошибки, специфичные для спецификаций (полнота) (1)
Заголовок
• Какие свойства мы выражаем в требованиях?
requires n == 2 && valid(a+(0..n-1));
ensures forall integer i, j; 0 <= i < j < n ==>
a[i] <= a[j]; // отсортированность
void sort(size_t n, int a[n]) { a[0] = 1; a[1] = 2; }
Ошибки, специфичные для спецификаций (полнота) (2)
Заголовок
• Какие свойства мы выражаем в требованиях?
requires n == 2 && valid(a+(0..n-1));
ensures forall integer i, j; 0 <= i < j < n ==>
a[i] <= a[j]; // отсортированность
void sort(size_t n, int a[n]) { a[0] = 1; a[1] = 2; }
• Как правильно их выразить?
... //сохранение всех элементов
ensures forall int *i; a <= i < a + n ==>
Сount{Pre}(a, n, *i) == Сount{Post}(a, n, *i);
void sort(size_t n,int a[n]){if(a[0]>a[1])swap(a,0,1);}
Ошибки, специфичные для спецификаций (полнота) (2)
Заголовок
• Противоречие в логических утверждениях
a == 1 && a == 2
Ошибки, специфичные для спецификаций (противоречия) (1)
Заголовок
• Противоречие в логических утверждениях
a == 1 && a == 2
• Изо лжи следует всё, что угодно
requires 0 == 1;
ensures result == 0 && result == 1 &&
result == 2;
int main(void) { int a = 1; return a / 0; }
Ошибки, специфичные для спецификаций (противоречия) (1)
Заголовок
• Противоречие в логических утверждениях
a == 1 && a == 2
• Изо лжи следует всё, что угодно
requires 0 == 1;
ensures result == 0 && result == 1 &&
result == 2;
int main(void) { int a = 1; return a / 0; }
• Мертвый код
void test(int a){ if (a > 0) if (a < 0) a/0; }
Ошибки, специфичные для спецификаций (противоречия) (1)
Заголовок
• Verification Engineering of Safety
and Security Critical Industrial
Applications (VESSEDIA)
• STANCE project
• Programme Inter Carnot
Fraunhofer from BMBF and ANR
• Начало проекта - 2009
Пример ошибки в реальном проекте (1)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
Пример ошибки в реальном проекте (2)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
axiom CountSectionEmpty:
forall int *a, v, integer m, n;
n <= m ==> Count(a, m, n, v) == 0;
Пример ошибки в реальном проекте (2)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
axiom CountSectionEmpty:
forall int *a, v, integer m, n;
n <= m ==> Count(a, m, n, v) == 0;
axiom CountSectionHit:
forall int *a, v, integer n, m;
a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1;
Пример ошибки в реальном проекте (2)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
axiom CountSectionEmpty:
forall int *a, v, integer m, n;
n <= m ==> Count(a, m, n, v) == 0;
axiom CountSectionHit:
forall int *a, v, integer n, m;
a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1;
int a = 5;
assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0;
Пример ошибки в реальном проекте (2)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
axiom CountSectionEmpty:
forall int *a, v, integer m, n;
n <= m ==> Count(a, m, n, v) == 0;
axiom CountSectionHit:
forall int *a, v, integer n, m;
a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1;
int a = 5;
assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0;
assert Count(&a+1,0,0,5) == Count(&a + 1,0,-1,5)+1;
Пример ошибки в реальном проекте (2)
Заголовок
logic integer Count{L}(int *a, integer m, integer n, int v);
axiom CountSectionEmpty:
forall int *a, v, integer m, n;
n <= m ==> Count(a, m, n, v) == 0;
axiom CountSectionHit:
forall int *a, v, integer n, m;
a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1;
int a = 5;
assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0;
assert Count(&a+1,0,0,5) == Count(&a + 1,0,-1,5)+1;
assert 0 == 1;
Пример ошибки в реальном проекте (2)
Заголовок
size_t strlen(const char *s) {
const char *sc;
for (sc = s; *sc != '0'; ++sc)
/* nothing */;
return sc - s;
}
Как выглядит разработка спецификации для функции? (1)
Заголовок
requires exists size_t i;
0 <= i && s[i] == '0' &&
valid(s+(0..i));
size_t strlen(const char *s)
Как выглядит разработка спецификации для функции? (2) (Контракт)
Заголовок
requires exists size_t i;
0 <= i && s[i] == '0' &&
valid(s+(0..i));
assigns nothing;
size_t strlen(const char *s)
Как выглядит разработка спецификации для функции? (2) (Контракт)
Заголовок
requires exists size_t i;
0 <= i && s[i] == '0' &&
valid(s+(0..i));
assigns nothing;
ensures s[result] == '0';
size_t strlen(const char *s)
Как выглядит разработка спецификации для функции? (2) (Контракт)
Заголовок
requires exists size_t i;
0 <= i && s[i] == '0' &&
valid(s+(0..i));
assigns nothing;
ensures s[result] == '0';
ensures forall size_t i; 0 <= i< result ==>
s[i] != '0';
size_t strlen(const char *s)
Как выглядит разработка спецификации для функции? (2) (Контракт)
Заголовок
const char *sc;
/*@ loop invariant s <= sc;
*/
for (sc = s; *sc != '0'; ++sc)
/* nothing */;
return sc - s;
Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
Заголовок
const char *sc;
/*@ loop invariant s <= sc;
loop invariant forall char *p;
s <= p < sc ==> *p != '0';
*/
for (sc = s; *sc != '0'; ++sc)
/* nothing */;
return sc - s;
Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
Заголовок
const char *sc;
/*@ loop invariant s <= sc;
loop invariant forall char *p;
s <= p < sc ==> *p != '0';
loop variant SIZE_MAX - (sc - s);
*/
for (sc = s; *sc != '0'; ++sc)
/* nothing */;
return sc - s;
Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (5) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
ЗаголовокКак выглядит разработка спецификации для функции? (6) (Инструменты)
Заголовок
logic integer strlen(char *s) =
s == '0' ? 0 : 1 + strlen(s + 1);
Как выглядит разработка спецификации для функции? (7) (аксиоматика)
Заголовок
logic integer strlen(char *s) =
s == '0' ? 0 : 1 + strlen(s + 1);
lemma strlen_shift:
forall char *s;
(exists integer i; 0 <= i && s[i] == '0') &&
*s != '0' ==>
strlen(s) == strlen(s + 1) + 1;
Как выглядит разработка спецификации для функции? (7) (аксиоматика)
Заголовок
logic integer strlen(char *s) =
s == '0' ? 0 : 1 + strlen(s + 1);
lemma strlen_shift:
forall char *s;
(exists integer i; 0 <= i && s[i] == '0') &&
*s != '0' ==>
strlen(s) == strlen(s + 1) + 1;
lemma strlen_strend:
forall char *s; *s == '0' ==> strlen(s) == 0;
Как выглядит разработка спецификации для функции? (7) (аксиоматика)
Заголовок
/*@ ...
ensures result == strlen(s);
*/
size_t strlen_str(const char *s) {
const char *sc;
/*@ ...
loop invariant strlen(s) == strlen(sc) + (sc - s);
...
*/
for (sc = s; *sc != '0'; ++sc)
/* nothing */;
return sc - s;
}
Как выглядит разработка спецификации для функции? (8) (аксиоматика)
Заголовок
• Трудоёмкость
• В разы больше чем разработка
• Каждой строчке кода соответствует ~3-5 строчек
спецификаций
• Инструменты поддерживают не все конструкции языков
программирования
• Goto назад по коду
• Switch с “проваливающимися” case
• Цикломатическая сложность функций (< 15)
• …
• Применяется для проектов небольшого размера
• обычно не более 10 тыс. строк
Ограничения по применению дедуктивной верификации
Заголовок
• Серебряной пули не существует
• Формальная верификация имеет как плюсы, так и минусы
• Сложность применения
• Что мы доказываем (безопасность(safety), функциональные
требования)
• Предположения, исходя из которых проводится верификация
• Формальная верификация не гарантирует отсутствие всех ошибок
• Формальная верификация не является заменой тестированию
• При дедуктивной верификации существенна роль человека
Резюме
Заголовок
• Система верификации на основе Frama-
C+Jessie+Why3 опубликована под свободной
лицензией
• http://linuxtesting.ru/astraver
• Руководства и введение в инструменты на русском
• http://astraver.linuxtesting.org/
• Спецификации для библиотечных функций ядра Linux
• https://github.com/evdenis/verker/
Дополнительная информация
Заголовок
ptsecurity.com
Спасибо!
Спасибо!

More Related Content

What's hot

Кто сказал «WAF»?
Кто сказал «WAF»?Кто сказал «WAF»?
Кто сказал «WAF»?
Positive Development User Group
 
Flask, гордость и предубеждение
Flask, гордость и предубеждениеFlask, гордость и предубеждение
Flask, гордость и предубеждение
Yehor Nazarkin
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Stas Vyschepan
 
Эвристические методы защиты приложений
Эвристические методы защиты приложенийЭвристические методы защиты приложений
Эвристические методы защиты приложений
Positive Hack Days
 
От экспериментального программирования к промышленному: путь длиной в 10 лет
От экспериментального программирования к промышленному: путь длиной в 10 летОт экспериментального программирования к промышленному: путь длиной в 10 лет
От экспериментального программирования к промышленному: путь длиной в 10 лет
Positive Hack Days
 
Пост-эксплуатация веб-приложений в тестах на проникновение
Пост-эксплуатация веб-приложений в тестах на проникновениеПост-эксплуатация веб-приложений в тестах на проникновение
Пост-эксплуатация веб-приложений в тестах на проникновение
beched
 
Data mining for nmap acceleration
Data mining for nmap accelerationData mining for nmap acceleration
Data mining for nmap acceleration
beched
 
Криптология в анализе защищённости
Криптология в анализе защищённостиКриптология в анализе защищённости
Криптология в анализе защищённости
beched
 
Уязвимое Android-приложение: N проверенных способов наступить на грабли
Уязвимое Android-приложение: N проверенных способов наступить на граблиУязвимое Android-приложение: N проверенных способов наступить на грабли
Уязвимое Android-приложение: N проверенных способов наступить на грабли
Positive Development User Group
 
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Vladimir Kochetkov
 
Автоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кодаАвтоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кода
Vladimir Kochetkov
 
Полный цикл разработки на Python + Django
Полный цикл разработки на Python + DjangoПолный цикл разработки на Python + Django
Полный цикл разработки на Python + Django
Azamat Tokhtaev
 
Blackbox-тестирование веб-приложений
Blackbox-тестирование веб-приложенийBlackbox-тестирование веб-приложений
Blackbox-тестирование веб-приложений
beched
 
Node.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчикаNode.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчика
Alexei Smolyanov
 
AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путь
Vladimir Kochetkov
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
Andrew Mayorov
 
Django: инструкция по применению
Django: инструкция по применениюDjango: инструкция по применению
Django: инструкция по применению
Ivan Kolodyazhny
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Vladimir Kochetkov
 
Воркшоп по анализ защищённости веб-приложений
Воркшоп по анализ защищённости веб-приложенийВоркшоп по анализ защищённости веб-приложений
Воркшоп по анализ защищённости веб-приложений
beched
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
Igor Shkulipa
 

What's hot (20)

Кто сказал «WAF»?
Кто сказал «WAF»?Кто сказал «WAF»?
Кто сказал «WAF»?
 
Flask, гордость и предубеждение
Flask, гордость и предубеждениеFlask, гордость и предубеждение
Flask, гордость и предубеждение
 
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
Оптимизация высоконагруженных ASP.NET приложений, работающих с MS SQL Server ...
 
Эвристические методы защиты приложений
Эвристические методы защиты приложенийЭвристические методы защиты приложений
Эвристические методы защиты приложений
 
От экспериментального программирования к промышленному: путь длиной в 10 лет
От экспериментального программирования к промышленному: путь длиной в 10 летОт экспериментального программирования к промышленному: путь длиной в 10 лет
От экспериментального программирования к промышленному: путь длиной в 10 лет
 
Пост-эксплуатация веб-приложений в тестах на проникновение
Пост-эксплуатация веб-приложений в тестах на проникновениеПост-эксплуатация веб-приложений в тестах на проникновение
Пост-эксплуатация веб-приложений в тестах на проникновение
 
Data mining for nmap acceleration
Data mining for nmap accelerationData mining for nmap acceleration
Data mining for nmap acceleration
 
Криптология в анализе защищённости
Криптология в анализе защищённостиКриптология в анализе защищённости
Криптология в анализе защищённости
 
Уязвимое Android-приложение: N проверенных способов наступить на грабли
Уязвимое Android-приложение: N проверенных способов наступить на граблиУязвимое Android-приложение: N проверенных способов наступить на грабли
Уязвимое Android-приложение: N проверенных способов наступить на грабли
 
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
Как разработать защищенное веб-приложение и не сойти при этом с ума? (PHDays 3)
 
Автоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кодаАвтоматическая генерация патчей для уязвимого исходного кода
Автоматическая генерация патчей для уязвимого исходного кода
 
Полный цикл разработки на Python + Django
Полный цикл разработки на Python + DjangoПолный цикл разработки на Python + Django
Полный цикл разработки на Python + Django
 
Blackbox-тестирование веб-приложений
Blackbox-тестирование веб-приложенийBlackbox-тестирование веб-приложений
Blackbox-тестирование веб-приложений
 
Node.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчикаNode.JS: возможности для РНР-разработчика
Node.JS: возможности для РНР-разработчика
 
AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путь
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
 
Django: инструкция по применению
Django: инструкция по применениюDjango: инструкция по применению
Django: инструкция по применению
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
 
Воркшоп по анализ защищённости веб-приложений
Воркшоп по анализ защищённости веб-приложенийВоркшоп по анализ защищённости веб-приложений
Воркшоп по анализ защищённости веб-приложений
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
 

Similar to Формальная верификация кода на языке Си

Formal Verification of a Linux Security Module
Formal Verification of a Linux Security ModuleFormal Verification of a Linux Security Module
Formal Verification of a Linux Security Module
Denis Efremov
 
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасностиSAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
Andrey Karpov
 
Formal verification of operating system kernels
Formal verification of operating system kernelsFormal verification of operating system kernels
Formal verification of operating system kernels
Denis Efremov
 
Экстремальная оптимизация производительности на примере MongoDB Java Driver
Экстремальная оптимизация производительности на примере MongoDB Java DriverЭкстремальная оптимизация производительности на примере MongoDB Java Driver
Экстремальная оптимизация производительности на примере MongoDB Java Driver
Vitebsk DSC
 
Статический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокСтатический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибок
Andrey Karpov
 
In the sun.misc.Unsafe bowels
In the sun.misc.Unsafe bowelsIn the sun.misc.Unsafe bowels
In the sun.misc.Unsafe bowels
Alexander Efremenkov
 
2014-11-01 03 Николай Линкер. Open your clojure
2014-11-01 03 Николай Линкер. Open your clojure2014-11-01 03 Николай Линкер. Open your clojure
2014-11-01 03 Николай Линкер. Open your clojure
Омские ИТ-субботники
 
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
yaevents
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
Olexandra Dmytrenko
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
m2rus
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
Platonov Sergey
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
Andrey Karpov
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Positive Hack Days
 
Java Ahead-Of-Time compilation
Java Ahead-Of-Time compilationJava Ahead-Of-Time compilation
Java Ahead-Of-Time compilation
Nikita Lipsky
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
corehard_by
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
Andrey Karpov
 
Как команда PVS-Studio может улучшить код операционной системы Tizen
Как команда PVS-Studio может улучшить код операционной системы TizenКак команда PVS-Studio может улучшить код операционной системы Tizen
Как команда PVS-Studio может улучшить код операционной системы Tizen
Andrey Karpov
 
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
Iosif Itkin
 

Similar to Формальная верификация кода на языке Си (20)

Formal Verification of a Linux Security Module
Formal Verification of a Linux Security ModuleFormal Verification of a Linux Security Module
Formal Verification of a Linux Security Module
 
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасностиSAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
SAST, CWE, SEI CERT и другие умные слова из мира информационной безопасности
 
Formal verification of operating system kernels
Formal verification of operating system kernelsFormal verification of operating system kernels
Formal verification of operating system kernels
 
Экстремальная оптимизация производительности на примере MongoDB Java Driver
Экстремальная оптимизация производительности на примере MongoDB Java DriverЭкстремальная оптимизация производительности на примере MongoDB Java Driver
Экстремальная оптимизация производительности на примере MongoDB Java Driver
 
Статический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокСтатический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибок
 
In the sun.misc.Unsafe bowels
In the sun.misc.Unsafe bowelsIn the sun.misc.Unsafe bowels
In the sun.misc.Unsafe bowels
 
2014-11-01 03 Николай Линкер. Open your clojure
2014-11-01 03 Николай Линкер. Open your clojure2014-11-01 03 Николай Линкер. Open your clojure
2014-11-01 03 Николай Линкер. Open your clojure
 
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
Модели в профессиональной инженерии и тестировании программ. Александр Петрен...
 
Память в Java. Garbage Collector
Память в Java. Garbage CollectorПамять в Java. Garbage Collector
Память в Java. Garbage Collector
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Цена ошибки
Цена ошибкиЦена ошибки
Цена ошибки
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
 
Java Ahead-Of-Time compilation
Java Ahead-Of-Time compilationJava Ahead-Of-Time compilation
Java Ahead-Of-Time compilation
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Как команда PVS-Studio может улучшить код операционной системы Tizen
Как команда PVS-Studio может улучшить код операционной системы TizenКак команда PVS-Studio может улучшить код операционной системы Tizen
Как команда PVS-Studio может улучшить код операционной системы Tizen
 
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
TMPA-2013 Petrenko Pakulin: Technical Solutions and Non-Technical Challenges ...
 

Формальная верификация кода на языке Си

  • 1. Заголовок ptsecurity.com Формальная верификация кода на языке Си м.н.с. Ефремов Д.В. (аспирант ВШЭ) ИСП РАН efremov@ispras.ru
  • 2. Заголовок • Hacker-Proof Code Confirmed (quantamagazine) • Computer Scientists Close In on Perfect, Hack-Proof Code (wired) • Kaspersky Launches ‘Unhackable’ OS (guidingtech) • Unhackable kernel could keep all computers safe from cyberattack (newscientist) • Is This Security-Focused Linux Kernel Really UnHackable? (thehackernews) • Hack-resilient • Error-free code • Yale develops world's first hacker-resistant operating system (ibtimes) Немного заголовков
  • 3. Заголовок • Crowd Sourced Formal Verification (CSFV) (VERIGAMES) • High-Assurance Cyber Military Systems (HACMS) • Formally Verify Blockchain-Based Integrity Monitoring System • A Diagnostic Approach for Persistent Threat Detection (ADAPT) • Cyber Fault-tolerant Attack Recovery (CFAR) • Testing and Modeling of Brandeis Artifacts (TAMBA) • Clean-slate design of Resilient, Adaptive, Secure Hosts (CRASH) DARPA
  • 4. Заголовок • Orange Book: division A (verified protection) (A1, Beyond A1) • Common Criteria (EAL7) • DO-178C/DO-333 "Formal Methods Supplement to DO-178C and DO-278A” • IEC 61508 (SIL4) • ФСТЭК России ГОСТ Р ИСО/МЭК 15408 «Требованиях безопасности информации к операционным системам» профили защиты операционных систем общего назначения (типа «А») Стандарты
  • 5. Заголовок •Verified Software Initiative (2007) •Dafny •Whiley •SPARK/Ada •The Key Project/Java •Spec#/Sing# Академический фронт
  • 6. Заголовок • Верификация - проверка соответствия программного обеспечения предъявляемым к нему требованиям; • Дедуктивная верификация – представление корректности программы как набора математических утверждений, называемых условиями верификации, выполнение которых проверяется автоматическими или интерактивными доказателями теорем; • Спецификация - набор требований и параметров, которым удовлетворяет некоторый объект (представлена в виде мат. модели, тестовых наборов, формальной спецификации) Верификация
  • 7. Заголовок Высшая школа экономики, Москва, 2016 Дедуктивная верификация программ • Лекция Алана Тьюринга Лондонскому математическому обществу • Методы Флойда/Хоара • Инструменты дедуктивной верификации для Си, Java, С# • SunRise, ESC/Java, Frama-C, LOOP, Boogie/VCC • Применение к реальным проектам небольшого размера • Атомная энергетика (Англия, Франция) • Авионика (Airbus, NASA) • Компоненты специализированных ОС (seL4, Hyper-V)
  • 8. Заголовок • Компилятор и линковщик работают корректным образом • В программном обеспечении, использующемся при верификации, не произошло ошибок • Компьютер функционирует таким образом, как мы думаем об этом (rowhammer) • Нижележащий слой ПО (например, ОС, прошивка сетевой карты, микрокод процессора) функционирует в рамках нашего представления о том, что он должен делать и что не должен делать (и ещё не содержит ошибок) • Пользователь компьютера, если он есть, специально не «пакостит» • Выполнены предположения о входных данных программы, о начальном состоянии • … На что опираться vs. Что вы будете с этого иметь (1)
  • 9. Заголовок •Гарантии того, что программное обеспечение функционирует в точном соответствии с требованиями, к нему предъявляемыми, на всех входных данных, начальных состояниях, при любом поведении окружения * ** • * В предположении что все предположения выполнены • ** И не осталось предположений, которых мы не занесли в списочек На что опираться vs. Что вы будете с этого иметь (2)
  • 10. Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)
  • 11. Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)
  • 12. Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)
  • 13. Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} • Отсутствие целочисленного переполнения 𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX 𝑏 ≔ 𝑎 + 1 𝑎 = 𝑏 − 1 Примеры требований по безопасности (safety)
  • 14. Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} • Отсутствие целочисленного переполнения 𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX 𝑏 ≔ 𝑎 + 1 𝑎 = 𝑏 − 1 • Отсутствие разыменования нулевого указателя valid 𝑎 ∗ 𝑎 ≔ 1{∗ 𝑎 = 1} • … Примеры требований по безопасности (safety)
  • 15. Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 Примеры требований по функциональности
  • 16. Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 Примеры требований по функциональности
  • 17. Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 • Если в дереве присутствует искомый элемент, то функциях его обязательно найдёт O_O Примеры требований по функциональности
  • 18. Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 • Если в дереве присутствует искомый элемент, то функциях его обязательно найдёт O_O • Программа не держит в памяти секретные данные дольше, чем это требуется для их обработки @_@ • … Примеры требований по функциональности
  • 19. Заголовок • CompCert – компилятор языка Clight (Coq > Ocaml) • seL4 – микроядро L4 (Cparse > Isabelle/HOL) • CertiKOS – Certified Kit Operating System • Ironclad – End-to-End Security via Automated Full- System Verification (Dafny) • FSCQ – A Formally Certified Crash-proof File System (Coq) • Quark – веб-браузер с верифицированным ядром (Coq) Известные проекты
  • 20. Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си;
  • 21. Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си; • Это чистая функция; • Она вычисляет среднее между двумя целыми числами;
  • 22. Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си; • Это чистая функция; • Она вычисляет среднее между двумя целыми числами; • При определённых условиях возможно целочисленное переполнение.
  • 23. Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (2) • Возможно ли целочисленное переполнение в том контексте, где функция вызывается? • Считать ли возможное целочисленное переполнение ошибкой?
  • 24. Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (3) • Контекст: функция двоичного поиска; • Индексы l и h неотрицательны, l не превосходит h; • Возможна ошибка выхода за границу массива при целочисленном переполнении.
  • 25. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (1) •Описать контекст вызова: 𝜙: 𝑍 × 𝑍 → ⊤, ⊥ 𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏
  • 26. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (1) •Описать контекст вызова: 𝜙: 𝑍 × 𝑍 → ⊤, ⊥ 𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏 •Описать требования, которым должны удовлетворять результаты: 𝜓: 𝑍 × 𝑍 × 𝑍 → {⊤, ⊥} 𝜓 𝑎, 𝑏, 𝑟𝑒𝑠𝑢𝑙𝑡 ≡ 𝑟𝑒𝑠𝑢𝑙𝑡 = 𝑎 + 𝑏 2
  • 27. ЗаголовокКак доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇
  • 28. ЗаголовокКак доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇 • Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим программным кодом если завершается и завершается без ошибки, иначе возвращается специальное значение 𝜔
  • 29. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇 • Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим программным кодом если завершается и завершается без ошибки, иначе возвращается специальное значение 𝜔 • Доказать полную корректность: ∀𝑎, 𝑏 𝜙 𝑎, 𝑏 ⇒ 𝑀 𝑎𝑣𝑟 𝑎, 𝑏 ≠ 𝜔 && 𝜓 𝑎, 𝑏, 𝑀 𝑎𝑣𝑟 𝑎, 𝑏
  • 30. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint
  • 31. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647
  • 32. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a
  • 33. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a axiom H1: to_int o1 = 2 axiom H2: to_int o2 = (to_int a + to_int b)
  • 34. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a axiom H1: to_int o1 = 2 axiom H2: to_int o2 = (to_int a + to_int b) goal avr_safety: in_bounds 2 ->
  • 35. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a axiom H1: to_int o1 = 2 axiom H2: to_int o2 = (to_int a + to_int b) goal avr_safety: in_bounds 2 -> in_bounds(to_int a + to_int b) ->
  • 36. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a axiom H1: to_int o1 = 2 axiom H2: to_int o2 = (to_int a + to_int b) goal avr_safety: in_bounds 2 -> in_bounds(to_int a + to_int b) -> not to_int o1 = 0 ->
  • 37. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647 constant a, b, o1, o2: bint axiom H0: a >= of_int 0 && b >= of_int 0 && b >= a axiom H1: to_int o1 = 2 axiom H2: to_int o2 = (to_int a + to_int b) goal avr_safety: in_bounds 2 -> in_bounds(to_int a + to_int b) -> not to_int o1 = 0 -> in_bounds(div (to_int o2) (to_int o1))
  • 38. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4)
  • 39. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации
  • 40. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации Исправление кода
  • 41. Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации Исправление кода Уточнение спецификаций
  • 43. Высшая школа экономики, Москва, 2016 Стек инструментов дедуктивной верификации CIL CIL with annotations С program with ACSL annotations Jessie program (with annotations built-in) Jessie translator Why3 support Jessie2 CIL visitors (rewriters) Frama-C Jessie plugin
  • 44. Высшая школа экономики, Москва, 2016 Стек инструментов дедуктивной верификации CIL CIL with annotations С program with ACSL annotations Jessie program (with annotations built-in) Jessie translator Why3 support Why3 VC generator Why3 WhyML modules Verification conditions in Why3MLVC transformations Why3 encoders + drivers Logical formulas/scripts in SMT-LIB/SMT-LIBv2/native format Coq, PVS, Isabelle proof templates Why3 transformation/proof/shapes database Alt-Ergo Z3 CVC4 Coq PVS Why3 IDE ... Jessie2 CIL visitors (rewriters) Frama-C Jessie plugin Why3 Isabelle ...
  • 45. Заголовок • Код • Что формальная верификация может проверить и чего не может? • Формальные спецификации • Можно ли разработать формальные спецификации до стадии написания кода? • Что в них должно быть отображено? • Что инструмент (его модели и теоретическая основа) позволяет в них отобразить? • Насколько полными/точными/непротиворечивыми должны быть спецификации? • Код и спецификации • Можно ли дважды ошибиться и при этом доказать, что всё корректно? Где может встречаться ошибка?
  • 46. Заголовок • Зависит от того, какие модели заложены в инструментах верификации • Памяти, целочисленной арифметики, битовой арифметики… • Чем сложнее модель, тем детальнее она отражает действительность • Чем сложнее модель, тем более сложными становятся формулы условий верификации • Чем сложнее формулы, тем хуже на них работают автоматические доказатели логических формул • Аналогия QEMU⟺BOCHS Ошибки, которые «ловятся» в коде (1)
  • 47. Заголовок • Деление на ноль • Разыменование указателя • Некратный сдвиг типизированного указателя • Выход за границу массива • Целочисленное переполнение • Переполнение при операциях с плавающей запятой • Бесконечные циклы • … Ошибки, которые «ловятся» в коде (2)
  • 48. Заголовок •А как вы моделируете память (read, write)? char *p = "побольше цинизма, Киса"; p[0] = 'П'; •А как вы моделируете указатели (переполнение указателей)? char *p = UINT_MAX - 1; strlen(p); Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)
  • 49. Заголовок •А как вы моделируете стек (ограниченный или безграничный)? #define STACK_SIZE 1000*0x1000 //@ ensures result == 1; int main(void) { int a[STACK_SIZE]; memset(a, 0, STACK_SIZE); a[STACK_SIZE-1] = 1; return a[STACK_SIZE-1]; } Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)
  • 50. Заголовок •Что мы пишем в функциональные требования? ensures result >= 0; long abs(int a) { return 4; } Ошибки, специфичные для спецификаций (полнота) (1)
  • 51. Заголовок •Что мы пишем в функциональные требования? ensures result >= 0; long abs(int a) { return 4; } •Как мы пишем функциональные требования? unsigned abs(int a) return a >= 0 ? a :-((long)a); ensures result == a || result == -a; Ошибки, специфичные для спецификаций (полнота) (1)
  • 52. Заголовок •Что мы пишем в функциональные требования? ensures result >= 0; long abs(int a) { return 4; } •Как мы пишем функциональные требования? unsigned abs(int a) return a >= 0 ? a :-((long)a); ensures result == a || result == -a; ensures result == -a <==> a < 0; Ошибки, специфичные для спецификаций (полнота) (1)
  • 53. Заголовок •Что мы пишем в функциональные требования? ensures result >= 0; long abs(int a) { return 4; } •Как мы пишем функциональные требования? unsigned abs(int a) return a >= 0 ? a :-((long)a); ensures result == a || result == -a; ensures result == -a <==> a < 0; ensures a>=0 ? result==a : result==-a; Ошибки, специфичные для спецификаций (полнота) (1)
  • 54. Заголовок • Какие свойства мы выражаем в требованиях? requires n == 2 && valid(a+(0..n-1)); ensures forall integer i, j; 0 <= i < j < n ==> a[i] <= a[j]; // отсортированность void sort(size_t n, int a[n]) { a[0] = 1; a[1] = 2; } Ошибки, специфичные для спецификаций (полнота) (2)
  • 55. Заголовок • Какие свойства мы выражаем в требованиях? requires n == 2 && valid(a+(0..n-1)); ensures forall integer i, j; 0 <= i < j < n ==> a[i] <= a[j]; // отсортированность void sort(size_t n, int a[n]) { a[0] = 1; a[1] = 2; } • Как правильно их выразить? ... //сохранение всех элементов ensures forall int *i; a <= i < a + n ==> Сount{Pre}(a, n, *i) == Сount{Post}(a, n, *i); void sort(size_t n,int a[n]){if(a[0]>a[1])swap(a,0,1);} Ошибки, специфичные для спецификаций (полнота) (2)
  • 56. Заголовок • Противоречие в логических утверждениях a == 1 && a == 2 Ошибки, специфичные для спецификаций (противоречия) (1)
  • 57. Заголовок • Противоречие в логических утверждениях a == 1 && a == 2 • Изо лжи следует всё, что угодно requires 0 == 1; ensures result == 0 && result == 1 && result == 2; int main(void) { int a = 1; return a / 0; } Ошибки, специфичные для спецификаций (противоречия) (1)
  • 58. Заголовок • Противоречие в логических утверждениях a == 1 && a == 2 • Изо лжи следует всё, что угодно requires 0 == 1; ensures result == 0 && result == 1 && result == 2; int main(void) { int a = 1; return a / 0; } • Мертвый код void test(int a){ if (a > 0) if (a < 0) a/0; } Ошибки, специфичные для спецификаций (противоречия) (1)
  • 59. Заголовок • Verification Engineering of Safety and Security Critical Industrial Applications (VESSEDIA) • STANCE project • Programme Inter Carnot Fraunhofer from BMBF and ANR • Начало проекта - 2009 Пример ошибки в реальном проекте (1)
  • 60. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); Пример ошибки в реальном проекте (2)
  • 61. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); axiom CountSectionEmpty: forall int *a, v, integer m, n; n <= m ==> Count(a, m, n, v) == 0; Пример ошибки в реальном проекте (2)
  • 62. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); axiom CountSectionEmpty: forall int *a, v, integer m, n; n <= m ==> Count(a, m, n, v) == 0; axiom CountSectionHit: forall int *a, v, integer n, m; a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1; Пример ошибки в реальном проекте (2)
  • 63. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); axiom CountSectionEmpty: forall int *a, v, integer m, n; n <= m ==> Count(a, m, n, v) == 0; axiom CountSectionHit: forall int *a, v, integer n, m; a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1; int a = 5; assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0; Пример ошибки в реальном проекте (2)
  • 64. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); axiom CountSectionEmpty: forall int *a, v, integer m, n; n <= m ==> Count(a, m, n, v) == 0; axiom CountSectionHit: forall int *a, v, integer n, m; a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1; int a = 5; assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0; assert Count(&a+1,0,0,5) == Count(&a + 1,0,-1,5)+1; Пример ошибки в реальном проекте (2)
  • 65. Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); axiom CountSectionEmpty: forall int *a, v, integer m, n; n <= m ==> Count(a, m, n, v) == 0; axiom CountSectionHit: forall int *a, v, integer n, m; a[n] == v ==> Count(a,m,n+1,v)==Count(a,m,n,v)+1; int a = 5; assert Count(&a+1,0,-1,5) == 0 && Count(&a+1,0,0,5) == 0; assert Count(&a+1,0,0,5) == Count(&a + 1,0,-1,5)+1; assert 0 == 1; Пример ошибки в реальном проекте (2)
  • 66. Заголовок size_t strlen(const char *s) { const char *sc; for (sc = s; *sc != '0'; ++sc) /* nothing */; return sc - s; } Как выглядит разработка спецификации для функции? (1)
  • 67. Заголовок requires exists size_t i; 0 <= i && s[i] == '0' && valid(s+(0..i)); size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)
  • 68. Заголовок requires exists size_t i; 0 <= i && s[i] == '0' && valid(s+(0..i)); assigns nothing; size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)
  • 69. Заголовок requires exists size_t i; 0 <= i && s[i] == '0' && valid(s+(0..i)); assigns nothing; ensures s[result] == '0'; size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)
  • 70. Заголовок requires exists size_t i; 0 <= i && s[i] == '0' && valid(s+(0..i)); assigns nothing; ensures s[result] == '0'; ensures forall size_t i; 0 <= i< result ==> s[i] != '0'; size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)
  • 71. Заголовок const char *sc; /*@ loop invariant s <= sc; */ for (sc = s; *sc != '0'; ++sc) /* nothing */; return sc - s; Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
  • 72. Заголовок const char *sc; /*@ loop invariant s <= sc; loop invariant forall char *p; s <= p < sc ==> *p != '0'; */ for (sc = s; *sc != '0'; ++sc) /* nothing */; return sc - s; Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
  • 73. Заголовок const char *sc; /*@ loop invariant s <= sc; loop invariant forall char *p; s <= p < sc ==> *p != '0'; loop variant SIZE_MAX - (sc - s); */ for (sc = s; *sc != '0'; ++sc) /* nothing */; return sc - s; Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)
  • 74. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 75. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 76. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 77. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 78. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 79. ЗаголовокКак выглядит разработка спецификации для функции? (5) (Инструменты)
  • 80. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 81. ЗаголовокКак выглядит разработка спецификации для функции? (4) (Инструменты)
  • 82. ЗаголовокКак выглядит разработка спецификации для функции? (6) (Инструменты)
  • 83. Заголовок logic integer strlen(char *s) = s == '0' ? 0 : 1 + strlen(s + 1); Как выглядит разработка спецификации для функции? (7) (аксиоматика)
  • 84. Заголовок logic integer strlen(char *s) = s == '0' ? 0 : 1 + strlen(s + 1); lemma strlen_shift: forall char *s; (exists integer i; 0 <= i && s[i] == '0') && *s != '0' ==> strlen(s) == strlen(s + 1) + 1; Как выглядит разработка спецификации для функции? (7) (аксиоматика)
  • 85. Заголовок logic integer strlen(char *s) = s == '0' ? 0 : 1 + strlen(s + 1); lemma strlen_shift: forall char *s; (exists integer i; 0 <= i && s[i] == '0') && *s != '0' ==> strlen(s) == strlen(s + 1) + 1; lemma strlen_strend: forall char *s; *s == '0' ==> strlen(s) == 0; Как выглядит разработка спецификации для функции? (7) (аксиоматика)
  • 86. Заголовок /*@ ... ensures result == strlen(s); */ size_t strlen_str(const char *s) { const char *sc; /*@ ... loop invariant strlen(s) == strlen(sc) + (sc - s); ... */ for (sc = s; *sc != '0'; ++sc) /* nothing */; return sc - s; } Как выглядит разработка спецификации для функции? (8) (аксиоматика)
  • 87. Заголовок • Трудоёмкость • В разы больше чем разработка • Каждой строчке кода соответствует ~3-5 строчек спецификаций • Инструменты поддерживают не все конструкции языков программирования • Goto назад по коду • Switch с “проваливающимися” case • Цикломатическая сложность функций (< 15) • … • Применяется для проектов небольшого размера • обычно не более 10 тыс. строк Ограничения по применению дедуктивной верификации
  • 88. Заголовок • Серебряной пули не существует • Формальная верификация имеет как плюсы, так и минусы • Сложность применения • Что мы доказываем (безопасность(safety), функциональные требования) • Предположения, исходя из которых проводится верификация • Формальная верификация не гарантирует отсутствие всех ошибок • Формальная верификация не является заменой тестированию • При дедуктивной верификации существенна роль человека Резюме
  • 89. Заголовок • Система верификации на основе Frama- C+Jessie+Why3 опубликована под свободной лицензией • http://linuxtesting.ru/astraver • Руководства и введение в инструменты на русском • http://astraver.linuxtesting.org/ • Спецификации для библиотечных функций ядра Linux • https://github.com/evdenis/verker/ Дополнительная информация