Új GnuTLS bug miatt sebezhető egy csomó nyílt forrású szoftver

Címkék

Egy új sebezhetőséget fedeztek fel a Linux disztribúciók által széles körben szállított GnuTLS crypto library-ben. A hiba technikai elemzése elolvasható itt. Patch már van, így érdemes mielőbb frissíteni. Részletek az Ars Technica cikkében.

Hozzászólások

Miert nem irjak ezeket ujra olyan nyelvben, amelyet nem erint a puffertulcsordulas?

Te most a versenyhelyzetről beszélsz, nem? Arra mindig is fogsz találni lehetőséget a jelenlegi nyelvekben.

Itt most inkább arról van szó (nagyon lebutítva a dolgot), hogy túlírhatsz-e, vagy méginkább: túlolvashatsz-e egy konténert (tömböt, etc.), vagy sem. A go legjobb tudomásom szerint erre nem ad lehetőséget (sem a java, sem a python, stb.)

C++ esetén a QVector, és az std::vector bár a többiek szerint megoldásnak tűnik, ott mindig is ott lesz a veszély hogy a túloptimalizáló programozók belenyúlnak a belső reprezentációt ismerve a tömbbe; de hát ez a nyelv ilyen, ad rá lehetőséget. Go pedig nem.

Update: Így van, az én értelmezésem nem egyedi, memory-safety-ről ilyen esetekben beszélünk. (http://en.wikipedia.org/wiki/Memory_safety) Amiről te beszélsz az a contention; egészen más szemantikai szint. (És talán nem is ide tartozik, mert tippem szerint ezek az ssl libek single-threadesek)

a szakmai nyelv pongyolasaga, de amikor 'memoriakorrupcio hiba'-t emlegetunk, akkor igazabol kicsit keverjuk a szezont a fazonnal. a memoriakorrupcio ugyanis nem egy hibakategoria, hanem egy lehetseges tunet. egy puffertulcsordulas (tomb tulindexelese) hibakategoria, de mivel a tipikus esetben ez memoriakorrupciora vezet, ezert pongyolan ugy szoktuk csak mondani, hogy memoriakorrupcios hiba. igy viszont mar talan ertheto eax hozzaszolasa, egy versenyhelyzet hibanak siman lehet memoriakorrupcio a tunete (pl. a nemreg publikalt CVE-2014-0196) es ha egy kornyezet (nyelv, futtatasi rendszer, stb) nem garantalja ezen hibak nemletet (hajra kettos tagadas ;), akkor bizony az nem szamit memory safe-nek. a huszaros megoldas az szokott lenni amugy, hogy a nyelv/rendszer nem tamogatja a tobbszalu vegrehajtast, az osztott memoria hasznalatat, signal-okat, stb es akkor 'eleg' a tobbi memoriakorrupciora vezeto hibakategoria eliminalasa.

PS: The GnuTLS library is thread safe by design

OK-OK értem én, csak azt akartam kiemelni, hogy - ha már véletlenül rosszul fogalmazott - akkor pont ez az a szituáció, amikor van értelme a megkülönböztetésnek, mert arról szól a beszélgetés, hogy vannak nyelvek, amik _ezt_ a fajta hibát (a puffertúlírást-olvasást, stb.) kijavítják, ugyanakkor a párhuzamosításból fakadó hiba szemantikailag magasabb, azt nyelv lehetőségeitől függetlenül el tudod érni.

Nem, amikor azt irom hogy nem memory-safe, akkor azt ugy ertem hogy nem memory-safe. Amit irsz, az igaz a memory-safe nyelvekre (pl. java), de a go-ra nem. Pl.:

test.go

eax@debian:~/go$ go build test.go 
eax@debian:~/go$ gdb ./test
(gdb) run
Starting program: /home/eax/go/test 
0xf840028228
[New LWP 5340]

Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 5340]
0x0000000000400e37 in main.main () at /home/eax/go/test.go:33
33          fmt.Println("boom: ", *m.data) 
(gdb) i r
rax            0x7ffff7f9ef00   140737353740032
rbx            0x4141414141414141       4702111234474983745
rcx            0xf840028270     1066225795696
rdx            0xf840028270     1066225795696
rsi            0x7ffff7f9ef08   140737353740040
rdi            0x7ffff7f9ef68   140737353740136
rbp            0xf840028220     0xf840028220
rsp            0x7ffff7f9eee0   0x7ffff7f9eee0
r8             0x4569b8 4549048
r9             0x47d8b8 4708536
r10            0x0      0
r11            0x470ba8 4656040
r12            0x47d7c8 4708296
r13            0x10     16
r14            0x0      0
r15            0x0      0
rip            0x400e37 0x400e37 <main.main+567>
eflags         0x10206  [ PF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) x/i $rip
=> 0x400e37 <main.main+567>:    mov    (%rbx),%rbp
(gdb) 

