Slide 1

Slide 1 text

Заголовок ptsecurity.com Формальная верификация кода на языке Си м.н.с. Ефремов Д.В. (аспирант ВШЭ) ИСП РАН [email protected]

Slide 2

Slide 2 text

Заголовок • 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) Немного заголовков

Slide 3

Slide 3 text

Заголовок • 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

Slide 4

Slide 4 text

Заголовок • 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 «Требованиях безопасности информации к операционным системам» профили защиты операционных систем общего назначения (типа «А») Стандарты

Slide 5

Slide 5 text

Заголовок •Verified Software Initiative (2007) •Dafny •Whiley •SPARK/Ada •The Key Project/Java •Spec#/Sing# Академический фронт

Slide 6

Slide 6 text

Заголовок • Верификация - проверка соответствия программного обеспечения предъявляемым к нему требованиям; • Дедуктивная верификация – представление корректности программы как набора математических утверждений, называемых условиями верификации, выполнение которых проверяется автоматическими или интерактивными доказателями теорем; • Спецификация - набор требований и параметров, которым удовлетворяет некоторый объект (представлена в виде мат. модели, тестовых наборов, формальной спецификации) Верификация

Slide 7

Slide 7 text

Заголовок Высшая школа экономики, Москва, 2016 Дедуктивная верификация программ • Лекция Алана Тьюринга Лондонскому математическому обществу • Методы Флойда/Хоара • Инструменты дедуктивной верификации для Си, Java, С# • SunRise, ESC/Java, Frama-C, LOOP, Boogie/VCC • Применение к реальным проектам небольшого размера • Атомная энергетика (Англия, Франция) • Авионика (Airbus, NASA) • Компоненты специализированных ОС (seL4, Hyper-V)

Slide 8

Slide 8 text

Заголовок • Компилятор и линковщик работают корректным образом • В программном обеспечении, использующемся при верификации, не произошло ошибок • Компьютер функционирует таким образом, как мы думаем об этом (rowhammer) • Нижележащий слой ПО (например, ОС, прошивка сетевой карты, микрокод процессора) функционирует в рамках нашего представления о том, что он должен делать и что не должен делать (и ещё не содержит ошибок) • Пользователь компьютера, если он есть, специально не «пакостит» • Выполнены предположения о входных данных программы, о начальном состоянии • … На что опираться vs. Что вы будете с этого иметь (1)

Slide 9

Slide 9 text

Заголовок •Гарантии того, что программное обеспечение функционирует в точном соответствии с требованиями, к нему предъявляемыми, на всех входных данных, начальных состояниях, при любом поведении окружения * ** • * В предположении что все предположения выполнены • ** И не осталось предположений, которых мы не занесли в списочек На что опираться vs. Что вы будете с этого иметь (2)

Slide 10

Slide 10 text

Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)

Slide 11

Slide 11 text

Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)

Slide 12

Slide 12 text

Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} Примеры требований по безопасности (safety)

Slide 13

Slide 13 text

Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} • Отсутствие целочисленного переполнения 𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX 𝑏 ≔ 𝑎 + 1 𝑎 = 𝑏 − 1 Примеры требований по безопасности (safety)

Slide 14

Slide 14 text

Заголовок • Отсутствие деления на ноль 𝑏 ≠ 0 𝑐 ≔ 𝑎 𝑏 {𝑎 = 𝑐 ∗ 𝑏} • Отсутствие целочисленного переполнения 𝐼𝑁𝑇_𝑀𝐼𝑁 ≤ 𝑎 + 1 ≤ 𝐼𝑁𝑇_MAX 𝑏 ≔ 𝑎 + 1 𝑎 = 𝑏 − 1 • Отсутствие разыменования нулевого указателя \valid 𝑎 ∗ 𝑎 ≔ 1{∗ 𝑎 = 1} • … Примеры требований по безопасности (safety)

Slide 15

Slide 15 text

Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение \ 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 Примеры требований по функциональности

Slide 16

Slide 16 text

Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение \ 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 Примеры требований по функциональности

Slide 17

Slide 17 text

Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение \ 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 • Если в дереве присутствует искомый элемент, то функциях его обязательно найдёт O_O Примеры требований по функциональности

Slide 18

Slide 18 text

