Meltdown i Spectre (2018)
Dvadeset godina si vjerovao da ti procesor ne laže — laže, i to je bila cijena brzine.
Siječanj 2018. Nova godina, iste navike: kave, e-mailovi, cloud serveri koji tiho vrte svoje petlje negdje u dvorani hladnoj kao mrtvačnica. Otprilike dvadeset godina softver je živio u jednom uvjerenju koje nitko nije ni izgovarao naglas, jer se izgovara samo ono u što sumnjaš. Procesor je stijena. Sve što se događa iznad njega — operacijski sustav, aplikacije, tvoj bankovni PIN koji upisuješ vjerujući da ga nitko ne gleda — sve to sjedi na jednom čvrstom kamenu koji ne laže. Von Neumann je 1945. skicirao ideju da program i podaci žive zajedno, u istoj memoriji (K1, poglavlje 11), i od tog trenutka svi smo gradili na pretpostavci da je razina ispod nas riješena stvar. Ne provjeravaš temelje kuće svako jutro prije doručka. Vjeruješ da stoje.
A onda, u tom siječnju, netko je pokucao na taj temelj i čuo šuplji zvuk.
Ne jedan tim. Više njih, neovisno, u istom tjednu otkriva da je nešto duboko krivo — ne u nekom API-ju, ne u trećem redu neke funkcije koja nikad nije trebala postojati. Krivo je u samom siliciju. U tranzistorima — onim sitnim sklopkama koje se pale i gase milijardu puta u sekundi i od kojih je sagrađen svaki procesor na svijetu. Krivo je u triku brzine koji su inženjeri ugradili u procesore još devedesetih, s najboljim namjerama, jer je ubrzavao sve, a nitko nije ni sumnjao da bi to ubrzavanje jednog dana moglo biti sigurnosna rupa.
Zovu ih Meltdown i Spectre — imena koja su, ironično, previše dobro pogodila. Jedno će se moći ugasiti relativno brzo. Drugo će, kako mu ime kaže, progoniti industriju godinama, jer problem nije u jednom čipu ili jednoj grešci — problem je u ideji koja je desetljećima bila znak inženjerske genijalnosti: procesor koji pogađa što ćeš tražiti prije nego ga pitaš, samo da bi bio brži.
Tu genijalnost sad treba objasniti kao zločin. I to je prava priča ovog poglavlja — kako se najpouzdaniji dio računala, onaj u koji nitko nije ni sumnjao, pretvorio u najveću sigurnosnu jezu desetljeća. Ne zato što je netko pogriješio jednom, nego zato što je cijela struka, dvadeset godina, jurila brzinu — a brzina, pokazalo se, ima cijenu koju plaćaš tek kad je netko dovoljno strpljiv da je pronađe.
Zamisli konobara u kafiću koji te poznaje bolje nego što bi trebao. Sjedneš, još nisi otvorio usta, a on već stavlja espresso na tvoj stol. Kako zna? Ne zna, zapravo — pogađa. Devet od deset puta naručiš isto, primijetio je to, i da ti ne bi čekao, pripremi kavu unaprijed. Pogodi — sjajno, ušparao si trideset sekundi. Pogriješi — baci kavu, napravi ti onu koju stvarno želiš, i jedino što si izgubio su ta ista trideset sekundi koje bi svakako čekao. Nikad ne gubiš, samo eventualno ne dobivaš bonus. Genijalno, zar ne?
E, otprilike to tvoj procesor radi cijelo vrijeme, već dvadesetak i više godina. Zove se spekulativno izvršavanje, i to je jedan od onih trikova zbog kojih je računalo na kojem ovo čitaš stotinama puta brže od onoga s kojim si možda odrastao. Procesor, dok čeka da mu program kaže što dalje, ne sjedi skrštenih ruku. Gleda kôd, gleda uzorke, i kaže si: dobro, sudeći po ovome što se do sad događalo, sljedeći korak će vjerojatno biti X. I onda izvrši X. Unaprijed. Prije nego što je uopće siguran da to treba.
Ako pogodi — a pogađa nevjerojatno često, jer kôd se ponaša predvidljivo, petlje se vrte, uvjeti se rijetko iznenađujuće granaju — rezultat je već tu, spreman, i program samo produži bez čekanja. Ako ne pogodi, procesor tiho baci taj rezultat u smeće, kao konobar koji baci pogrešnu kavu, i vrati se na pravi put. Iz perspektive programa, ništa se nije dogodilo. Kôd radi isto što bi radio i bez ovog trika — samo brže. Barem je to bila teorija dvadesetak godina.
I ovdje dolazimo do stvari koju treba dobro upamtiti, jer je cijelo poglavlje o njoj: ova ideja nije nešto što je Intel smislio prošle godine u nekom sprintu. Spekulativno izvršavanje je temelj — literalno temelj, sloj ispod svega što softver misli da radi — ugrađen u procesore od devedesetih. Kad kažemo „gotovo svaki procesor napravljen u posljednja dva desetljeća”, ne pretjerujemo za efekt. Intel, AMD, ARM u tvom telefonu, čip u tvom autu, u pametnom satu, vjerojatno i u onom smart toasteru kojeg ti nitko nije tražio da kupiš — svi rade na istom principu. Pogodi unaprijed, ubrzaj, ako pogriješiš baci i nitko ne primijeti — a to ubrzavanje se često oslanja na cache, ono malo, brzo skladište podataka odmah pored jezgre procesora, gdje čip čuva stvari za koje sumnja da će mu ponovno zatrebati.
I nitko — inženjeri, arhitekti čipova, ljudi koji su ovo dizajnirali, patentirali i slavili kao pobjedu performansi — nije mislio da je to sigurnosni problem. Zašto bi mislili? Rezultat pogrešnog pogađanja se baci. Program ga nikad ne vidi. Iz softverske perspektive, spekulacija je nevidljiva, savršeno tiha, savršeno neprimjetna. Dvadeset godina to je bila jedna od onih čistih inženjerskih pobjeda gdje dobiješ brzinu bez ikakve cijene — barem naizgled bez cijene. Cijeli je informatički svijet počivao na jednoj tihoj pretpostavci: što se događa unutar čipa, ostaje unutar čipa.
Jer istina je bila drugačija. Baciti rezultat ne znači da rezultat nikad nije postojao. On je, na trenutak, sjedio negdje — u cacheu — i taj trag, ta sjena rezultata koji je »nikad postojao«, ispostavilo se, može se izmjeriti. Ne pročitati direktno, ne, procesor nije tako glup. Ali izmjeriti brzinu — koliko brzo se nešto dohvati iz cachea protiv koliko sporo se dohvati kad tamo nije — i iz te brzine, strpljivo, bit po bit, rekonstruirati što je ta sjena zapravo sadržavala.
Siječanj 2018. Dvadeset i nešto godina tihe, neprimjetne, obožavane pobjede brzine — i onda, jednog jutra, cijela industrija shvati da je konobar, dok je unaprijed spremao kavu, cijelo vrijeme ostavljao trag na stolu koji svatko strpljiv može pročitati. I taj trag nije bio u kavi. Bio je u siliciju.

