Nella base di codice del kernel Linux, da cui viene sviluppata la release 6.18, è stata adottata l'implementazione del meccanismo di comunicazione interprocesso Binder, scritta in linguaggio Rust. Binder è utilizzato in Android per gestire l'interazione tra processi e la chiamata remota di metodi (un processo Android può invocare un metodo o una funzione in un altro processo Android, utilizzando Binder per identificare, chiamare e trasferire 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 sicura e migliorare l'efficacia nella rilevazione di problemi di gestione della memoria in Android (circa il 70% di tutte le vulnerabilità critiche identificate in Android è causato da errori nella gestione della memoria).
L'uso di Rust ha permesso di risolvere alcuni problemi incontrati dagli sviluppatori di Binder, inclusi errori legati al conteggio dei riferimenti, ai lock e al controllo dei limiti, nonché di ridurre notevolmente la complessità della gestione degli errori. L'implementazione di Binder in Rust è funzionalmente simile alla versione originale in C, supera tutti i test AOSP (Android Open-Source Project) e può essere utilizzata per creare versioni funzionanti del firmware Android. Nonostante le avanzate capacità e il supporto per oggetti con semantiche di possesso complesse, il driver in Rust risulta più piccolo della versione in C: 5.5 contro 5.8 mila righe di codice.
Nella descrizione del commit, l'autore menziona i seguenti motivi per la riscrittura di Binder:
- Binder si è evoluto per 15 anni e nel corso di questo tempo la sua funzionalità e complessità sono aumentate significativamente — il progetto si trova all'incrocio di tutti i componenti di Android e copre molteplici compiti che vanno oltre l'IPC:
- analisi e trasformazione corretta dei contenuti delle transazioni, che possono contenere più oggetti di diversi tipi (ad esempio puntatori, descrittori di file), che interagiscono tra loro;
- controllo della dimensione dei pool di thread nello spazio utente e garanzia di assegnazione delle transazioni ai thread in modo da evitare deadlock esaurendo i thread nel pool;
- monitoraggio dei contatori di riferimenti di oggetti condivisi da più processi, trasferendo correttamente le modifiche ai contatori di riferimenti tra processi;
- elaborazione di numerosi scenari di errore e combinazione di 13 diverse chiusure, 7 contatori di collegamenti e variabili atomiche. Deve eseguire tali compiti il più rapidamente e correttamente possibile.
- Nel codice legacy si è accumulato un notevole debito tecnico, che ha complicato sia la ricerca di errori che lo sviluppo successivo. Ad esempio, nel core si possono trovare funzioni grandi più di mille righe di codice, metodi di gestione degli errori discutibili e strutture intricate.
- Il Binder è un componente critico dal punto di vista della sicurezza di Android, poiché gli elementi della piattaforma che operano in ambienti sandbox isolati, come il processo di rendering in Chrome e SW Codec, hanno accesso diretto ad esso; una vulnerabilità nel Binder permetterebbe di eludere l'isolamento. L'alta complessità, unita al debito tecnico, rende molto difficile mantenere un alto livello di sicurezza nel Binder.
Fonte: opennet.ru
