Filip Pizlo esitles konverentsil SPLASH’24 avatud C/C++ kompilaatorit Fil-C, mis pakub kaitset mäluhalduse vigadega seotud probleemide vastu. Projekt on suunatud täieliku ühilduvuse tagamisele olemasoleva C ja C++ koodiga — olemasoleva koodi lihtsalt uuesti kompileerimine tagab mäluga ohutu töötamise. Kompilaator on loodud LLVM projekti komponentide abil ja jagatakse Apache 2.0 litsentsi alusel. Runtime on saadaval BSD litsentsi alusel. Erinevalt hiljuti välja kuulutatud projektist TrapC, mis on alles kavandamisjärgus, on kompilaator Fil-C juba valmis olemasoleva koodi kompileerimiseks.
Projekt sisaldab ka mäluga ohutult töötavaid C (libc) ja C++ (libc++) standardteegi variante, mis põhinevad Musl ja LLVM libc++ teekidel. Muuhulgas võivad kogutud programmides olla kasutusel sellised võimalused nagu mitme ülesande täitmine, signaalide töötlemine, failide mäluga kaardistamine (mmap), longjmp/setjmp ja erindite töötlemine C++-is. Fil-C abil võivad ilma muudatusteta olla kokku pandud projektid bzip2, zip, pcre ja ncurses. Väikeste muudatustega toetatakse OpenSSH, OpenSSL, CPython, SQLite, Lua, Curl, Lynx, jpeg6b, zsh, xzutils ja simdutf kokkupanekut.
Mäluprobleemide kaitse tagatakse 128-bitiste MonoCaps pointerite kasutamise kaudu, mis sisaldavad metaandmeid tüüpide kontrollimiseks ja puutete piiride jälgimiseks, samuti FUGC prügikoristaja aktiveerimisega, mis kontrollib kõiki mälu eraldamise ja vabastamise operatsioone. Mälu kasutamise vigade korral katkestatakse rakendus kohe, mis takistab võimalike haavatavuste ärakasutamist.
On väidetud, et MonoCaps ja FUGC kombinatsioon võimaldab tabada ja blokeerida kõik vead, mis on seotud mälust välja minekuga, nii virnas kui heap'is, juba vabastatud mälu kasutamisega, pointeritega seonduvate võidujooksu olukordadega ning vale tüübi käsitlemise (Type Confusion) probleemidega pointerite ja pointeriteta tüüpide ristumisel, samuti dünaamilise linkimisega (linking) ja va_listide ebaõige kasutamisega. Lisaks kontrollib Fil-C eraldi piire ja tüüpe süsteemikõnedele edastatavates puhverdes.
Fil-C kasutamise võimalus olemasolevate projektide kaitsmiseks, ilma vajaduseta nende koodi ümber kirjutada või erilisi keelekonstruktsioone kaasata, toob kaasa jõudluse languse. Praegusel arenguetapil on Fil-C kogutud programmid umbes 1,5-5 korda aeglasemad võrreldes tavapäraste kompilaatormoodulitega. Plaanides on töö optimiseerimise kallal. Eeldatakse, et pärast selle töö lõpetamist toimub enamikul juhtudel koodi täitmine 1,2 korda aeglasemalt ja halvimates stsenaariumites ei ületa aeglustumine poolteist korda. Kompilaator toetab praegu ainult Linuxi platvormi X86_64 süsteemidel. Eelnevad versioonid toetasid ka macOS-i ja FreeBSD-d, kuid siis otsustati mitte hajutada jõude ning esmalt valmistada ette kvaliteetne libc sadam ühe platvormi jaoks.
Teine Fil-C piirang on põhimõtteline keeld ABI tasandi ühilduvuse säilitamisest C/C++ koodi jaoks, mis ei võimalda siduda Fil-C-s kompileeritud koodi teiste kompilaatorite poolt loodud teekide ja objektifailidega. Funktsioonide kutsumise meetod ja dünaamilise sidumise viis Fil-C-s erineb olemasolevatest kompilaatoritest ja linker'itest. Selline lahendus selgitatakse sellega, et sidumisel kaitsmata koodiga kaob Fil-C pakutud kaitse mõte ning tekib illusioon kaitstud rakendusest — ABI ühilduvuse olemasolul oleks arendajatel kiusatus siduda Fil-C-sse vaid üksikfailid, vaevamata end terve projekti portimisega.
Fil-C mehhanismi MonoCap põhineb 16-baidiste viidete kasutamisel, kus lisaks mälu aadressile on viidatud objekt, mis sisaldab teavet võimaluste (capability) kohta, nagu viidatud puhversäilituskohtade ülemised ja alumised piirid, samuti massiiv, mis määratleb andmetüübid, mis on salvestatud igas mälu plokis (1 bait teavet tüübi (unset, int, ptr, free) kohta iga 16-baidise mälu ploki jaoks). Iga kord, kui mälule pöördutakse viite kaudu, tehakse piiride ja tüübi kontroll (nt tüübiga «ptr» mällu ei tohi salvestada andmeid tüübiga «int» ja vastupidi).
Kõik mälu eraldamise ja vabastamise toimingud töötlevad FUGC (Fil’s Unbelievable Garbage Collector) jäätmevaldaja, mille käigus, kui mälu vabastatakse, muudetakse kõik vabastatava puutega seotud tüüpide kirjed väärtuseks "free" ja siis suunatakse kõik viidatud vabastatud objektide osutid eraldi objekti, mis signaalib, et mälu on juba vabastatud. Igasugune edasine juurdepääs andmeplokile tüübiga "free" või vabastatud objektiga seotud osutile genereerib erandi, mis aitab kaitsta kasutaja pärast vabastamise haavatavuste eest. Jäätmevaldaja töötab paralleelselt ja ei peata teiste niitide täitmist.
MonoCaps ja FUGC kombinatsiooni kasutamine võimaldab säilitada tuttavat töövoogu pointeritega ning hoida malloc ja free kutsungite semantika muutumatuna, samas tagades garantii. Programmi kood võib sisaldada erinevaid loogilisi vigu, nagu vale tüübi konverteerimine, vale aritmeetika pointerite puhul, võidusitu ja väära free() funktsiooni kutsumine, kuid hoolimata sellest, Fil-C salvestab algsed piirid ja andmetüübid ning katkestab täitmise, kui tehakse katse pääseda pointeri kaudu väljastpoolt salvestatud piire, vabastatud mälubloki juurde või lugeda andmeid tüübi "int" kui pointerit või vastupidi.
Fil-C, Philip Pizlo, on Epic Games'i direktori, kes vastutab programmeerimiskeelte projektide eest. Philipil on ulatuslik kogemus virtuaalmasinate, programmeerimiskeelte, kompilaatorite ja prügikogujate valdkonnas. Näiteks IBM-is arendas ta programmeerimiskeelt X10, Microsoftis töötas ta Stopless, Clover ja Chicken prügikogujate kallal, Apple'is tegeles ta JIT-kompilaatori ja WebKiti brauserimootori optimeerimisega ning Epic Games'is juhib ta arendajate meeskonda, mis arendab programmeerimiskeelt Verse ja sellega seotud virtuaalmasinat. Philip on samuti üks võtmearendajatest. virtuaalmasinad Jikes RVM, Ovm ja Fiji VM.

Allikas: opennet.ru
