Rosetta 2 på Mac-datorer med Apple Silicon
Mac-datorer med Apple Silicon kan köra kod som har kompilerats för instruktionsuppsättningen x86_64 genom att använda en översättningsmekanism som kallas Rosetta 2. Två typer av översättning erbjuds: just-in-time och ahead-of-time.
Just-in-time-översättning
I översättningsfunktionen just-in-time (JIT) identifieras ett x86_64 Mach-objekt tidigt i avbildskörningssökvägen. När dessa avbilder hittas överför kärnan styrningen till en speciell Rosetta-översättningsstubb istället för till redigeraren för dynamiska länkar, dyld(1)
. Översättningsstubben översätter sedan x86_64-sidor medan avbilden körs. Den här översättningen sker helt och hållet inom processen. Kärnan verifierar fortfarande kodhasherna för varje x86_64-sida mot de kodsignaturer som är bifogade till den binärfil som sidan hör till. Om ett hashvärde inte stämmer tvingar kärnan fram den rensningspolicy som är lämplig för den aktuella processen.
Ahead-of-time-översättning
I översättningssökvägen ahead-of-time (AOT) läses x86_64-binärfiler från lagring vid de tidpunkter som systemet bedömer är optimala för kodens svarshastighet. De översatta artefakterna skrivs till lagring som en speciell typ av Mach-objektfil. Den filen liknar en körbar avbild, men är markerad för att indikera att det är den översatta produkten av en annan avbild.
I den här modellen härleder AOT-artefakten all sin identitetsinformation från den ursprungliga körbara x86_64-avbilden. För att tvinga igenom denna bindning signerar en priviligierad användarutrymmesentitet översättningsartefakten med en enhetsspecifik nyckel som hanteras av Secure Enclave. Denna nyckel släpps endast till den priviligierade användarutrymmesentiteten som identifieras som sådan genom en begränsad behörighet. Den kodkatalog som skapats för översättningsartefakten innehåller kodkataloghashen för den ursprungliga körbara x86_64-avbilden. Själva signaturen på översättningsartefakten kallas för supplementsignatur.
I likhet med AOT-funktionen startar JIT-funktionen med att kärnan överför styrningen till Rosetta-körningen istället för redigeraren för dynamiska länkar, dyld(1)
. Men Rosetta-körningen skickar sedan en IPC-förfrågan till Rosetta-systemtjänsten som frågar om det finns någon AOT-översättning tillgänglig för den aktuella körbara avbilden. Om en sådan hittas tillhandahåller Rosetta-tjänsten ett handtag till den översättningen och den mappas in i processen och körs. Under körning driver kärnan igenom översättningsartefaktens kodkataloghasher som autentiserats av den signatur som lagras i den enhetsspecifika signeringsnyckeln. Den ursprungliga x86_64-avbildens kodkataloghasher är inte inblandade i den här processen.
Översatta artefakter lagras i ett datavalv som inte är tillgängligt vid körning av någon entitet med undantag för Rosetta-tjänsten. Rosetta-tjänsten hanterar åtkomsten till dess cache genom att distribuera skrivskyddade filbeskrivningar till enskilda översättningsartefakter. Detta begränsar åtkomsten till AOT-artefaktens cache. Tjänstens IPC och beroende fotavtryck hålls avsiktligt väldigt smalt för att begränsa angreppsytan.
Om kodkataloghashen för den ursprungliga x86_64-avbilden inte matchar med den som är inkodad i AOT-översättningsartefaktens signatur hanteras resultatet som en ogiltig kodsignatur och lämpliga tillämpningsåtgärder genomförs.
Om en fjärrprocess frågar kärnan efter behörigheter eller andra kodidentitetsegenskaper för en AOT-översatt körbar avbild returneras den ursprungliga x86_64-avbildens identitetsegenskaper till processen.
Innehåll i statiska tillförlitlighetscacher
macOS 11 och senare levereras med Mach-”fat”-binärfiler som innehåller delar av x86_64- och arm64-datorkod. På Mac-datorer med Apple Silicon kan användaren välja att köra x86_64-delen av en binär systemfil genom Rosetta-funktionen, t.ex. för att läsa in en insticksfil som saknar inbyggd arm64-variant. För att stöda detta innehåller den statiska tillförlitlighetscachen som levereras med macOS normalt tre kodkataloghasher per Mach-objektfil.
En kodkataloghash för arm64-delen
En kodkataloghash för x86_64-delen
En kodkataloghash för AOT-översättningen av x86_64-delen
Rosettas AOT-översättningsprocess är deterministisk på så vis att den reproducerar identiska utmatningar för varje given inmatning, oberoende av när översättningen utfördes eller på vilken enhet den utfördes.
Under macOS-bygget körs varje Mach-objektfil genom Rosettas AOT-översättningskörning som är kopplad till den version av macOS som byggs, och den kodkataloghash som skapas spelas in till tillförlitlighetscachen. Av effektivitetsskäl levereras de faktiska översatta produkterna inte med operativsystemet och omkonstitueras vid behov när användaren begär dem.
När en x86_64-avbild körs på Mac-datorer med Apple Silicon, och avbildens kodkataloghash finns i den statiska tillförlitlighetscachen, förväntas också kodkataloghashen för den AOT-artefakt som skapas finnas i den statiska tillförlitlighetscachen. Sådana produkter signeras inte av den enhetsspecifika nyckeln eftersom signeringsutfärdaren lagras i den säkra Apple-startkedjan.
Osignerad x86_64-kod
Mac-datorer med Apple Silicon tillåter inte att inbyggd arm64-kod körs om giltig bifogad signatur saknas. Den här signaturen kan vara så enkel som en ”ad hoc”-kodsignatur (jämför codesign(1)
) som inte har någon faktisk identitet från den hemliga halvan av ett asymmetriskt nyckelpar (det är helt enkelt en icke-autentiserad mätning av binärfilen).
Av kompatibilitetsskäl kopplade till binärfiler har översatt x86_64-kod tillstånd att köras genom Rosetta utan någon signaturinformation alls. Ingen specifik identitet överförs till den koden genom den enhetsspecifika Secure Enclave-signeringsprocessen, och den utför körningar med exakt samma begränsningar som inbyggd osignerad kod utför körningar på Intel-baserade Mac-datorer.