--
"You're NOT paranoid, we really are out to get you!"

Ha jól értem, a probléma az, hogy egy metódus két külön szálból meghívódik, és közben memóriát allokáció történik, és míg az egyik jól kiszámolja, hogy akkor
az 5. helyre kell írni, a másik átállítja a tömb méretét 3-ra.

Ez ellen mind a java, mind a c#, mind a python, és talán még a go is véd, ugyanis el fog szállni a kód egy megfelelő exception-nel, mert ott nem tudsz puffertúlcsordulást
csinálni. A c-ben ez nincs védve, gondolom egyszerűen azért, mert megbíznak a fejlesztőben, hogy tudja, mit csinál. Na, ez az, ami miatt folyamatosan puffer túlcsordulás
miatt kell parázni.

az altalad felsorolt nyelvek egyike sem tamogatja a C nyelvbol ismert puffer fogalmat (mivel nem tamogatnak pointereket ill. pointer aritmetikat) tehat puffer tulcsordulasrol eleve nehez beszelni. amit tamogatnak az egy array tipus (ami mas fogalom, mint a C array tipusa), es futasidoben ellenoriznek minden indexelest (cserebe lassulast okozva termeszetesen). de mindettol fuggetlenul a felsorolt nyelvekben is siman lehet versenyhelyzetet okozo kodot irni, es az asm szintu implementaciotol fuggoen ebbol lehet memoriakorrupciot is csinalni. pl. egy array parhuzamos novelese es irasa kozott verseny van (l. a hivatkozott CVE-t), ha a nyelv/runtime maga nem szinkronizalja ezeket korrektul, akkor gaz van, ha meg igen, akkor meg lassu az egesz (python-nal eleve ott a GIL ugye).

Hú, most elgondolkodtattál... Azt találtam, hogy nem igaz az az állítás, hogy java-ban nincsenek pointerek támogatva, mert számomra is most derült ki, hogy
mégiscsak van, igaz, hogy misc-ben, de van.

Itt van a javadoc:

http://j7a.ru/classsun_1_1misc_1_1_unsafe.html

És egy teljesítményteszt, ami összehasonlítja a heap vs bytebuffer vs direct részt:

http://www.javacodegeeks.com/2013/08/which-memory-is-faster-heap-or-byt…

Namost, a direct bytebuffer is tartalmaz range check-et, és érdekes, hogy írásnál ez nem is jelent sebességkülönbséget!!!, csak olvasásnál...

Ez nekem igencsak jónak tűnik, és innentől kezdve jórészt indokolatlannak érzem azt a fajta félelmet, hogy majd az indexelés az lassítani fog.

Viszont, van egy érdekes ötletem... mi van, ha csinálok egy olyan kódot, ami az unsafe-et használja, tudok-e crasheltetni.. és igen, lehet:

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class CrashTest {

private static Unsafe unsafe;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
}
}

public static void main(String[] args) {
long pointer = unsafe.allocateMemory(4);

unsafe.putInt(pointer, 0);

System.out.println(unsafe.getInt(pointer));

System.out.println("Now here comes the crash");

for (long ptr = pointer; ptr < pointer + 500*10000000; ptr = ptr + 4){
unsafe.putInt(ptr, 1);
}

System.out.println(unsafe.getInt(pointer));

unsafe.freeMemory(pointer);
}

}