Curenje kroz vrata brzine
Dobro. Ali zamisli da konobar, kad pogodi krivo, ne samo baci kavu — nego je stavi na pult, na sekundu, prije nego je sakrije. I zamisli da postoji način da odškrinutih očiju, s druge strane šanka, izmjeriš KOLIKO BRZO se ta kava pojavila i nestala. Iz te brzine možeš pogoditi što je bilo u šalici. Nisi vidio kavu. Ali znaš da je bila tu. To je, u jednoj rečenici, cijeli Meltdown i Spectre. Procesor pogodi, procesor pospremi za slučaj da je pogodio dobro, procesor onda skuži da je pogriješio — i sve poništi. Barem misli da je sve poništio.
Jer ono što se stvarno poništi jest rezultat u registrima — ono što se vidi na prvu. Ali dok je spekulativno izvršavao tu pogrešnu granu, procesor je usput dotaknuo memoriju, a memorija koju dotakneš završi u cacheu. Cache ne briše kad se spekulacija poništi. Zašto bi? Sa stajališta samog čipa ništa se loše nije dogodilo — samo je jedna od tisuću grana koje istovremeno istražuje ispala pogrešna, i on se vratio na pravi put. Trag u cacheu ostaje sjediti tamo kao otisak stopala na pijesku nakon što je val, naizgled, sve zaravnao. Problem je što taj otisak možeš izmjeriti. Ne pogledom — vremenom. Očitavanje podatka koji je već u cacheu traje, recimo, četiri nanosekunde. Očitavanje podatka koji nije u cacheu traje četrdeset. Napadač ne treba VIDJETI tajnu. Napadač treba samo štopericu i dovoljno strpljenja da isproba svih 256 mogućih vrijednosti jednog bajta, mjeri koja je brza — i bingo, upravo je pročitao bajt memorije koji mu formalno nije bio dozvoljen ni pipnuti. To se zove »side-channel napad« (napad kroz pokrajnji, nuspojavni trag), i genijalnost, pa i jeza cijele stvari je da ne napada podatak. Napada nuspojavu brzine kojom je čip radio nešto sasvim drugo.
Sad, Meltdown i Spectre nisu ista rupa, i vrijedi razdvojiti tko je što zapravo skrivio, jer to će ti se vratiti kroz cijeli ostatak priče. Meltdown je Intelova specifičnost — njihov procesor je bio toliko agresivan u pogađanju da bi dopustio da spekulativna instrukcija PROČITA memoriju kernela prije nego je uopće provjerio ima li program dozvolu za to. Kernel je onaj privilegirani dio operacijskog sustava koji upravlja hardverom i memorijom cijelog računala — šef osiguranja koji sve nadzire, dok su svi tvoji obični programi samo gosti koji smiju hodati po predviđenim stazama. U toj kernelovoj memoriji sjedi ono što baš nikome vani ne bi trebalo biti dostupno: tvoja lozinka, tuđi podaci u istom stroju, sve što drži sustav na okupu. Provjera dozvole se dogodi, ali kasno — kad je šteta, onaj trag u cacheu, već ostavljena. Zamisli osiguranje na koncertu koje te pusti unutra, dozvoli da uđeš u backstage, i TEK ONDA pogleda karticu i kaže: ups, nemaš pristup, izlaz. Ali ti si već vidio što je iza vrata. Meltdown je zato bio i strašan i, ironično, lakši za rješavanje: dovoljno je bilo naučiti procesor da provjeri karticu PRIJE nego pusti gosta unutra. Zakrpa (uz cijenu o kojoj sljedeća sekcija priča) i problem je uglavnom saniran, i uglavnom samo za Intel.
Spectre je druga priča, i ime nije nasumično birao tim koji ga je otkrio — htjeli su nešto što će te progoniti, duha kojeg ne možeš jednom zauvijek istjerati. Spectre ne ovisi o jednoj arhitekturnoj mušici jednog proizvođača. Napada samu ideju predviđanja grananja — onaj dio procesora koji, kao vozač koji ne čeka semafor da stvarno pocrveni nego kreće po pretpostavci, unaprijed pogađa koju granu koda ćeš vjerojatno slijediti, da ne bi gubio vrijeme čekajući odluku. Tu ideju koriste svi moderni procesori — Intel, AMD, ARM, čip u tvom telefonu, u tvom autu, u tvom pametnom hladnjaku, ako je dovoljno pametan da uopće ima procesor. Umjesto da probije zid između korisnika i kernela kao Meltdown, Spectre nagovara sam program da spekulativno pročita nešto što ne bi trebao — trenira predviđanje grananja da pogriješi na baš pravom mjestu, u pravom trenutku, i onda mjeri isti onaj trag u cacheu. Nema jednog jasnog mjesta za zakrpu, jer nema jedne greške. Postoji desetak varijanti, i istraživači i danas, godinama poslije, otkrivaju nove. Otud i ime — ne rupa koju zatvoriš i zabetoniraš, nego duh koji se vraća.
Ono što oba napada zajedno dokazuju — a to je dio koji je najviše zaboljao ljude koji su cijelu karijeru vjerovali u odvojenost procesa, onu svetu granicu koju operacijski sustav postavlja između tvog preglednika i tuđeg preglednika, između tvoje aplikacije i bankovnog softvera koji radi na istom stroju u istom trenutku — jest da ta granica postoji SAMO na razini softvera. Fizički, na razini silicija, sve to vrijeme sjedi u istom cacheu, na istom čipu, i sve što treba jest dovoljno strpljiv napadač sa štopericom da tu granicu pregazi bez da je ijednom formalno prekrši. Nije provalio kroz vrata. Mjerio je koliko brzo se vrata otvaraju i zaključio što je iza.

