Google ha riscritto in linguaggio Rust il firmware pvmfm, utilizzato in Android

Nel quadro di un'iniziativa mirata a potenziare la sicurezza dei componenti software critici della piattaforma Android, Google ha riscritto il firmware pvmfm in Rust, utilizzato per gestire le macchine virtuali avviate dal hypervisor pVM all'interno dell'Android Virtualization Framework. In precedenza, il firmware era stato scritto in C e implementato sopra il bootloader U-Boot, nel cui codice erano state trovate vulnerabilità legate a problemi di gestione della memoria.

Il firmware riscritto in Rust è incluso in Android 14, mentre le librerie universali create durante lo sviluppo del firmware sono state confezionate come pacchetti crate e consegnate alla comunità Rust. Ad esempio, è stato pubblicato il pacchetto smccc per supportare le interfacce ARM PSCI (Power State Coordination Interface) e le chiamate SMCCC (SMC Calling Convention), e il pacchetto aarch64-paging per la manipolazione delle tabelle di pagina della memoria. È stato anche effettuato un lavoro per risolvere errori e ampliare le funzionalità del pacchetto esistente virtio-drivers con implementazione di driver VirtIO. Oltre alla piattaforma Android, i pacchetti menzionati sono stati utilizzati nel progetto Oak, che sviluppa componenti per la trasmissione, la memorizzazione e l'elaborazione dei dati in ambienti sicuri (TEE, Trusted Execution Environment).

L'hypervisor pVM acquisisce il controllo nelle fasi iniziali di avvio e garantisce un isolamento completo della memoria macchine virtuali e dell'ambiente host, impedendo all'host di accedere alle macchine virtuali protette in cui vengono elaborati dati sensibili. Il firmware pvmfm (Protected Virtual Machine Firmware) ottiene il controllo immediatamente dopo l'avvio della macchina virtuale, esegue una verifica dell'ambiente formattato e prende una decisione di interruzione di emergenza del caricamento nel caso venga rilevato un problema di integrità, oppure genera un certificato di avvio per il sistema ospite in caso di conferma della catena di fiducia.

La riscrittura in Rust consente di raggiungere un rispetto più semplice e sicuro della «regola del due», applicata da Google per mantenere la sicurezza dei componenti di sistema di Android. Secondo questa regola, ogni codice aggiunto deve soddisfare non più di due delle seguenti tre condizioni: lavoro con dati non verificati, utilizzo di un linguaggio di programmazione non sicuro (C/C++) e esecuzione con privilegi elevati. Da questa regola ne deriva che il codice per l'elaborazione di dati esterni deve essere o ridotto a privilegi minimi (isolate) o scritto in un linguaggio di programmazione sicuro. Secondo le statistiche di Google, circa il 70% di tutte le vulnerabilità pericolose riscontrate in Android sono causate da errori nella gestione della memoria.

Rust è focalizzato su un uso sicuro della memoria e consente di ridurre il rischio di vulnerabilità causate da problemi come l'accesso a una zona di memoria dopo che è stata liberata e il superamento del buffer. L'uso sicuro della memoria in Rust è garantito durante la compilazione attraverso il controllo dei riferimenti, il tracciamento della proprietà degli oggetti e la gestione del tempo di vita degli oggetti (scoping), oltre alla valutazione della correttezza dell'accesso alla memoria durante l'esecuzione del codice. Rust fornisce anche strumenti per proteggere da overflows aritmetici, richiede l'inizializzazione obbligatoria dei valori delle variabili prima del loro utilizzo, gestisce meglio gli errori nella libreria standard, adotta il concetto di immutabilità (immutable) per riferimenti e variabili per impostazione predefinita e offre una forte tipizzazione statica per minimizzare errori logici.

Tra le difficoltà che sorgono durante lo sviluppo in Rust di componenti a basso livello, come i driver, si menziona la necessità di lavorare con puntatori nudi in modalità unsafe, poiché Rust è stato progettato tenendo conto dell'uso della memoria allocata nel programma, e nel codice che opera senza strati sopra l'hardware, è necessario accedere alla memoria condivisa e al MMIO. Al momento, le capacità di Rust per lavorare con puntatori nudi lasciano a desiderare, ma la situazione dovrebbe migliorare dopo la stabilizzazione del supporto per le macro offset_of, slice_ptr_get e slice_ptr_len.

Tra gli svantaggi si segnala anche la necessità di una sintassi migliorata per accedere ai campi delle strutture e agli indici degli array tramite puntatori nudi, senza la creazione di riferimenti, oltre a limitazioni nella creazione di wrapper sicuri per operazioni unsafe, che possono causare comportamenti indefiniti e non possono essere verificate dal compilatore. Ad esempio, tali wrapper non possono essere creati per le operazioni con le tabelle delle pagine di memoria, poiché il mapping delle pagine in una parte del programma può influenzare altre parti.

Per quanto riguarda le dimensioni del codice risultante, la vecchia versione del firmware pVM occupava 220 kB, mentre la nuova occupa 460 kB, ma nella versione riscritta sono state aggiunte nuove funzionalità, grazie alle quali è stato possibile eliminare alcuni altri componenti utilizzati durante il caricamento. Di conseguenza, la dimensione complessiva di tutti i componenti di caricamento vecchi e nuovi è risultata comparabile. Si osserva che quando la dimensione è più importante delle prestazioni, risultati comparabili a quelli del linguaggio C possono essere ottenuti attivando nel compilatore modalità di ottimizzazione aggiuntive per le dimensioni, eliminando dipendenze superflue e non utilizzando strumenti di formattazione delle stringhe.

Si menziona inoltre il proseguimento del lavoro per l'implementazione della possibilità di avviare applicazioni Trusted Application scritte in Rust nel sistema operativo Trusty, che fornisce un ambiente TEE (Trusted Execution Environment) per Android, eseguito parallelamente ad Android sullo stesso processore in un ambiente isolato separato. Trusty viene utilizzato nei dispositivi Pixel e già utilizza Rust nelle librerie e nei componenti di sistema (il kernel rimane in C).

Fonte: opennet.ru

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster