Dettagli tecnici sull'integrità del flusso di controllo
"La disponibilità di un numero enorme di puntatori a funzioni nel kernel contribuisce alla popolarità di questo modello di attacco. Anche se gli aggressori non possono iniettare il proprio codice eseguibile, è possibile eseguire parti arbitrarie del codice kernel esistente per completare il loro exploit.
LLVMIl CFI di tenta di mitigare questi attacchi limitando i target di chiamata validi e provocando il panico del kernel quando rileva una violazione del CFI. Viene aggiunto un controllo prima di ogni ramo indiretto per confermare che l'indirizzo di destinazione punta a una funzione valida con una firma corretta. Ciò impedisce a un ramo indiretto di saltare a una posizione di codice arbitraria e limita anche le funzioni che possono essere chiamate. Un utente malintenzionato sarà comunque in grado di modificare un puntatore a funzione, se un bug ne consente l'accesso. Ma il CFI di LLVM limita il 55% delle chiamate indirette a un massimo di 5 target possibili e l'80% a un massimo di 20 target. Per determinare tutti gli obiettivi di chiamata validi per ogni ramo indiretto, il compilatore deve vedere tutto il codice del kernel contemporaneamente.
L'utilizzo di LTO (Ottimizzazione del tempo di collegamento) lo rende possibile. Il CFI di LLVM richiede l'utilizzo di LTO, in cui il compilatore produce codice bit specifico di LLVM per tutti i C unità di compilazione e un linker compatibile con LTO utilizza il backend LLVM per combinare il codice bit e compilarlo in Codice nativo.
Oltre a consentire l'utilizzo di CFI, LTO raggiunge migliori prestazioni di runtime attraverso l'analisi dell'intero programma e l'ottimizzazione tra moduli.
ThinLTO ha quasi raggiunto il miglioramento delle prestazioni di LTO. In modalità ThinLTO, come nel normale LTO, Clang emette il codice bit LLVM dopo la fase di compilazione. Il bitcode ThinLTO è arricchito con un riepilogo compatto del modulo. Durante la fase di collegamento, solo i riepiloghi vengono letti e uniti in un indice di riepilogo combinato, che include un indice delle posizioni delle funzioni per la successiva importazione di funzioni tra moduli. Successivamente viene eseguita un'analisi rapida ed efficiente dell'intero programma sull'indice riepilogativo combinato. ThinLTO consente un processo di collegamento multi-thread, che si traduce in tempi di compilazione ridotti.
A causa dell'interruzione dell'esecuzione del programma da parte di CFI quando si verificano determinate classi di bug, si classifica anche come strumento di ricerca bug, come menzionato in precedenza, se utilizzato in modalità permissiva. CFI permissivo mostrerà le violazioni CFI nel registro del kernel, senza causare il panico del kernel. I kernel core 4.9 (dispositivi Pixel di terza generazione) e 4.14 (dispositivi Pixel di quarta generazione) avevano diversi tipi di funzioni mancate corrispondenze che hanno portato a violazioni CFI, che sono state risolte da Google nei patchset disponibili sul kernel/common repository.
Tuttavia, a causa della natura dell'ecosistema Android, è probabile che queste discrepanze si trovino nel codice specifico del produttore del SoC (in questo caso, Qualcomm) o dell'OEM (OnePlus). Diverse violazioni CFI nel codice Qualcomm distinte dal kernel 4.19 sono state corrette sul kernel Kirisakura per OnePlus 8 Pro (esempio: 1, 2, 3).
L'esecuzione del kernel in CFI permissivo ha rivelato violazioni CFI anche nel codice relativo ai driver OnePlus (è possibile trovare i commit pertinenti Qui E Qui). Il kernel Kirisakura per OnePlus 8 Pro funziona con l'applicazione CFI, proteggendo gli utenti da questo tipo di attacchi di riutilizzo del codice."
Per saperne di più
Appassionato di fai da te (ovvero recuperatore di vecchi pezzi di PC). Appassionato utente di Android sin dai tempi di Eclair, Skanda ama anche seguire le recenti tendenze di sviluppo nel mondo del single-board computing.