Otkriće i koordinacija
Sad dolazimo do dijela priče koji zvuči kao znanstvenofantastični triler, ali je zapravo birokratska drama s malo panike umiješane. Ljeto 2017. Negdje u Googleu, tim koji se zove Project Zero — Googleov interni sigurnosni odjel, ne neka vanjska agencija, ljudi kojima Google plaća plaću baš zato da cijeli dan budu paranoični za tebe i traže rupe u tuđem (i vlastitom) softveru — nabasa na nešto što im se ne sviđa. Ne mala rupa. Rupa u samom procesoru.
I onda, kao u onoj sceni gdje svi likovi istovremeno posegnu za istim pištoljem, otkrije se da nisu jedini. Neovisno, u istom razdoblju, do sličnih zaključaka došli su akademici s Tehničkog sveučilišta u Grazu u Austriji, pa još jedan tim, pa još jedan. Nitko nije nikome rekao, nitko nije kopirao tuđi rad. Naprosto, kad je ideja dovoljno zrela, više pametnih glava dođe do nje u istom trenu. Zvuči poznato? Trebalo bi. Isto se dogodilo s integriranim krugom — Kilby i Noyce, dvije strane kontinenta, isto rješenje, u razmaku od par mjeseci, bez da su se ikad čuli. Znanost i inženjerstvo ne čekaju tvoj kalendar. Kad je vrijeme zrelo, otkriće se dogodi na više mjesta odjednom, kao da je zrak sam nosio ideju.
Samo — ovo nije bio novi čip koji ćeš kupiti kad izađe pa ga zamijeniti ako ne valja. Ovo je bila rupa u čipovima koji već rade, u milijardama uređaja, od pametnog telefona u tvom džepu do servera koji drži tuđu bankovnu aplikaciju. Ne možeš to jednostavno »objaviti na blogu« i otići na kavu. Pa je krenula ona faza koju industrija zove embargo — svi koji znaju o propustu drže jezik za zubima dok se ne pripremi rješenje, kako zlikovci ne bi saznali za rupu prije nego što je zakrpana — a ja bih to nazvao: svi šute, svi znaju, svima je muka.
Plan je bio uredan: otkriće se drži pod embargom otprilike do siječnja 2018., dovoljno vremena da se pripreme softverske zakrpe za operativne sustave, preglednike, cloud platforme, sve što sjedi na tim procesorima, pa se sve objavi koordinirano, jednog dana, s već spremnim rješenjima. Zvuči kao dobar plan. Zvučao je dobro na papiru barem šest mjeseci.
Onda je, kao što uvijek biva kad previše ljudi zna tajnu, netko negdje pisnuo. Krajem 2017. počeli su kolati čudni commit-ovi u Linux kernelu — commit je, pojednostavljeno, svaka pojedinačna promjena koda koja se bilježi u povijest projekta, poput zapisa u dnevniku »ovo sam danas promijenio i zašto« — samo što ovi zapisi nisu imali ono »zašto«. Izgledali su kao velika arhitekturna intervencija bez ikakvog objašnjenja. Programeri koji pratе razvoj kernela (a ima ih, i previše su pametni za svoje dobro) počeli su sastavljati komadiće slagalice. Forumi, spekulacije, novinari koji njuškaju. Datum objave planiran za 9. siječnja 2018. postao je neodrživ negdje oko Nove godine — vijest je počela curiti prije nego što su svi bili spremni, i cijela ta uredna koordinacija pretvorila se u žurnu improvizaciju.
Meltdown i Spectre objavljeni su na kraju ranije nego što je plan predviđao — 3. siječnja 2018., s dijelom zakrpa još u razvoju, s izvještajima koji su se sudarali, s tvrtkama koje su izdavale priopćenja u panici da ih ne pretekne konkurencija ili novinska naslovnica. Kaos, da, ali kontroliran kaos — jer zakrpe su bar već bile u pripremi, samo ne sve i ne posvuda. Da je otkriće ostalo skriveno bez tog curenja tko zna koliko dugo, priča bi bila drukčija; da nitko nije radio ništa mjesece prije, priča bi bila katastrofa.