Заголовок • Массив отсортирован ∀𝑖𝑛𝑡 𝑗; 0 ≤ 𝑗 < 𝐴𝑅𝑅𝐴𝑌_𝑆𝐼𝑍𝐸 − 1 ⇒ 𝑎 𝑗 ≤ 𝑎[𝑗 + 1] • Функция возвращает всегда положительное значение \ 𝑟𝑒𝑠𝑢𝑙𝑡 > 0 • Функция может менять порядок элементов в массиве, но не его содержимое 0_0 • Если в дереве присутствует искомый элемент, то функциях его обязательно найдёт O_O • Программа не держит в памяти секретные данные дольше, чем это требуется для их обработки @_@ • … Примеры требований по функциональности

Slide 19

Slide 19 text

Заголовок • 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) Известные проекты

Slide 20

Slide 20 text

Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си;

Slide 21

Slide 21 text

Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си; • Это чистая функция; • Она вычисляет среднее между двумя целыми числами;

Slide 22

Slide 22 text

Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (1) • Она существует и написана на языке Си; • Это чистая функция; • Она вычисляет среднее между двумя целыми числами; • При определённых условиях возможно целочисленное переполнение.

Slide 23

Slide 23 text

Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (2) • Возможно ли целочисленное переполнение в том контексте, где функция вызывается? • Считать ли возможное целочисленное переполнение ошибкой?

Slide 24

Slide 24 text

Заголовок Высшая школа экономики, Москва, 2016 Что можно сказать о функции на языке Си по её коду? (3) • Контекст: функция двоичного поиска; • Индексы l и h неотрицательны, l не превосходит h; • Возможна ошибка выхода за границу массива при целочисленном переполнении.

Slide 25

Slide 25 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (1) •Описать контекст вызова: 𝜙: 𝑍 × 𝑍 → ⊤, ⊥ 𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏

Slide 26

Slide 26 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (1) •Описать контекст вызова: 𝜙: 𝑍 × 𝑍 → ⊤, ⊥ 𝜙 𝑎, 𝑏 ≡ 𝑎 ≥ 0 ∧ 𝑏 ≥ 0 ∧ 𝑎 ≤ 𝑏 •Описать требования, которым должны удовлетворять результаты: 𝜓: 𝑍 × 𝑍 × 𝑍 → {⊤, ⊥} 𝜓 𝑎, 𝑏, 𝑟𝑒𝑠𝑢𝑙𝑡 ≡ 𝑟𝑒𝑠𝑢𝑙𝑡 = 𝑎 + 𝑏 2

Slide 27

Slide 27 text

Заголовок Как доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇

Slide 28

Slide 28 text

Заголовок Как доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇 • Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим программным кодом если завершается и завершается без ошибки, иначе возвращается специальное значение 𝜔

Slide 29

Slide 29 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (2) • Формализовать понятие ошибки (целочисленное переполнение): 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠: 𝑍 → {⊤, ⊥} 𝑖𝑛_𝑏𝑜𝑢𝑛𝑑𝑠 𝑛 ≡ 𝑀𝐼𝑁_𝐼𝑁𝑇 ≤ 𝑛 ≤ 𝑀𝐴𝑋_𝐼𝑁𝑇 • Формализовать код программы: функция 𝑀 𝑎𝑣𝑟 , которая возвращает результат 𝑀 𝑎𝑣𝑟 (𝑎, 𝑏) в соответствии со своим программным кодом если завершается и завершается без ошибки, иначе возвращается специальное значение 𝜔 • Доказать полную корректность: ∀𝑎, 𝑏 𝜙 𝑎, 𝑏 ⇒ 𝑀 𝑎𝑣𝑟 𝑎, 𝑏 ≠ 𝜔 && 𝜓 𝑎, 𝑏, 𝑀 𝑎𝑣𝑟 𝑎, 𝑏

Slide 30

Slide 30 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint

Slide 31

Slide 31 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (3) function to_int bint : int function of_int int : bint predicate in_bounds (n:int) = -2147483648 <= n && n <= 2147483647

Slide 32

Slide 32 text

Заголовок Высшая школа экономики, Москва, 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

Slide 33

Slide 33 text

Заголовок Высшая школа экономики, Москва, 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)

Slide 34

