Il codice base del kernel Linux, che costituisce la base per la release 6.18, include un'implementazione Rust del meccanismo di comunicazione interprocesso Binder. Binder è utilizzato in Android per la comunicazione interprocesso e l'invocazione di metodi remoti (un processo Android può chiamare un metodo o una funzione in un altro processo Android, utilizzando Binder per identificare, invocare e passare argomenti tra processi). Il codice di Binder è stato riscritto in Rust nell'ambito di un progetto volto a rafforzare la sicurezza, promuovere pratiche di programmazione sicure e migliorare l'efficienza del rilevamento dei problemi di memoria in Android (circa il 70% di tutte le vulnerabilità pericolose identificate in Android sono causate da errori di memoria).
L'utilizzo di Rust ha permesso agli sviluppatori di Binder di risolvere diversi problemi, tra cui errori relativi al conteggio dei riferimenti, al blocco e al controllo dei limiti, e di ridurre significativamente la complessità della gestione degli errori. L'implementazione Rust di Binder è funzionalmente identica all'implementazione C originale, supera tutti i test AOSP (Android Open-Source Project) e può essere utilizzata per creare build funzionanti del firmware Android. Nonostante le sue funzionalità avanzate e il supporto per oggetti con semantica di proprietà complessa, il driver Rust è più piccolo della versione C: 5.5 righe di codice contro 5.8.
Nella descrizione del commit, l'autore menziona i seguenti motivi per cui Binder è stato riscritto:
- Binder è in fase di sviluppo da 15 anni e, nel corso di questo periodo, le sue funzionalità e complessità sono cresciute in modo significativo. Il progetto si colloca all'intersezione di tutti i componenti Android e copre un'ampia gamma di attività che vanno oltre l'IPC:
- analisi e trasformazione corrette del contenuto delle transazioni che possono contenere più oggetti di diverso tipo (ad esempio puntatori, descrittori di file) che interagiscono tra loro;
- controllare la dimensione dei pool di thread dello spazio utente e garantire che le transazioni siano assegnate ai thread in modo da evitare deadlock quando il pool esaurisce i thread;
- Tracciamento dei contatori di riferimento degli oggetti condivisi tra i processi, propagazione corretta delle modifiche dei contatori di riferimento tra i processi;
- Gestire molteplici scenari di errore e combinare 13 diversi blocchi, 7 contatori di riferimento e variabili atomiche. Deve eseguire queste attività nel modo più rapido e corretto possibile.
- Il codice legacy aveva accumulato un notevole debito tecnico, complicando sia l'individuazione dei bug che lo sviluppo successivo. Ad esempio, il core conteneva funzioni di grandi dimensioni, che superavano le mille righe di codice, metodi di gestione degli errori discutibili e strutture complesse.
- Binder è un componente Android critico per la sicurezza, poiché gli elementi della piattaforma in esecuzione in ambienti sandbox isolati, come il processo di rendering di Chrome e il codec software, vi hanno accesso diretto, e una vulnerabilità in Binder consentirebbe di bypassare la sandbox. La sua elevata complessità, unita al suo debito tecnico, rende estremamente difficile mantenere un elevato livello di sicurezza in Binder.
Fonte: opennet.ru
