Za zmínku stojí, že pokud někdo chce bezpečnost a kompatibilitu, tak může přeložit klasické Coreutils pomocí Fil-C. Tím ve výsledku dostane memory safety lepší než v Rustu, protože není potřeba žádný unsafe kód a funguje to i pro dynamické linkování.
> není potřeba žádný unsafe kód
Vzato do důsledků, toto neplatí nikdy v žádném jazyce. Ani pro Hello World v JS.
Ano, runtime Fil-C jsem do toho nepočítal. Nicméně třeba už na standardní knihovnu C++ se ty zároky Fil-C vztahují. Což je podstatné zlepšení v memory safety oproti Rustu, kde je standardní knihovna plná unsafe kódu.
Compiletime je, když sedím v kanclu za stolem. Runtime může být, když jsem na dovolené, pár časových pásem ode mě a další radosti.
Něco pokryjou testy a podobně. Ale když se dá něco ošetřit v compiletime, tak je to prostě jednodušší a příjemnější.
Ano, v runtime. Např. jedna z částí té ochrany je, že každý ukazatel má metadata, která vymezují rozsah paměti, kam jde přistupovat, a to se kontroluje při každém použití ukazatele.
Aniž bych chtěl shazovat práci lidí kolem Fil-C, tak to jejich runtime přístup má zase jiné nevýhody. Protože můžou chytit zápisy mimo oprávněný prostor, ale bez sémantických informací (void* toho moc nesděluje) navíc jen hádají. Stejně tak neodhalí chyby souběhu. Jen zareagují, když náhodou nastanou.
Takže ano - je to pak asi bezpečnější z hlediska exploitů. Ale uživatel bude stejně naštvaný, protože program spadne. A ty runtime kontroly taky sníží výkon, což se třeba u coreutils dost řeší.
kdyz se na to narazilo muzete se tesit na wookash podcast kde je autor fil-c a casey muratori jako co-host. videl jsem to nazivo a prislo mi to super zajimavy nejen z hlediska realizace, ale jak vubec pristoupit k podobnymu typu projektu. jen to typicky vezme tak mesic nez to postriha vyda.
To ale nic nemění na tom, že Fil-C je sanitizer. Tak jak nekompiluju C programy s ASAN nebo UBSAN, tak přesně nechci release binárku s Fil-C, protože mě to uchuzuje o výkon.
> tak přesně nechci release binárku s Fil-C, protože mě to uchuzuje o výkon.
Lide delaji ruzne veci, co je ochuzuji o vykon (napr. kontroluji meze pole, kopiruji objekty, zamykaji, i kdyz to neni potreba), takze proc ne toto, kdyz to prinese lepsi bezpecnost? Na rozdil od ASANu je Fil-C k tomuhle urcen.
Navic, zpomaleni u nekterych aplikaci nemusi byt tak vyrazne - napr. simd heavy aplikace nebo IO-bound aplikace - treba sudo, nebo ruzne servery.
Zkontrolovat meze skoro nic nestojí. Fil-C ale potřebuje mnohem víc paměti a tak jeho běh několikanásobně zpomalí aplikaci.
Cílem je kompletní memory safety - tady se to autor snaží dotáhnout mnohem dál než v Rustu.
S těmi runtime kontrolami máte pravdu, jenže AFAIK není žádný rozšířený jazyk, který by se tomu vyhnul. I safe Rust ošetřuje různé věci za běhu (např. meze pole, nebo vás nutí zamykat, i když žádný souběh nehrozí, nebo musíte zbytečně klonovat objekty, abyste uspokojil typový systém).
To, že se něco musí dělat v runtime ale není argument pro to, že by se tam mělo dělat všechno.
BTW, memory safety by neměl být cíl ale jen implementační detail na cestě ke spolehlivějšímu softwaru. A pád programu na hubu může být i větší problém, než přístup mimo hranice pole. Záleží na tom, co ten software dělá.
Já to beru jako SW, co nejde tak snadno ovládat útočníkem. Osobně mi nepřijde, že by memory safety korelovala se spolehlivostí.
Memory safety vlastně ani není přesně definována. Např. C program mohu odsimulovat v Rustu uvnitř velkého pole, které bude sloužit jako paměť programu. Je takový program memory safe? A pokud ano, je to k něčemu?
Ovládnutí ale není jediný možný útok. Co třeba DoS? Tam sestřelení bohatě stačí.
A s tou vágností memory safety naprosto souhlasím. Celou memory safety si můžeme dát vycpat, pokud program nedělá to, co od něho potřebujeme. A tady vidím zásadní rozdíl mezi přístupem Rustu a Fil-C. Sadomaso kompilátor je víc prevence, zatímco hlídaný běh spíš damage control.
Sice je tam jistý překryv, ale rozhodně nedělají stejnou věc jiným způsobem.
> A tady vidím zásadní rozdíl mezi přístupem Rustu a Fil-C. Sadomaso kompilátor je víc prevence, zatímco hlídaný běh spíš damage control.
Souhlasím pro Rust bez unsafe. Bohužel unsafe je ale prakticky ve všech programech - nějde bez něj zavolat systémovou funkci, pokud chcete dynamic linking, tak Rust nemá stabilní ABI, takže musíte použít cdylib, které opět nejde volat bez unsafe. I kdybychom předpokládali, že unsafe ve standardní knihovně je v pořádku, tak z balíčků na crates.io má cca 20 % unsafe kód. Naneštěstí je psaní unsafe kódu v Rustu vcelku složité, takže je vcelku pravděpodobné, že tam jsou chyby.
Ale při volání cizího kódu jdou záruky pryč i u toho Fil-C. A to nejsou jen systémové funkce. Jakékoliv cizí knihovny v binárkách tím trpí úplně stejně.
Nejde volat kód/knihovny nepřeložené pomocí Fil-C. U systémových volání se memory safety kontroluje.
Tohle je ovšem drobný problém. Troufnu si tvrdit, že na tohle ten projekt umře, pokud ho dřív nezabije něco jiného.
Proč myslíte? Vždyť už dnes s tím přeložíte a zprovozníte mnoho programů. Linuxové jádro ještě ne, ale userland ano - viz distribuce Pizlix.
AFAIK nikdo jiný se nedostal dál. A to je to one-man show. Když to srovnáte třeba s Rustem - kolik lidí na něm pracuje a zatím ani jeho safe podmnožina není memory safe a můžete tam udělat třeba use after free (15 let známý bug).
A jak to nasadím? Musím si přeložit úplně všechny knihovny, které můj software chce používat? Používá se to už někde v produkci?
To, že existuje nějaká memory safe distribuce je úplně jedno. Důležité jsou zalepené díry v reálně používaných programech a běžících službách. Dostal se někam i takhle?
> A jak to nasadím? Musím si přeložit úplně všechny knihovny, které můj software chce používat?
Ano, musíte přeložit vše. Jedna z instalačních metod je stáhnout vše do /opt/fil a provozovat vedle stávajících programů z jiné distribuce. Např. takhle můžete provozovat sshd.
> Používá se to už někde v produkci?
Slyšel jsem, že pro OpenSSH a pro Lighttpd.
S tímhle by se mohlo zajímavě experimentovat v NixOS. Každý balík je tam self-contained, takže sestavit si některé z nich takhle by mohlo být řešitelné.
Dík. Protože tohle mi na těch stránkách chybělo, nebo jsem to minul. Nějaké reference ve stylu "Použili jsme to pro tenhle program a našli jsme tenhle a tenhle bug." Bonusové body by byly, kdyby ten bug normálnímu asanu ušel.
Už s tím Fil-C přestaň. Je to v podstatě za cenu mnohem nižšího výkonu a mnohem vyšší paměťové náročnosti. To v tomto kontextu ten rust je 1000x lepší, protože runtime sanitizer nepotřebuje.
Nemôžete vedieť koľkokrát je čo lepšie, kým si neurobíte merania. A v mnohých prípadoch môže byť spomalenie ospravedlniteľné. Inak za Google tuším asi pred rokom publikoval niekto výsledky výskumu, keď v C++ upravili kontajnery, aby nedochádzalo k prístupu mimo skutočný rozsah, predpokladali výrazne spomalenie, a skutočné bolo, pokiaľ sa dobre pamätám, menej ako 1%.
Tak si s Fil-C zkompiluj třeba celé KDE - bude to pomalé jako prase a budeš na jeho běh potřebovat 2x víc paměti. Fil-C je užitečný hlavně tím, že můžu takto instrumentovat existující kód a hledat v něm bugy (prostě je to další nástroj k ASAN, UBSAN, valgrind, atd...), ale není to pro produkční nasazení vzhledem k tomu, že masivně degraduje výkon.
Rust tento problém nemá, protože ten jazyk je mnohem víc striktní a compiler díky tomu dokáže eliminovat kontroly, které by jinak musel dělat - takže těch runtime kontrol ve výsledné binárce až tak moc není.
Bounds checking jde eliminovat - pokud procházím pole od začítku do konce, tak tam se jednoduše eliminuje jak v Rustu tak v C++. Navíc plno optimalizovaného kódu vůbec nepoužívá standardní kontejnery, ale fixní pole, atd... Stačí stáhnout chromium a podívat se jak je mnoho věcí napsaných.
Fil-C je zajímavý tím, že nemusíš na kód (skoro) hrábnout - to může být podstatné rozhodovací hledisko. Cena je výkon.
Rust je zajímavým svou cenou. Na jednu stranu se člověk musí učit něco nového, změnit způsob myšlení - což bolí. Na druhou stranu Rust jako jazyk je velmi moderní, a na to třeba já dost slyším.
Přesně tak.
Krom toho má Rust velký potenciál v optimalizacích - právě díky omezením na aliasing. A řekl bych i velký potenciál pro sdílení kódu, který je díky typovému systému složitější použít špatně.