Введение

Код, несущий доказательства (PCC), — это программный механизм, позволяющий хост-системе проверять свойства приложения посредством формального доказательства, сопровождающего исполняемый код этого приложения. Хост-система может быстро проверить корректность доказательства и сравнить его выводы со своей политикой безопасности, чтобы определить, безопасно ли запускать приложение. Это особенно полезно для обеспечения безопасности памяти, то есть предотвращения таких проблем, как переполнение буфера. Код, несущий доказательства, был впервые описан в 1996 году Джорджем Некулой и Питером Ли.

Пример фильтра пакетов

В первоначальной публикации о коде с доказательством в 1996 году в качестве примера использовались пакетные фильтры: приложение, работающее в пользовательском режиме, передает ядру функцию, написанную на машинном коде, которая определяет, заинтересовано ли приложение в обработке конкретного сетевого пакета. Поскольку пакетный фильтр выполняется в режиме ядра, он может скомпрометировать целостность системы, если содержит вредоносный код, записывающий данные в структуры ядра. Традиционные подходы к решению этой проблемы включают интерпретацию доменно-специфичного языка для фильтрации пакетов, вставку проверок при каждом обращении к памяти (аппаратная изоляция ошибок) и написание фильтра на языке высокого уровня, который ядро компилирует перед запуском. Эти подходы имеют недостатки в производительности для кода, выполняемого так часто, как пакетный фильтр, за исключением подхода компиляции в ядре, который компилирует код только при загрузке, а не при каждом его выполнении. При использовании кода с доказательством ядро публикует политику безопасности, определяющую свойства, которым должен соответствовать любой пакетный фильтр: например, фильтр не должен обращаться к памяти за пределами пакета и его временной области памяти. Для доказательства того, что машинный код соответствует этой политике, используется решатель теорем. Шаги этого доказательства записываются и присоединяются к машинному коду, который передается загрузчику программ ядра. Загрузчик программ может быстро проверить доказательство, что позволяет ему впоследствии запускать машинный код без дополнительных проверок. Если злоумышленник изменит либо машинный код, либо доказательство, полученный код с доказательством будет либо недействителен, либо безвреден (все равно будет соответствовать политике безопасности).