tak tohle je celkem drsný…
Optimalizace v GCC vytvořila bezpečnostní díru v jádře
Brad Spengler uvolnil exploit. který dokáže přes virtuální rozhraní tun získat práva roota. Takto zneužitou chybu nezastaví dokonce ani SELinux. Postižená jsou jádra 2.6.30 a 2.6.18 (obsaženo v Red Hat Enterprise Linuxu 5). U dalších nebyl výskyt chyby potvrzen. Aby byl exploit úspěšný, jsou potřeba krom zmíněných jader další dvě podmínky a to přístup k /dev/net/tun a moduly PulseAudio.
Dále čtěte…
- Podpora hardwaru v Linuxu 11. 5. 2012 13:25
- Google zrcadlí GIT repositář linuxového jádra 26. 4. 2012 10:39
- Vyšlo jádro 3.3.3 23. 4. 2012 14:58
- Jádra 3.0.28, 3.2.15 a 3.3.2 16. 4. 2012 9:20
- Konec vývoje jádra 2.4 11. 4. 2012 16:12
tak tohle je celkem drsný...
celé vláknoRe: tak tohle je celkem drsný...
celé vláknoJe, ale naštěstí pro GCC je v tom GCC nevinně. :-)
kód?
celé vláknoMohl by mi nekdo objasnit duvod proc ten tun testuje az po jeho pouziti? dik
struct sock *sk = tun->sk; // initialize sk with tun->sk … if
(!tun)
return POLLERR; // if tun is NULL return error
Re: kód?
celé vláknototo je v pohode, lebo robis so smernikmi, ak nie je pre tym ifom pouzity socket sk, tak je to korektna konstrukcia…
Re: kód?
celé vláknonechapu jak to muze byt korektni? dyt tam dela neco jako NULL->sk, to prece musi spadnout ne?
Re: kód?
celé vláknonie nepadlo by to, keby tam ten if ostal…
Re: kód?
celé vláknoSamozřejmě že by to padlo – nebo aspon mohlo padnout, protože je to nedefinované chování (například pokud by se ta hodnota nikdy nepoužila, může na ni kompilátor úplně zapomenout)
Něco jinýho by bylo
struct sock **sk = &tun->sk;což je OK i pro tun == NULL (ačkoli výsledná hodnota sk je v tom případě neplatná)
Re: kód?
celé vláknoTo je právě ta chyba. Asi to přišlo vývojáři more cool to napsat přímo v inicializaci ;)
Ve skutečnosti je optimalizace gcc korektní. Bez něj by to sice nebyla přímo díra se zneužitelnosti roota, nicméně by to stejně padalo jak shnilé hrušky a titulek je tedy značně zavádějící.
Re: kód?
celé vláknoNemyslim ze je korektni ta optimalizace. Myslim ze hrabat optimalizatorem do if ( pointer == NULL ) neni nikdy moc chytre, pokud neni kompilator opravdu genialni. Co treba
d1 = struct_data1, d2 = struct_data2, *s = random_z_( &d1, &d2 ) - &d1;
x = (&d1 + s)->mujX;
if ( !s ) { ... neco s d2 ... } else { ... neco s d1 ... }
Pochopi GCC ze se nejedna o klasicky NULL test ale vetveni kodu?
To inicializovani promenne s NULL pointrem v linuxu padne tak jako tak (i pri cteni), kdyz ten proces nema tu pamet, ne? Nebo cteni projde? Ale je to teda pekne pitoma frajerina, proc to nenechaji nenainicializovane a nepriradi tu hodnotu az za ifem, to nechapu.
Re: kód?
celé vláknoTo gcc do něj nehrabe, ten původní kód je napsaný tak, že nejdřív ze struktury čte data a potom teprv testuje, zda ta struktura není NULL. Na základě toho (úspěšného, viz * níže) čtení gcc usoudí, že struktura NULL být nemůže (když se z ní dříve úspěšně četlo) a test na str == NULL úplně vyhodí.
Takže i výše zmíněný kód gcc zpracuje korektně, bo nemůže tušit, co v tom „s“ vlastně bude. Kdyby předtím bylo ještě a = *s, tak rovněž část kódu za if (!s) vyhodí (pominu-li to, že s by měl být ptrdiff_t, takže by kód bylo třeba výrazně upravit).
- – za normálních okolností by spadnul, v tomto případě si exploit předtím na adresu 0×0 namapuje validní stránku.
Není to frajeřina, je to prostě jen chyba při vývoji.

