Ako tu bolo písané predomou: vy nevidíte rozdiel medzi Javou a Rustom? V jave som kedy si programoval, Rust bohužiaľ poznám len teoreticky. Ale ten základný rozdiel je v tom že Java nie je len jazyk ale aj framework a behové prostredie kde kód je predkladaný do “medzikódu” pre toto behové prostredie, ktoré môže výrazne ovplyvniť funkčnosť a bezpečnosť.
Rust je len jazyk a podobne ako C/C++ je prekladaný už priamo pre danú architektúru, čiže bezpečnosť je tam viac závislá priamo na kóde a čiastočne na kompilátore, nie je tam žiadny JVM či medzijazyk.
Jadro Linuxu sa s vydaním novej verzie znovukompiluje a teda udržiava aktuálny aj kompilát toho čo je napísané v Ruste.
Rust treba chápať skôr ako moderné “C-čko”, ktoré ako to vyzerá sa uchycuje a poskytuje mnoho výhod a veľmi malo nevýhod voči C/C++
Java se samozrejme stejne jako kod v libovolnem jinem jazyce (treba i javascript) da prekompilovat do binarni podoby. V tom zadny rozdil neni.
Stejne tak jako aktualni kompilator typicky neprekompiluje 20let stary kod, tak stary kod javy nepobezi na aktualnim jre. V tom taky zadny rozdil neni.
Presne proto se to pouzivat presne tak, jak se to pouziva. Ty jazyky a jejich nastroje nejsou kompatabilni ani samy se sebou. A presne proto se pouziva C/C++ ... protoze tu kompatabilitu udrzuje zdaleka nejlepe.
Cize Java 1.6 ktora vysla v roku 2006 a je uz nepodporovana obsahuje nejake chyby a nie je to chyba skor toho SW alebo admina?
Myslite ze 17 rokov stary system beziaci SW na baze RUSTu bude bezpecny?
Mame iny jazyk alebo techniku ktora zabezpeci ze ak na nieco kasleme 17 rokov tak to bude stale bezpecne?
Dává to smysl, jen ho nevidíš.
Z Rustu se volá např. externí PAM knihovna napsaná v C. Standardní C sudo dělá úplně to stejné, volá tu stejnou externí PAM knihovnu. Akorát v tom C není explicitně zmíněné, že je to unsafe (protože v C je unsafe úplně všechno). V Rustu máš informaci o tom, že voláš unsafe kód. Takže situace mnohem lepší než v C sudo.
Až někdo přepíše PAM do Rustu, tak tam unsafe nebude. Musíš počkat, nejde přepsat celý Linux do Rustu najednou, chce to nějaký čas :-).
Vy jste všichni hrozně omezení svým viděním z C světa. Pravda je taková, že dynamické knihovny se v Linuxu hodně používají, ale je to spíš takový relikt minulosti, který se hodí jen pro C kód (není to dobré aní pro C++ ). Důvody jsou následující
Můžete namítat, že při bezpečnostní chybě v dynamické kníhovně (ta bezpečnostní chyba je typicky v C ne v Rustu :--)), nemusím znovu překládat všechny aplikace, ale stačí vyměnit dynamickou knihovnu. Tento argument přestal být relevantní s nástupem kontainerizace a dockeru, protože se typicky provozuje jedna aplikace v kontajneru a stejně se musí vyměnit celý kontainer.
Mimochodem Rust umí vyrobit i nativní dynamickou knihovnu (viz dylib) s Rust ABI, prakticky to ale nikdo nepoužívá z výše uvedených důvodů, má to spoustu nevýhod.
sudo nemám v kontajneru, ale jsem naprosto v pohodě s tím, když bude PAM staticky přilinkovaný k sudo. Ty bezpečnostní záplaty, kvůli kterým se typicky dělá upgrade dynamické knihovny, budou totiž s Rustem asi tak 10x méně častné než s C. Bonusy jako LTO a vyšší výkon aplikací jsou tak nějak v ceně.
Problém je v tom, že v něčem tak obrovském jako Linux ty dynamické knihovny používá kdeco, většinou půjde o programy v C (nebo C++, prostě cokoliv závisle na C ABI). Linkovat knihovny přepsané do Rustu staticky znamená nafouknutí všech binárek, co nějakou takovou knihovní používají. Prostě když třeba nějaké CL utility A, B, C používají knihovnu L, je blbost linkovat ji všude staticky a ještě ji mít jako dynamickou pro aplikace D, E, F, které ji taky potřebují a zatím nebyly přepsány do Rustu.
P.S. Možná by pomohlo mít něco jako pluginy v Go, ale to pořád neřeší ten starý kód napsaný v C(++).
1. 5. 2023, 10:28 editováno autorem komentáře
I v Rustu jde vyrobit dynamickou knihovnu s Rust ABI, ale není to úplně dobrý nápad, protože by to znamenalo nutnost udržovat stabilní ABI a kam to vede, nám ukázalo C++.
Swift nedělá monomorfizaci generik, zkompiluje jednu instanci funkce pro všechny typy a řeší se to pak v runtime. Tím se zjednodušuje udržení stabilního ABI, ale stojí to výkon. Rust ani C++ touto cestou nejdou, preferující vyšší výkon a vytváří instanci pro každý typ v compile time. Vždycky je to něco za něco.
1. Sice je pravda, ze nejde urobit tree shaking, ale je to uplne bezpredmetne. Pokial je funkcia v binarke na disku, nech si tam je. Do pamate bude nastrankovana len vtedy, ak ju nieco realne pouzije (resp. pouzije nieco v tej istej 4k stranke).
Naproti tomu to, ze dynamicka kniznica je zdielana medzi rozlicnymi procesmi prinasa radovo vyssie uspory v spotrebe pamate.
2. Ano, musia udrziavat stabilne ABI, a pokial s tym ma jazyk problem, je to problem jazyka, nie konceptu ABI. Pokial kniznice priebezne menia ABI/API, tak to vytvara zbytocny churn pre vsetkych.
3. Co tu nebolo spomenute je to, ze dynamicke kniznice sa pouzivaju aj ako pluginy, na rozsirenie funkcnosti. V glibc je to napr. cely nsswitch, pam samotny ma modulov tiez pozehnane. Zalinkovat vsetky do kazdej binarky tiez nie je riesenie, pouzivatel moze doinstalovat dalsie a nakonfigurovat system tak, aby sa pouzivali (vid napriklad sssd).
Tedy mě prosím opravte:
- na počátku to bylo tak jak říkáte, tři aplikace používali jednu dll/so knihovnu, kterážto byla díky tomu v paměti jen jednou.
- následně se začalo šašit s bezpečností, a tak díky bezpečnosti i když tři aplikace pužívají tu samou sdílenou knihovnu, tak každý z nich ji má načtenou znova protože soukromej paměťovej prostor.
- změnilo se od té doby něco?
Jenže ony jsou to jaksi PAM moduly které se dají prostě doinstalovat. Nemyslím si že se někomu chce rekompilovat celé sudo kvůli přidání autentizační metody.
Navíc dynamické linkování je skvěle pokud chcete mít něco co systém prostě programům poskytuje, co si netahají samy.
Souhlas, C ABI věci nejsou ideální, ale co nám zbývá.
"Vy jste všichni hrozně omezení svým viděním z C světa"
A ty ses zjevne blazen. Zadny dodavatel zadne aplikace nebude denne kompilovat nove verze proto, ze se v nejake z tisicovek knihoven ktere ta aplikace at uz primo nebo neprimo pouziva, objevil nejaky bug.
Nejen ze to nebude kompilovat, on se tim vubec nebude zaobirat, protoze neni v nicich silach ani jen sledovat co kde ma zrovna dneska novou verzi. Natoz resit, ze se opet pomilionpate zmenilo api, a je treba neco nekde prepsat.
Záleží, co dodáváš.
Binární aplikaci koncovému uživateli? Fajn, tam mají tvoje argumenty asi trochu smysl a může být řešením linkovat to proti dynamickým knihovnám v C, pokud neřešíš bezpečnost. Ale i to je diskutabilní, ty dynamické knihovny v C musíš každou chvíli updatovat, protože bezpečnost C je tragická a stále se objevují nové chyby. Pokud bys linkoval staticky Rust kód, nemusíš updatovat kvůli paměťovým bezpečnostmím chybám, ty tam nebudou. To ušetří spoustu práce a administrativy s updaty. Jako bonus máš navíc vyšší bezpečnost a výkon.
Pokud dodáváš service jako docker kontajner do cloudu pro spustu uživatelů, tak to je úplně jiná písnička, tam je dynamické linkování s C knihovnami přímo kontraproduktivní, nemá to žádné výhody, jen spoustu nevýhod, plus to s sebou nese tragickou bezpečnost C kódu. Použití Rustu se statickým linkováním Rust knihoven je mnohem lepší volba.
No to si při vší uctě nemyslím. Pokud například srovnáte linux driver pro e1000 psaný v C a ten co byl jako reference psán v Rustu, tak je to imho jako nebe a dudy. Rust je zkrátka modernější jazyk, jeho čitelnost a rychlost pochopení toho o co v kódu jde, je imho jedna z jeho hlavních devíz. Nicméně ano, je to nejspíš z části můj subjektivní pocit :)
To ano, ale přepis do například C++20 by měl podobné výhody.
To by měl i "přepis do C", tj. kdyby ho někdo dneska napsal znovu od nuly a pořádně. Ono je dost nefér porovnávat historický kód, který vznikl v určité době, za určitých okolností a pak se ještě dlouho vyvíjel, s kódem napsaným čistě od nuly. On ten rust driver taky za dvacet let nebude vypadat tak krásně - pokud by se tedy těch dvacet let opravdu používal a udržoval. Ale do propagandy se takové srovnání samozřejmě hodí, jakkoli to o vhodnosti jazyka pro daný účel vypovídá pramálo.
Druhá polovina problému je samozřejmě i to, že jakýkoli nově napsaný driver nevyhnutelně bude míst své nové vlastní chyby. A uživatelé jsou obvykle citlivější na to, když najednou přestane fungovat něco, na co byli zvyklí, že to fungovalo. Nebo i na to, když se něco začne chovat trochu jinak, než byli zvyklí.
Kolega IMHO prostě myslel, že defaultní úroveň (paměťové) bezpečnosti je u Rustu vyšší než u (moderního) C nebo C++.
V tom právě vidím ten největší problém, v tom dokolečka opakovaném dogmatu, že cokoli napsané v C je automaticky fuj a cokoli napsané v rustu je automaticky super (a super bezpečné). S důsledky téhle zaslepenosti si bohužel asi užijeme ještě spoustu legrace.
Tak ona to není do určité míry pravda? Ta rovnice je IMHO takto:
Abyste v C napsal dobrý program, musíte bejt fakt dobrej.
Abyste v Rustu napsal špatný program, musíte bejt fakt blbej.
To znamená, pro průměrně inteligentního/schopnýho programátora je C fuj, a Rust supr. Rust není samospásný, ale dává možnosti které C prostě nemá.
Já jsem pochopil Rust tak, že jeho benefitem (oproti) C je v tom, že buzeruje.
Je to stejný jako zásada, že máte psát program/funkci co dělá jednu věc. Protože člověk má omezené mentální kapacity, a tak, pokud musí hlídat všechno (C/C++), tak mu zkrátka nezbude kapacita ohlídat všechno. Zatímco, když tu hrubou práci odvede stroj (Rust), tak se může soustředit na další problémy a odchytá toho víc.
Samozřejmě čas teprve ukáže o kolik Rust tu laťku bezpečnosti/užitečnosti posunul. Už teď je ale vidět, že je to o dost.
He, napadlo mě ještě lepší přirovnání, díky tomu, že se momentálně věnuju parserům:
Můžete mít parser, který vám oznámí, že v kódu je chyba. Neřekne kde ani jaká.
A nebo můžete mít parser, který vám řekne, že na řádce 30, sloupci 5 očekává jednu z těchto možností (A, B, C).
Ano, někdo jako pan Kubeček, může prohlásit, že v tom nevidí rozdíl. A má pravdu, že pracovat se dá i s prvním případem. A rozhodně má pravdu, že v obou případech je v kódu chyba.
Já si ale dovolím být rebel, a ignorovat jeho názor, a budu psát parsery přeci jen tím druhým způsobem ;-)
"V tom právě vidím ten největší problém, v tom dokolečka opakovaném dogmatu, že cokoli napsané v C je automaticky fuj ..."
Cokoi napsane v cemkoli je fuj, pokud to pise prase. A jelikoz takovych je cim dal vic, tak to presne podle toho vypada.
Ja si covolim naprosto kacirsky tvrdi, ze kod v C je daleko bezpecnejsi - pokud ho napise nekdo, kdo vi co a proc dela. Zatimci v rustu (nebo dalsich) se spoleha na to, ze se o to postara nekdo jiny.
Zatim se totiz (opakovane) historicky ukazuje, ze pan Ono Seto Samo .. neexistuje.
Zatim se totiz (opakovane) historicky ukazuje, ze pan Ono Seto Samo .. neexistuje.
Přesně to jsem měl na mysli. Za dobu, co se programováním zabývám, jsem už zažil tolik (údajně) zázračných a revolučních jazyků, o kterých jejich věrozvěstové hlásali, že v nich nejde psát špatně a že v nich budou dobré programy psát i špatní programátoři. Některé upadly v zapomnění (prolog anyone?), některé se se skřípěním zubů stále používají, protože v nich v tom svatém nadšení byly napsány velké projekty, které není praktické zahodit a přepsat od nuly, některé se stále používají i bez velkého skřípání zubů, ale také už bez toho velkého nadšení. Jedno ale mají všechny společné: žádný nesplnil ty nerealistické sliby, jak v nich zázrakem nepůjdou psát špatné programy a že v nich bude psát skvěle i špatný programátor.
Což není to samé, jako tvrzení, že v Rustu nejde napsat špatnej program, které tu tlačíte vy.
Přečtěte si moje příspěvky. V každém, doslova v každém jsem napsal noticku o tom, že Rust není všespásný. A v každé, doslova každé vaší reakci je ignorována. Vaši motivaci nechápu.
Smiřte se s tím. Rust je celkem dobrej počin.
Což není to samé, jako tvrzení, že v Rustu nejde napsat špatnej program, které tu tlačíte vy.
Rozdíl je minimální - a hlavně zanedbatelný proti tomu, jak daleko jsou obě verze toho tvrzení od reality. Realita je taková, že rust do značné míry brání jednomu specifickému druhu chyb, které se v programech mohou vyskytnout. To není málo, ale nezabrání všem ostatním chybám a už vůbec nezabrání psaní špatných programů. A ne, na to, aby někdo napsal v rustu špatný program, vůbec nemusí být "úplně blbej", rozhodně ne o nic víc než na to, aby ho napsal v jakémkoli jiném jazyce.
Realita je taková, že ten jeden specifický druh chyb, kterému Rust zabrání, je zodpovědný za 70% všech bezpečnostních chyb: https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/
Zbavit se 70% bezpečnostních chyb je velká věc, proto se Rust tolik tlačí. Firmám to totiž v dlouhodobém horizontu ušetří spoustu peněz, bezpečnostní chyby jsou hodně drahé. Peníze stojí jak samotné opravy, tak i administrava s updaty, to jsou přímé náklady. Pak tu máme nepřímé náklady ve formě možného úniku citlivých dat a případná ztráty reputace, když se nějaká chyba medializuje. Tohle se špatně vyčísluje, ale levné to nebude.
...je zodpovědný za 70% všech bezpečnostních chyb
Bohužel mám poměrně dobrou představu, čemu je dnes zvykem říkat bezpečnostní chyba (hint: mezi vývojáři se zkratka CVE často cynicky interpretuje jako "CV Enhancement"), takže jakkoli to číslo zní drsně, samo o sobě mne moc neohromuje.
...bezpečnostní chyby jsou hodně drahé. Peníze stojí jak samotné opravy, tak i administrava s updaty, to jsou přímé náklady.
Námět k zamyšlení: myslíte že "nebezpečnostní" chyby drahé nejsou? A co třeba neefektifvně napsané programy, kde operace nebo výpočty trvají zbytečně dlouho? Nebo třeba neprakticky navržené uživatelské rozhraní, kvůli kterému uživatelům práce trvá déle a navíc je ještě frustruje? To nestojí spoustu peněz?
Bohužel mám poměrně dobrou představu, čemu je dnes zvykem říkat bezpečnostní chyba (hint: mezi vývojáři se zkratka CVE často cynicky interpretuje jako "CV Enhancement"), takže jakkoli to číslo zní drsně, samo o sobě mne moc neohromuje.
Takže nepopíráš, že 70% identifikovaných bezpečnostních chyb je způsobeno chybnou správnou paměti v C/C++, ale zároveň říkáš, že tě to neohromuje a vlasně to není až tak velký problém. To je opravdu zajímavý přístup, protože chybná správa paměti prakticky vždy vede k možnosti remote code execution, pokud má útočník možnost ovlivnit vstup programu (což typicky má). Docela dost to vypovídá o celé této diskuzi. Naštěstí jsou lidé jako ty v menšině (i když jsou docela hlasití), takže máme dobrý důvod věřit tomu, že se situace na poli bezpečnosti zlepší, i když to bude běh na dlouho trať.
Takže nepopíráš, že 70% identifikovaných bezpečnostních chyb je způsobeno chybnou správnou paměti v C/C++
K domu se nemůžu vyjádřit, ta data a metodiku jsem neviděl. Ale vzhledem k tomu, že vím, že výrazná většina toho, co se dnes označuje za bezpečnostní chyby, má ve skutečnosti zanedbatelnou závažnost a velká část jsou dokonce úplné ptákoviny, nemá to číslo, i kdyby nakrásně bylo pravdivé, moc velkou vypovídací hodnotu.
chybná správa paměti prakticky vždy vede k možnosti remote code execution, pokud má útočník možnost ovlivnit vstup programu (což typicky má)
K tomu se ale vyjádřit můžu, protože mi z podstaty mé práce těch "bezpečnostních chyb" rukami projde poměrně dost. Tohle tvrzení není pravda ani zdaleka. A navíc i ten předpoklad, že má (vzdálený) útočník možnost (v dostatečné míře) ovlivnit vstup, je sám o sobě hodně silný a většina CVE ho nesplňuje. Ve výsledku je (naštěstí) remote code execution spíš výjimkou než pravidlem* a i z nich je většina vázána na dodatečné podmínky, typicky že je natažený a aktivní nějaký nepříliš používaný modul. (Velké procento CVE vzniká tak, že nějaký nadšenec vypustí static checker nebo tool typu syzkaller na nějaký starý, dnes už téměř nepoužívaný a nepříliš udržovaný modul a nareportuje výsledek, obvykle aniž by se obtěžoval ověřit, jestli jsou podmínky té chyby opravdu prakticky splnitelné (nebo dokonce vynutitelné) a pokud vůbec ano, jestli se ta chyba dá i nějak využít. To by totiž bylo moc práce a on by nestihl nabrat tolik zářezů.)
* - tvrdíte, že 70 procent bezpečnostních chyb je způsobeno problémem s memory safety a zároveň tvrdíte, že tento typ chyb "prakticky vždy" umožňuje RCE; z toho mi vychází, že podle vás by asi tak dvě třetiny bezpečnostních chyb měly umožňovat RCE.