Slide 34 text

Заголовок Высшая школа экономики, Москва, 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 ->

Slide 35

Slide 35 text

Заголовок Высшая школа экономики, Москва, 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) ->

Slide 36

Slide 36 text

Заголовок Высшая школа экономики, Москва, 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 ->

Slide 37

Slide 37 text

Заголовок Высшая школа экономики, Москва, 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))

Slide 38

Slide 38 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4)

Slide 39

Slide 39 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации

Slide 40

Slide 40 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации Исправление кода

Slide 41

Slide 41 text

Заголовок Высшая школа экономики, Москва, 2016 Как доказать что код функции корректен? (4) Условие верификации Исправление кода Уточнение спецификаций

Slide 42

Slide 42 text

Стек инструментов дедуктивной верификации CIL CIL with annotations С program with ACSL annotations Frama-C

Slide 43

Slide 43 text

Высшая школа экономики, Москва, 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

Slide 44

Slide 44 text

Высшая школа экономики, Москва, 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 Why3ML VC 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 ...

Slide 45

Slide 45 text

Заголовок • Код • Что формальная верификация может проверить и чего не может? • Формальные спецификации • Можно ли разработать формальные спецификации до стадии написания кода? • Что в них должно быть отображено? • Что инструмент (его модели и теоретическая основа) позволяет в них отобразить? • Насколько полными/точными/непротиворечивыми должны быть спецификации? • Код и спецификации • Можно ли дважды ошибиться и при этом доказать, что всё корректно? Где может встречаться ошибка?

Slide 46

Slide 46 text

Заголовок • Зависит от того, какие модели заложены в инструментах верификации • Памяти, целочисленной арифметики, битовой арифметики… • Чем сложнее модель, тем детальнее она отражает действительность • Чем сложнее модель, тем более сложными становятся формулы условий верификации • Чем сложнее формулы, тем хуже на них работают автоматические доказатели логических формул • Аналогия QEMU⟺BOCHS Ошибки, которые «ловятся» в коде (1)

Slide 47

Slide 47 text

Заголовок • Деление на ноль • Разыменование указателя • Некратный сдвиг типизированного указателя • Выход за границу массива • Целочисленное переполнение • Переполнение при операциях с плавающей запятой • Бесконечные циклы • … Ошибки, которые «ловятся» в коде (2)

Slide 48

Slide 48 text

Заголовок •А как вы моделируете память (read, write)? char *p = "побольше цинизма, Киса"; p[0] = 'П'; •А как вы моделируете указатели (переполнение указателей)? char *p = UINT_MAX - 1; strlen(p); Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)

Slide 49

Slide 49 text

Заголовок •А как вы моделируете стек (ограниченный или безграничный)? #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]; } Вопрос гарантии отсутствия ошибок в коде (ошибки, которые «не ловятся»)

Slide 50

Slide 50 text

Заголовок •Что мы пишем в функциональные требования? ensures \result >= 0; long abs(int a) { return 4; } Ошибки, специфичные для спецификаций (полнота) (1)

Slide 51

Slide 51 text

Заголовок •Что мы пишем в функциональные требования? 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)

Slide 52

Slide 52 text

Заголовок •Что мы пишем в функциональные требования? 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)

Slide 53

Slide 53 text

Заголовок •Что мы пишем в функциональные требования? 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)

Slide 54

Slide 54 text

Заголовок • Какие свойства мы выражаем в требованиях? 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)

Slide 55

Slide 55 text

Заголовок • Какие свойства мы выражаем в требованиях? 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)

Slide 56

Slide 56 text

Заголовок • Противоречие в логических утверждениях a == 1 && a == 2 Ошибки, специфичные для спецификаций (противоречия) (1)

Slide 57

Slide 57 text

Заголовок • Противоречие в логических утверждениях a == 1 && a == 2 • Изо лжи следует всё, что угодно requires 0 == 1; ensures \result == 0 && \result == 1 && \result == 2; int main(void) { int a = 1; return a / 0; } Ошибки, специфичные для спецификаций (противоречия) (1)

Slide 58

Slide 58 text

Заголовок • Противоречие в логических утверждениях 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)

Slide 59

Slide 59 text

