Wat als alle processors ter wereld een fundamentele fout bevatten, die op steeds meer manieren wordt uitgebuit, en waarvoor geen goede patch bestaat? We onderzoeken Spectre, de kwelduivel van Intel en AMD, en bekijken waarom het lek een half jaar na de ontdekking nog steeds aan de orde is.
Dit artikel verscheen oorspronkelijk op 20 juli 2018. Omdat Spectre ook vandaag nog actueel is, hebben we het herwerkt met recente voorbeelden.
Intel en AMD lijken wel gestalkt door de geest van Spectre. De kwetsbaarheid verandert processors in een fantastische vector voor hackers om systemen mee te kraken. Hoewel het lek al aan het begin van 2018 werd ontdekt, blijven de repercussies tot op vandaag voelbaar. Pas ontdekte Intel nog dat AMD-chips kwetsbaar blijven voor Spectre ondanks een mitigatie die al jaren in voegen is. Intel ontdekte die fout zelf ook maar omdat het nog steeds op zoek is naar een goede oplossing voor de eigen chips. Niemand lijkt de achterpoort finaal te kunnen sluiten. In 2021 ontdekten onderzoekers eveneens nieuwe Spectre-gerelateerde problemen bij Intel en AMD.
In dit stuk graven we dieper. Om te begrijpen waarom Spectre processorfabrikanten blijft achtervolgen en een eenvoudige update het probleem niet verhelpt, moet je weten wat de kwetsbaarheid zo uniek maakt. Om dat te doen, moeten we in de werking van de architectuur van een moderne processor duiken.
Niemand lijkt de achterpoort finaal te kunnen sluiten.
Speculatieve uitvoering: de achilleshiel
Zowat alle moderne processors, of ze nu van Intel of AMD komen, op x86 gebouwd zijn dan wel ARM, maken gebruik van enkele gelijkaardige principes. Eén daarvan heet speculatieve uitvoering.
Speculatieve uitvoering is een slim antwoord op een probleem dat oude cpu’s teisterde. In de vroege dagen van processorarchitectuur had een cpu één rekenkern met een bepaalde kloksnelheid. Die voerde instructies uit in de volgorde waarin ze werden aangeboden. Aan instructie 2 werd pas begonnen als instructie 1 klaar was.
Dat is niet zo efficiënt. Als instructie 2 bijvoorbeeld waardes uit het geheugen nodig heeft, zal de cpu die waardes pas inladen wanneer instructie 1 is afgewerkt. Dat laden duurt lang, waardoor er waardevolle klokcycli verloren gaan, waarop de rekenkern niets doet. Processorarchitecten omzeilden dat probleem door cpu’s van een slim systeem te voorzien dat de chips toelaat om te gokken wat de volgende instructie zal zijn, en welke geheugenwaarden daarmee gepaard gaan.
Gokken en (prestaties) winnen
Een voorbeeld: vlak na instructie 1 wordt instructie 2 als speculatief ingeladen. Bijhorende geheugendata wordt naar de cache van de processor geschreven. De cache is een kleine pool van ultrasnel geheugen op de processor zelf. Wanneer een cpu instructies uitvoert, doet hij beroep op de cache en niet op het RAM-geheugen, omdat dat te traag is.
Is instructie 1 afgerond, dan zit instructie 2 de eerste instructie al op de hielen, met alle nodige data op de juiste plaats in de cache. Als de processor juist gespeculeerd heeft, moet hij helemaal geen waardevolle klokcycli wachten totdat de nodige data uit de RAM naar de cache is gehaald, en kan het rekenwerk gewoon doorgaan. Is de speculatie toch fout, dan wordt al het werk dat al gedaan is voor de uitvoering van instructie 2 ongedaan gemaakt, en wordt de volgende instructie ingeladen als vanouds.
Speculatieve voorspelling is steengoed geworden doorheen de jaren, met een succesratio van om en bij de 95 procent. Moderne cpu’s hebben een groot deel van hun snelheid te danken aan speculatieve uitvoering.
Spectre maakt op een slimme manier misbruik van speculatieve executie.
Het hele systeem is geïmplementeerd op micro-architecturaal niveau. De firmware van de cpu, die de werking van de logische schakelingen gebouwd door de miljarden interconnects en transistors beheert, regelt ook de speculatieve uitvoering. Programma’s houden er geen rekening mee: zij gaan er gewoon vanuit dat hun instructies op volgorde worden uitgevoerd. Het speculatieve luik gebeurt achter de schermen, en versnelt die uitvoering. Spectre maakt op een slimme manier misbruik van speculatieve executie.
De problemen deden zich in eerste instantie voor in Intelprocessors van voor 2018, maar variaties op het misbruik van de speculatieve uitvoering blijven tot vandaag bestaan. Hieronder doen we de werking van de originele Spectre-variant uit de doeken.
Speculatief misbruik
Het probleem ligt bij een ander stuk van de technologie. In het geheugen van pc’s en servers is er een belangrijk onderscheid tussen de user space en de kernel space. De user space bevat data die niet overdreven gevoelig is, terwijl in de normaliter erg goed beschermde kernel space de meest kritieke gegevens worden behandeld.
Een normale instructie zonder toegang tot de kernel space zal nooit door de processor raken met toegang tot de data daar. Vraagt een normale user space-instructie toegang tot data in de kernel space, dan zet de processor de instructie stop.
Niet zo als het om een speculatieve instructie gaat. De check gebeurt nog steeds, maar pas helemaal op het einde, wanneer blijkt dat de instructie daadwerkelijk moet worden uitgevoerd. De redenering hierachter kan je begrijpen: als de processor fout speculeert, worden alle wijzigingen teruggedraaid, en als de speculatieve instructie terecht wordt uitgevoerd, doorgaat ze een finale privilegecheck voordat de uitvoering wordt afgerond.
Lekke pipeline
Het probleem zit in de pipeline. Stel je eenvoudig voor dat een fictieve processor een pipeline van vier stappen heeft. In de eerste stap wordt data van het RAM-geheugen naar de processorcache geschreven, in de volgende stappen gebeuren er bewerkingen, en in de allerlaatste stap kijkt de cpu in het geval van de speculatieve instructie of ze wel moest worden uitgevoerd, en of ze de nodige privileges heeft.
Zelfs wanneer het antwoord op één van die vragen nee is, heeft een malafide speculatieve instructie wel wijzigingen kunnen aanbrengen in de processorcache. In die cache zijn data minder goed beschermd dan in de kernel space.
Het eerste Spectre-lek maakt van die tekortkoming in CPU’s gebruik om gevoelige data uit te lezen. Een speculatieve malware-instructie haalt data zoals een wachtwoord uit de kernel space naar de cache, waarna ze terecht wordt stopgezet, maar de cache intussen wel is aangepast. Aan de hand van die aanpassing kan malware vervolgens aan je wachtwoord raken.
Eén trucje, veel variaties
De nieuw ontdekte variaties op Spectre gaan nog een stapje verder. Zij vragen niet om beveiligde data te lezen, maar proberen malafide code weg te schrijven op geheugenlocaties waar ze geen toegang tot hebben. Een buffer overflow ligt hier aan de basis, en opnieuw is een laattijdig geïmplementeerde privilegecheck op speculatieve executies verantwoordelijk.
Waar de eerste variant op Spectre gevoelige data probeert te lezen door stiekem gegevens uit de kernel space naar de cache te schrijven, proberen Spectre 1.1 en Spectre 1.2 data te schrijven naar een geheugenadres dat niet bestaat. Laten we zeggen dat een speculatieve instructie toegang heeft tot een bereik van vijf verschillende opeenvolgende adressen in het geheugen. Tijdens de speculatieve uitvoering vraagt de instructie om een blokje malwarecode weg te schrijven naar adres zes. Normaliter stopt de processor de code, omdat adres zes in de context van de instructie niet bestaat. In speculatieve modus gebeurt die check niet, en wordt de code in de praktijk weggeschreven naar een geheugenadres dat tot een andere set instructies behoort.
Opnieuw zal de instructie door de cpu worden gestopt zodra ze van speculatief naar reëel verandert, maar opnieuw is het cachegeheugen in deze fase reeds aangetast. Een goede aanval zorgt er zo voor dat een proces met de juiste rechten data vanuit de cache inlaadt die voordien is overschreven, waardoor het goedaardige proces plots kwaadaardige dingen begint doen.
En de oplossing?
‘Maar Intel, check de privileges van een instructie dan voor de speculatieve uitvoering, in plaats van daarna’, roep je nu naar je scherm. Dat lijkt de oplossing, maar daar schuilt net het probleem. De micro-architectuur is er op gebouwd om de check achteraf uit te voeren. Alle transistors en de interconnects die ze tot logische schakelingen maken, zijn in de designfase door de ingenieurs zo ontworpen om pas achteraf te checken. Het is mogelijk om de firmware aan te passen en het veiligheidsprobleem (deels) op te lossen, maar dat brengt een enorme impact op de prestaties met zich mee.
In het geval van de eerste variant van Spectre, versie 1.0, rolde Intel firmwarepatches uit waarbij de processor wisselde tussen een user mode en een kernel mode. Voor de uitvoering gebeurt na de patch een check op iedere instructie, waarna de processor naar de juiste modus schakelt. Dat verhelpt het probleem, maar vertraagt de cpu in de praktijk tot tien procent. De werkelijke vertraging hangt af van het type processor en het type workload. Vooral Haswell-chips en ouder krijgen het zwaar te verduren. In traditionele consumentenprogramma’s gebeurt het rekenwerk vooral in de user space, en is de impact klein. In serverland moet er veel meer tussen user space en kernel space gewisseld worden, waardoor de patch de prestaties flink naar omlaag haalt.
Het is mogelijk om het veiligheidsprobleem (deels) op te lossen, maar dat brengt een enorme impact op de prestaties met zich mee.
Ook AMD-chips en cpu’s op ARM-architectuur kwetsbaar. Toch ondervinden zij minder problemen. Op Intel na bouwde iedereen wel ruimte in om speculatieve instructies vooraf op de rooster te leggen. Een firmwarepatch heeft daardoor een veel kleinere tot onvoelbare impact op de prestaties. Ook AMD moet de kwetsbaarheid echter wegwerken en vier jaar na datum is dat nog steeds niet helemaal gelukt.
Duistere toekomst
De kat is uit de zak. Spectre is intussen uitgegroeid tot een verzamelnaam voor lekken die speculatieve uitvoering misbruiken. Nu duidelijk is dat cpu’s kwetsbaar zijn via die vector, zoeken hackers en beveiligingsonderzoekers naarstig naar nieuwe manieren om speculatieve instructies te misbruiken. Daar zijn Spectre 1.1 en 1.2 voorbeelden van. Er is geen reden om te denken dat er geen versies 1.3 en 1.4 zullen komen, die andere manieren vinden om ongeoorloofde zaken speculatief realiteit te maken.
Intussen zijn we enkele jaren verder en heeft Intel Spectre onder de motorkap aangepakt. De grootste problemen zijn daarmee verholpen, maar speculatieve uitvoering blijft een gevaarlijk beestje. Van tijd tot tijd duiken er nieuwe variaties van Spectre op die ook op moderne chips werken. Volledig Spectre-vrije-processors ontwerpen, blijkt voor zowel Intel als AMD een grote uitdaging.
lees ook
Intel ontdekt Spectre-kwetsbaarheid in zowat alle AMD-processors
Tot het zover is, blijft Spectre een enorm venijnig lek, dat deels in de firmware kan worden verholpen, maar deels ook door alle softwarebouwers gemitigeerd moet worden. Helaas telkens met een prijs op het vlak van prestaties. Lees: de kwetsbaarheid blijft zeker en vast nog erg lang bestaan. hoor je binnen enkele maanden over een nieuwe gevaarlijke variant, dan weet je nu tenminste waarom die Spectre je blijft achtervolgen.
Eén lichtpuntje: in professionele omgevingen kunnen geavanceerde beveiligingsoplossingen soelaas bieden. Dat doen ze niet door het lek te patchen, maar door code na te kijken op kenmerken van een Spectre-aanval, bijvoorbeeld in een sandboxomgeving. De processor blijft wel kwetsbaar, maar malware wordt zo gestopt voor de aanval kan beginnen.