.NET natív kódra fordul (második körben). Természetesen nem a beépített SSL támogatásra gondolok, az Microsoftos natív kódba hív át, és abban ugyancsak lehetnek még felfedezésre váró hibák.

Persze nem lesz akkora a throughputja, mintha nyers C-ben írták volna, de valamit valamiért. Amíg a fejlesztők optimalizálás néven pont akkora puffereket allokálnak, ami szerintük kell, meg direkt a lehető legkisebb integer adattípusokat használják, addig lesznek ilyen hibák.

--

"Examples of such languages include Ada, Eiffel, Lisp, Modula-2, Smalltalk, OCaml and such C-derivatives as Cyclone, Rust and D. The Java and .NET Framework bytecode environments also require bounds checking on all arrays."

Mondjuk Rust-ban, de a nyelv teljesen mindegy. Csak ne legyen lukas, mert az nem.

szerk:
forras:en.wikipedia.org/wiki/Buffer_overflow
licensz: Creative Commons Attribution-ShareAlike License (WTF?)
+rohadjon meg minden olyan kezdemenyezes amely a felhasznalok szellemi tulajdonat copyrightolja sajatkent. Viva la CC0!

Ezek közül melyik nem interpretált? A Lisp tudtommal az, az Eiffelről is úgy rémlik, bár biztos nem vagyok benne, az Ada elég régi, talán az lehet egy opció, a többiről semmit sem tudok. Viszont attól tartok, hogy a többiek nem is elég elterjedtek ahhoz, hogy olyan helyen használják őket, ahol fontos lenne a biztonság.
De ez utóbbi csak a privát véleményem.

"A Lisp tudtommal interpretált."

Igazad is van, meg nem is. Elvileg az implementálás módja független a nyelvtől magától, a Lisp pedig pont az a nyelv, amelyikre ez gyakorlatilag is nagyon igaz. Tehát a Lisp lehet interpretált, compiled, everything in between, vagy ezek mind egyszerre (ahogy Schrödinger macskája is egyszerre halott és él).

Bár vannak próbálkozások azt nem értem miért nem lehet a fordító szintjén megoldani ezt a problémát, azzal hogy megvédik a stack-et és a heap-et a puffer túlcsordulástól. Természetesen ha a program szarul van megírva, és mindenféle pointereket castolgatnak össze vissza, vagy függvénypointereket használnak, az ellen nem védene, de nagy részt jó lenne. De ahogy látom a meglévő védelmeket sem használják pl.:
http://en.wikipedia.org/wiki/Buffer_overflow_protection

Sokat, mert egy 5msec-es fvg eseteben egy oda vissza valasz (pl adatbazis szerver) es mindjart csak 100req/sec a maximalis atvitel, ugy hogy semmi mast nem csinaltal meg. Egy nagyon surun hasznalt fgv eseteben a vegere tobb 10x gyorsulast is tapasztalhatsz csak mert megsporoltal egyetlen egy step-et processzor szinten

// Happy debugging, suckers
#define true (rand() > 10)

Nem új az, csak most találtak rá :-P

Ki a büdös franc használ GnuTLS-t egyébként... meg is érdemli.

--
GPLv3-as hozzászólás.

Több szem többet lát. Nagy volt a hírverés körülötte, a vendorok és szolgáltatók is beszartak (hiszen őket is érintette), ebből kifolyólag a ZDI és társai fokozottabb örömmel vásárolnak OpenSSL exploitokat és sebezhetőségleírásokat (majd mi jól megvédünk titeket alapon). Mivel nagyobb a kereslet, az erre szakosodott hibakeresők is nagyobb kedvvel, elánnal esnek neki a kód auditálásának. Ebből, és az általam korábban linkelt dologból fakadóan várható, hogy egy csomó OpenSSL biztonsági figyelmeztető fog napvilágot látni.

Ez egy öngerjesztő folyamat. Nincs itt semmi szokatlan látnivaló.

--
trey @ gépház