Filips Pizlo konferencē SPLASH'24 prezentēja atvērto C/C++ kompilatoru Fil-C, kas nodrošina aizsardzību pret problēmām, ko rada kļūdas darbā ar atmiņu. Projekta mērķis ir nodrošināt pilnīgu savietojamību ar esošo kodu C un C++ valodās - lai nodrošinātu drošu darbību ar atmiņu, pietiek vienkārši pārbūvēt esošo kodu. Kompilators ir izveidots, izmantojot LLVM projekta komponentus, un tiek izplatīts saskaņā ar Apache 2.0 licenci. Izpildlaiks tiek nodrošināts saskaņā ar BSD licenci. Atšķirībā no nesen izziņotā TrapC projekta, kas joprojām ir izstrādes stadijā, Fil-C kompilators jau ir gatavs izveidot esošo kodu.
Projekts nodrošina arī standarta C bibliotēku (libc) un C++ (libc++) versijas, kas drošas atmiņai, pamatojoties uz Musl un LLVM libc++ bibliotēkām. Cita starpā izveidotās programmas var izmantot tādas funkcijas kā daudzpavedienu veidošana, signālu apstrāde, atmiņas kartēšana (mmap), longjmp/setjmp un izņēmumu apstrāde programmā C++. Izmantojot Fil-C, bzip2, zip, pcre un ncurses projektus var izveidot, neveicot nekādas izmaiņas. Ar nelielām modifikācijām tiek atbalstīta OpenSSH, OpenSSL, CPython, SQLite, Lua, Curl, Lynx, jpeg6b, zsh, xzutils un simdutf būvēšana.
Aizsardzība pret atmiņas problēmām tiek nodrošināta, izmantojot 128 bitu MonoCaps rādītājus ar metadatiem tipa pārbaudei un bufera robežu izsekošanai, kā arī FUGC atkritumu savācēja izmantošana, kas kontrolē visas atmiņas piešķiršanas un atdalīšanas darbības. Kļūdu gadījumā, strādājot ar atmiņu, lietojumprogramma nekavējoties avarē, kas neļauj izmantot iespējamās ievainojamības.
Tiek norādīts, ka MonoCaps un FUGC kombinācija ļauj uztvert un bloķēt visas kļūdas, kas saistītas ar steka un kaudzes bufera robežu pārsniegšanu, piekļuvi jau atbrīvotajai atmiņai, sacensību apstākļiem, strādājot ar rādītājiem, kā arī nepareizu veidu apstrādi ( Tipa apjukums) kontekstā, kur krustojas rādītāja un bezrādītāja tipi, problēmas ar dinamisko saistīšanu un nepareiza va_lists izmantošana. Turklāt Fil-C atsevišķi pārbauda robežas un veidus buferos, kas tiek nodoti sistēmas izsaukumiem.
Ценой возможности использования Fil-C для защиты существующих проектов, без необходимости переписывания их кода или задействования особых языковых конструкций, является снижение производительности. На текущем этапе развития, собираемые в Fil-C программы медленнее примерно в 1.5-5 раз, по сравнению со сборкой обычными компиляторами. В планах заявлена работа по проведению оптимизации. Предполагается, что после завершения этой работы в большинстве случаев код будет выполняться медленнее в 1.2 раза, а в наихудших сценариях замедление не превысит полтора раза. Компилятор пока поддерживает только платформу Linux на системах X86_64. Предыдущие версии поддерживали macOS и FreeBSD, но затем было решено не распылять усилия и вначале подготовить качественный порт libc для одной платформы.
Vēl viens Fil-C ierobežojums ir būtisks atteikums uzturēt saderību ABI līmenī C/C++ kodam, kas neļauj Fil-C kompilēto kodu saistīt ar bibliotēkām un objektu failiem, ko apkopojuši citi kompilatori. Funkciju izsaukšanas metode un dinamiskās saistīšanas veids programmā Fil-C atšķiras no esošajiem kompilatoriem un linkeriem. Šāds lēmums tiek skaidrots ar to, ka, saistot ar neaizsargātu kodu, tiek zaudēta Fil-C piedāvātās aizsardzības būtība un rodas ilūzija par aizsargātu aplikāciju - ar ABI saderību izstrādātājiem būtu kārdinājums Fil-ā savākt tikai atsevišķus failus. -C, neapgrūtinot sevi ar visa projekta pārnešanu.
Fil-C MonoCap mehānisms ir balstīts uz 16 baitu rādītāju izmantošanu, kas papildus atmiņas adresei norāda atsauci uz objektu, kas ietver informāciju par iespējām, piemēram, bufera augšējo un apakšējo robežu, kas saistīta ar rādītājs, kā arī masīvs , kas nosaka katrā atmiņas blokā saglabātos datu tipus (1 baits ar tipa informāciju (unset, int, ptr, free) katram 16 baitu atmiņas blokam). Katru reizi, kad atmiņai piekļūst rādītājs, tiek pārbaudītas robežas un veids (piemēram, datus ar tipu “int” nevar ierakstīt atmiņā ar tipu “ptr” un otrādi).
Visas atmiņas piešķiršanas un atdalīšanas darbības apstrādā Fil's Unbelievable Garbage Collector (FUGC), kas, atbrīvojot atmiņu, iestata visu veidu ierakstus, kas saistīti ar atbrīvoto buferi, uz vērtību "free" un pēc tam novirza visus norādes uz atbrīvotajiem objektiem uz atsevišķu objektu, kas signalizē, ka atmiņa jau ir atbrīvota. Jebkāda turpmāka piekļuve datu blokam ar tipu “bezmaksas” vai rādītājam, kas saistīts ar atbrīvotu objektu, rada izņēmuma ģenerēšanu, kas nodrošina aizsardzību pret lietošanas pēc brīvas ievainojamībām. Atkritumu savācējs darbojas paralēli un neaptur citu pavedienu izpildi.
Izmantojot MonoCaps un FUGC kombināciju, jūs varat saglabāt iespēju strādāt ar rādītājiem kā parasti un atstāt malloc un bezmaksas zvanu semantiku nemainīgu, vienlaikus nodrošinot garantētu aizsardzību. Programmas kods var saturēt dažādas loģiskas kļūdas, piemēram, nepareizu veidu cast, nepareizu rādītāja aritmētiku, sacensību nosacījumus un nelaikus izsaukumus uz free(), taču neatkarīgi no tā visa, Fil-C atcerēsies sākotnējās robežas un datu tipu un pārtrauks izpildi. , ja tiek mēģināts piekļūt rādītājam uz apgabalu, kas atrodas ārpus atmiņā esošajām robežām, piekļūstiet atbrīvotajam atmiņas blokam vai nolasiet "int" tipa datus kā rādītāju vai otrādi.
Fil-C autors Filips Pizlo ir programmēšanas valodu projektu direktors uzņēmumā Epic Games. Filipam ir plaša pieredze darbā ar virtuālajām mašīnām, programmēšanas valodām, kompilatoriem un atkritumu savācējiem. Piemēram, IBM viņš izstrādāja programmēšanas valodu X10; Microsoft viņš strādāja pie atkritumu savācējiem Stopless, Clover un Chicken; Apple viņš strādāja pie JIT kompilatora un WebKit pārlūkprogrammas dzinēja optimizācijas; un Epic Games viņš vada izstrādes komandu, kas izstrādā Verse programmēšanas valodu un ar to saistīto virtuālo mašīnu. Filips ir arī viens no galvenajiem izstrādātājiem. virtuālās mašīnas Džikesa RVM, Ovm un Fidži VM.

Avots: opennet.ru