Заголовок • Verification Engineering of Safety and Security Critical Industrial Applications (VESSEDIA) • STANCE project • Programme Inter Carnot Fraunhofer from BMBF and ANR • Начало проекта - 2009 Пример ошибки в реальном проекте (1)

Slide 60

Slide 60 text

Заголовок logic integer Count{L}(int *a, integer m, integer n, int v); Пример ошибки в реальном проекте (2)

Slide 61

Slide 61 text

Заголовок 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)

Slide 62

Slide 62 text

Заголовок 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)

Slide 63

Slide 63 text

Заголовок 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)

Slide 64

Slide 64 text

Заголовок 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)

Slide 65

Slide 65 text

Заголовок 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)

Slide 66

Slide 66 text

Заголовок size_t strlen(const char *s) { const char *sc; for (sc = s; *sc != '\0'; ++sc) /* nothing */; return sc - s; } Как выглядит разработка спецификации для функции? (1)

Slide 67

Slide 67 text

Заголовок requires \exists size_t i; 0 <= i && s[i] == '\0' && \valid(s+(0..i)); size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)

Slide 68

Slide 68 text

Заголовок requires \exists size_t i; 0 <= i && s[i] == '\0' && \valid(s+(0..i)); assigns \nothing; size_t strlen(const char *s) Как выглядит разработка спецификации для функции? (2) (Контракт)

Slide 69

Slide 69 text

Заголовок 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) (Контракт)

Slide 70

Slide 70 text

Заголовок 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) (Контракт)

Slide 71

Slide 71 text

Заголовок const char *sc; /*@ loop invariant s <= sc; */ for (sc = s; *sc != '\0'; ++sc) /* nothing */; return sc - s; Как выглядит разработка спецификации для функции? (3) (Инварианты цикла)

Slide 72

Slide 72 text

Заголовок 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) (Инварианты цикла)

Slide 73

Slide 73 text

Заголовок 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) (Инварианты цикла)

Slide 74

Slide 74 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 75

Slide 75 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 76

Slide 76 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 77

Slide 77 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 78

Slide 78 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 79

Slide 79 text

Заголовок Как выглядит разработка спецификации для функции? (5) (Инструменты)

Slide 80

Slide 80 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 81

Slide 81 text

Заголовок Как выглядит разработка спецификации для функции? (4) (Инструменты)

Slide 82

Slide 82 text

Заголовок Как выглядит разработка спецификации для функции? (6) (Инструменты)

Slide 83

Slide 83 text

Заголовок logic integer strlen(char *s) = s == '\0' ? 0 : 1 + strlen(s + 1); Как выглядит разработка спецификации для функции? (7) (аксиоматика)

Slide 84

Slide 84 text

Заголовок 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) (аксиоматика)

Slide 85

Slide 85 text

Заголовок 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) (аксиоматика)

Slide 86

Slide 86 text

Заголовок /*@ ... 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) (аксиоматика)

Slide 87

Slide 87 text

Заголовок • Трудоёмкость • В разы больше чем разработка • Каждой строчке кода соответствует ~3-5 строчек спецификаций • Инструменты поддерживают не все конструкции языков программирования • Goto назад по коду • Switch с “проваливающимися” case • Цикломатическая сложность функций (< 15) • … • Применяется для проектов небольшого размера • обычно не более 10 тыс. строк Ограничения по применению дедуктивной верификации

Slide 88

Slide 88 text

Заголовок • Серебряной пули не существует • Формальная верификация имеет как плюсы, так и минусы • Сложность применения • Что мы доказываем (безопасность(safety), функциональные требования) • Предположения, исходя из которых проводится верификация • Формальная верификация не гарантирует отсутствие всех ошибок • Формальная верификация не является заменой тестированию • При дедуктивной верификации существенна роль человека Резюме

Slide 89

Slide 89 text

Заголовок • Система верификации на основе Frama- C+Jessie+Why3 опубликована под свободной лицензией • http://linuxtesting.ru/astraver • Руководства и введение в инструменты на русском • http://astraver.linuxtesting.org/ • Спецификации для библиотечных функций ядра Linux • https://github.com/evdenis/verker/ Дополнительная информация

Slide 90

Slide 90 text

Заголовок ptsecurity.com Спасибо! Спасибо!