Cijena zakrpe: brzina
Dobro, zakrpali su. Intel, Microsoft, Linux, Apple — svi su u panici izbacili ono što se zove »mikrokod update« (mikrokod je taj interni softver koji upravlja radom samog procesora, nešto između hardvera i softvera — kao uputstvo za uporabu ugrađeno u samu mašinu) i patch operativnog sustava, i tehnički gledano, curenje je stalo. Rupa je zatvorena. Slavimo? Ne baš. Jer se onda pokazalo da ta rupa nije bila neka nuspojava koja se može izvaditi kao trula plomba — bila je ugrađena u sam način na koji procesor radi svoj posao. A njegov posao, podsjetimo se, bio je da bude brz. Da pogađa unaprijed, da radi stvari prije nego što ih tražiš. Zakrpa je, u suštini, rekla procesoru: prestani pogađati tako slobodno. Provjeravaj više. Budi paranoičan.
A paranoičan procesor je, iznenađenje, sporiji procesor.
Brojke su varirale ovisno o tome koga pitaš i što mjeriš — negdje se gubitak jedva osjetio; kod običnog korištenja preglednika i Worda pad je bio kozmetički, par posto koje nitko normalan ne primijeti. Ali kod nekih opterećenja, posebno onih koja stalno dodiruju disk ili traže puno »sistemskih poziva« (to je kad program treba nešto od samog operacijskog sustava — pročitati datoteku, poslati podatke preko mreže — pa svaki put mora prekinuti svoj posao i pitati kernel za dozvolu), pad je bio dramatičan. Deset posto. Petnaest. Neki benchmarkovi na određenim bazama podataka pokazivali su i tridesetak posto sporiji rad. Zamisli da ti netko kaže da ti server od sutra radi trideset posto manje posla za isti novac. E, to se dogodilo. Preko noći. Bez da si ti nešto pokvario.
I tu dolazimo do dijela koji je najgore pogodio nekoga tko vjerojatno nikad nije čuo za Meltdown: cloud providere. Sjeti se poglavlja o tome kako je cloud zapravo tuđe računalo koje iznajmljuješ po satu (K5, pogl. 11) — pa, ako je tvoje računalo tuđe, tvoja sigurnosna rupa je i njihov problem, ali i obrnuto. Da bi to uopće bilo moguće, cloud provideri ne daju ti cijeli fizički server za sebe — umjesto toga, na jednom te istom čipu istovremeno žive desetci ili stotine »virtualnih strojeva«, softverskih simulacija računala, svaki od njih uvjeren da ima svoj vlastiti procesor za sebe, dok u stvarnosti svi dijele isti fizički komad silicija kao stanari u istoj zgradi. AWS, Google, Microsoft Azure su morali zakrpati stotine tisuća takvih fizičkih servera, jer je upravo to bio najgori mogući scenarij za Meltdown i Spectre — da netko u susjednom virtualnom stroju, za čije postojanje ti nemaš pojma, čita podatke iz tvog jer sjedite na istom čipu kao dvoje neznanaca koji nesvjesno prisluškuju jedno drugo kroz zid. Zakrpali su to, a onda su ti isti provideri tiho, bez fanfara, podigli cijene ili smanjili obećane performanse na nekim instancama. Ti to nikad nisi vidio u naslovima. Vidio si samo da ti račun na cloudu ovaj mjesec nekako izgleda drukčije.
A najgora vijest je čekala na kraju priče, onu koju nitko nije htio izgovoriti u prvim tjednima panike: ovo se ne može stvarno popraviti. Softverska zakrpa je flaster, ne operacija. Rekla je procesoru da bude oprezniji, ali dizajn koji dopušta curenje — sama arhitektura spekulativnog izvršavanja — ostaje ugrađen u milijarde tranzistora koje si već kupio. Da bi se problem stvarno riješio, treba redizajnirati sam čip, na razini silicija, a to nije ažuriranje koje se pošalje preko noći. To su godine razvoja, testiranja, nove generacije procesora. Intel je počeo ugrađivati hardverske zaštite protiv Meltdowna u čipove tek koju generaciju kasnije. Spectre, ta ružnija, tvrdoglavija varijanta, i dalje se ublažava, krpa po krpa, godinama nakon 2018. Neke varijante se vjerojatno nikad neće u potpunosti riješiti — samo će postati toliko nepraktične za iskorištavanje da ih svi prestanu spominjati.
Dvadeset godina brzine, plaćeno unatrag, u ratama, na tvom računu za struju i na tvom cloud računu. Skupa lekcija o tome što znači kad temelj koji si smatrao besplatnim — ubrzanje koje dolazi samo od sebe — pokaže da nikad nije bilo besplatno. Samo je čekalo da mu netko naplati.

