Цель разработки компилятора – полная совместимость с синтаксисом языков Си и С++ при обеспечении полной безопасности работы с памятью. Заявляется, что для использования достаточно пересобрать существующий код, так уже компилируются и работают bzip2, zip, pcre и ncurses. С незначительными модификациями поддерживается сборка OpenSSH, OpenSSL, CPython, SQLite, Lua, Curl, Lynx, jpeg6b, zsh, xzutils и simdutf.
Защита обеспечивается благодаря применению 128-битных указателей и сборщика мусора. Если защита отслеживает ошибку, программа аварийно завершается, что позволяет не эксплуатировать уязвимость.
Заявляется отслеживание защитой: выделения и корректного освобождения памяти в стеке и куче, отслеживание неправильной обработки типов и состояние гонки при работе с указателям.
Компиляция занимает в 1,5-5 раз больше времени, чем у gcc. Скорость выполнения в 1.2 раза ниже, чем при работе аналогичных программ, скомпилированных gcc. Пока компилятор доступен только для linux-платформ, такое решение было принято разработчиками для того, чтобы не распылять усилия. Линковка с объектным кодом, созданным другими компиляторами, невозможна в силу разного ABI.
Задействованный в Fil-C механизм MonoCap основывается на применении 16-байтовых указателей, в которых помимо адреса в памяти, указывается ссылка на объект, включающий сведения о возможностях (capability), таких как верхняя и нижняя границы буфера, ассоциированного с указателем, а также массив, определяющий типы данных, хранимые в каждом блоке памяти (1 байт с информацией о типе (unset, int, ptr, free) для каждого 16-байтового блока памяти). При каждом обращении к памяти по указателю осуществляется проверка границ и типа (например, в память с типом «ptr» не могут быть записаны данные с типом «int» и наоборот).
Все операции выделения и освобождения памяти обрабатываются сборщиком мусора FUGC (Fil’s Unbelievable Garbage Collector), который при освобождении памяти переводит все связанные с освобождаемым буфером записи о типах в значение «free» и затем перенаправляет все указатели на освободившиеся объекты на отдельный объект, сигнализирующий о том, что память уже освобождена. Любое дальнейшее обращение к блоку данных с типом «free» или по указателю, связанному с освобождённым объектом, приводит к генерации исключения, что позволяет защититься от уязвимостей класса use-after-free. Сборщик мусора работает параллельно и не приостанавливает выполнение других потоков.
Использование комбинации из MonoCaps и FUGC позволяет сохранить возможность привычной работы с указателями и оставить неизменной семантику вызовов malloc и free, предоставив при этом гарантированную защиту. Код программы может содержать различные логические ошибки, такие как неправильное приведение типов, неверные арифметические операции с указателями, состояния гонки и несвоевременный вызов функции free(), но независимо от всего этого, Fil-C запомнит исходные границы и тип данных, и прервёт выполнение, если будет предпринята попытка доступа по указателю к области вне запомненных границ, обращения к освобождённому блоку памяти или чтения данных с типом «int» как указателя или наоборот.
Автор Fil-C, Филипп Пизло (Filip Pizlo), занимает в компании Epic Games пост директора, отвечающего за проекты, связанные с языками программирования. Филипп имеет богатый опыт работы над виртуальными машинами, языками программирования, компиляторами и сборщиками мусора, например, в IBM он развивал язык программирования X10, в Microsoft работал над сборщиками мусора Stopless, Clover и Chicken, в Apple занимался JIT-компилятором и оптимизациями браузерного движка WebKit, в Epic Games возглавляет команду разработчиков, развивающую язык программирования Verse и связанную с ним виртуальную машину. Филипп также является одним из ключевых разработчиков виртуальных машин Jikes RVM, Ovm и Fiji VM.
>>> Подробности