Som en del av arbetet med att öka sÀkerheten för kritiska programkomponenter pÄ Android-plattformen har Google skrivit om pvmfm-firmwaret pÄ Rust, som anvÀnds för att organisera arbetet med virtuella maskiner som startas av hypervisorn pVM inom ramen för Android Virtualization Framework. Tidigare var firmwaret skrivet i C och implementerat ovanpÄ U-Boot-bootloadern, dÀr man tidigare upptÀckte sÄrbarheter orsakade av minnesproblem.
Den omarbetade Rust-firmwaret Àr inkluderat i Android 14, och de universella bibliotek som skapades under utvecklingen av firmwaret Àr dokumenterade som crate-paket och överlÀmnade till Rust-gemenskapen. Till exempel publicerades paketet smccc för stöd av ARM-grÀnssnitt PSCI (Power State Coordination Interface) och anrop av SMCCC (SMC Calling Convention), samt paketet aarch64-paging för hantering av minnestabeller. Det har ocksÄ genomförts arbete för att ÄtgÀrda buggar och utöka funktionaliteten hos det befintliga paketet virtio-drivers genom implementering av VirtIO-drivrutiner. Utöver Android-plattformen anvÀnds dessa paket i Oak-projektet, som utvecklar komponenter för överföring, lagring och behandling av data i skyddade miljöer (TEE, Trusted Execution Environment).
Hypervisorn pVM fÄr kontroll tidigt under uppstarten och sÀkerstÀller fullstÀndig isolering av minnet virtuella maskiner och vÀrdmiljön, vilket förhindrar att vÀrdsystemet fÄr Ätkomst till de skyddade virtuella maskiner dÀr konfidentiella data behandlas. pvmfm-firmwaret (Protected Virtual Machine Firmware) fÄr kontroll direkt efter att den virtuella maskinen har startats, utför en kontroll av den skapade miljön och fattar beslut om att avbryta uppstarten vid upptÀckta problem med integriteten eller genererar ett startcertifikat för gÀstsystemet om kedjan av förtroende bekrÀftas.
Omprogrammering i Rust gör det möjligt att enklare och sÀkrare följa "regeln om tvÄ", som Google tillÀmpar för att sÀkerstÀlla sÀkerheten i systemkomponenter i Android. Enligt denna regel bör all ny kod uppfylla högst tvÄ av tre villkor: arbete med osÀker indata, anvÀndning av osÀkra programmeringssprÄk (C/C++) och körning med förhöjda privilegier. Av denna regel följer att kod för att hantera extern data antingen bör begrÀnsas till minimi-privilegier (isolerad) eller skrivas pÄ ett sÀkert programmeringssprÄk. Enligt statistiken frÄn Google beror cirka 70 % av alla farliga sÄrbarheter som upptÀckts i Android pÄ minneshanteringsfel.
Rust fokuserar pÄ sÀker minneshantering och minskar risken för sÄrbarheter orsakade av problem som Ätkomst till minnesomrÄden efter att de har frigjorts och buffertöverskridanden. SÀker minneshantering i Rust sÀkerstÀlls under kompilering genom referenskontroll, spÄrning av objektÀgande och objektens livscykel (synlighet), liksom genom korrekthetsbedömning av minnesÄtkomst under kodens körning. Rust tillhandahÄller ocksÄ verktyg för att skydda mot heltalsöverflöd, krÀver obligatorisk initialisering av variabelvÀrden innan de anvÀnds, hanterar fel bÀttre i standardbiblioteket, tillÀmpar konceptet av oförÀnderliga (immutable) referenser och variabler som standard och erbjuder stark statisk typning för att minimera logiska fel.
En av de utmaningar som uppstÄr vid utveckling av lÄgnivÄkomponenter i Rust, som drivrutiner, Àr behovet av att arbeta med rÄpekare i osÀkert lÀge, eftersom Rust Àr utformat med hÀnsyn till minnesanvÀndning i programmet, och i kod som arbetar utan nÄgra abstraktionslager över hÄrdvaran mÄste man hantera delat minne och MMIO. För nÀrvarande lÀmnar Rusts kapacitet för arbete med rÄpekare mycket att önska, men situationen bör förbÀttras efter stabilisering av stöd för makron offset_of, slice_ptr_get och slice_ptr_len.
Bland nackdelar finns behovet av förbÀttrad syntax för att komma Ät fÀlt i strukturer och index i arrayer via rÄa pekare utan att skapa referenser, samt begrÀnsningar vid skapandet av sÀkra bindningar över osÀkra operationer som kan orsaka oförutsÀgbart beteende och som inte kan verifieras av kompilatorn. Till exempel Àr det omöjligt att skapa sÄdana bindningar för operationer med minnessidor, eftersom mappning av sidor i en del av programmet kan pÄverka andra delar.
NÀr det gÀller storleken pÄ den resulterande koden, tog den gamla versionen av pVM-firmware 220 kB, medan den nya tog 460 kB, men i den omskrivna versionen tillades nya funktioner som gjorde att flera andra komponenter som anvÀndes vid uppstart kunde tas bort. Som ett resultat visade sig den totala storleken pÄ alla gamla och nya startkomponenter vara jÀmförbar. Det noteras att nÀr storleken Àr viktigare Àn prestanda kan jÀmförbara resultat med C-sprÄket uppnÄs genom att inkludera extra optimeringslÀgen för storlek i kompilatorn, ta bort överflödiga beroenden och undvika stringformattering.
Det nÀmns dessutom att arbetet fortsÀtter med att implementera möjligheten att köra pÄlitliga applikationer skrivna i Rust (Trusted Application) i operativsystemet Trusty, som tillhandahÄller en TEE-miljö (Trusted Execution Environment) för Android, som körs parallellt med Android pÄ samma processor i en separat isolerad miljö. Trusty anvÀnds i Pixel-enheter och anvÀnder redan Rust i bibliotek och systemkomponenter (kÀrnan förblir pÄ C).
KĂ€lla: opennet.ru