Što to govori o temeljima
Sjećaš se buffer overflowa? Onog istog s kojim smo krenuli u ovoj enciklopediji, još u poglavlju 11 — pretpostavke da je memorija dobra i posluh momčad, pa netko upiše više nego što je predviđeno i najednom piše preko tuđeg dvorišta. Morris ga je 1988. pretvorio u crva koji je srušio pola tadašnjeg interneta. Heartbleed ga je 2014. reinkarnirao u knjižici koja je čuvala pola svjetske šifrirane komunikacije, u redu koda koji nitko nije provjerio dvije godine. I sad, 2018., ista priča — samo dva kata niže. Ne u programu. Ne u knjižnici. U tranzistorima. Von Neumannov dug, onaj isti spoj programa i podataka u istoj memoriji koji je pola stoljeća ranije učinio računala univerzalnima, sad je stigao do naplate na mjestu gdje ga nitko nije očekivao platiti — u siliciju samom.
I tu je stvar koja boli malo dulje od same zakrpe: pretpostavka da je hardver siguran — da je procesor ta čvrsta, nijema stijena ispod svega što softver radi — jednostavno je mrtva. Cijela sigurnosna arhitektura zadnjih dvadesetak godina, sve te lijepe kule od pjeska koje zovemo izolacija procesa, sandboxing, korisničke privilegije — sve je to stajalo na pretpostavci da čip radi točno ono što mu kažeš i ništa više. Meltdown i Spectre su pokazali da čip radi i ono što nisi tražio, samo da bi bio brži, i da to pamti dulje nego što bi trebao. A kad ti temelj zgrade odjednom priznaje da je cijelo vrijeme malo curio, ne provjeravaš samo temelj — provjeravaš sve što je na njemu sagrađeno.
Poanta ove kronike, ako je moraš stisnuti u jednu rečenicu za kavu: dvadeset godina smo gradili sigurnost cijele digitalne civilizacije na pretpostavci da procesor ne laže. A on je lagao, cijelo vrijeme, iz najboljih mogućih razloga — da ti stranica učita pola sekunde brže, da ti igra ne zapinje, da tablica ne čeka. Nije to bila zlonamjernost. Bila je to brzina, ambicija inženjera iz devedesetih koji su htjeli da im čip bude najbrži na tržištu, i koji su tu odluku ugradili duboko, duboko ispod razine na kojoj bi je ikad tko preispitao.
I tu dolazimo do te tihe, neugodne jeze koja ostaje kad zatvoriš ovaj članak. Heartbleed nas je učio da temelj možeš zapustiti i u redu koda koji svi koriste, a nitko ga ne provjerava, godinama. Meltdown i Spectre nas uče istu lekciju jedan sloj dublje — da temelj možeš zapustiti i u dizajnu koji je fizički utisnut u milijarde komada silicija, i da ga onda ne možeš samo pokrpati, moraš čekati sljedeću generaciju da ga popraviš. Isti obrazac, od koda do bakra: nešto staro, korisno, nedirano — i puno povjerenja koje nikad nije bilo zasluženo provjerom. Pitanje koje ostaje visjeti, ono koje ne voliš postavljati sebi prije spavanja, glasi: koliko još takvih temelja trenutno stoji ispod tebe, tihih, brzih i nikad zapravo provjerenih?