Sanificazione dell'overflow di numeri interi

Gli overflow di interi non intenzionali possono causare il danneggiamento della memoria o vulnerabilità di divulgazione di informazioni nelle variabili associate agli accessi alla memoria o alle allocazioni di memoria. Per contrastare questo problema, abbiamo aggiunto i disinfettanti per overflow di interi firmati e non firmati UndefinedBehaviorSanitizer (UBSan) di Clang per rafforzare il framework multimediale in Android 7.0. In Android 9, abbiamo ampliato UBSan per coprire più componenti e migliorato il supporto del sistema di build per esso.

Questo è progettato per aggiungere controlli su operazioni / istruzioni aritmetiche, che potrebbero traboccare, per interrompere in modo sicuro un processo se si verifica un overflow. Questi disinfettanti possono mitigare un'intera classe di danneggiamento della memoria e vulnerabilità di divulgazione delle informazioni in cui la causa principale è un overflow di numeri interi, come la vulnerabilità Stagefright originale.

Esempi e fonte

Integer Overflow Sanitization (IntSan) viene fornito dal compilatore e aggiunge la strumentazione al file binario durante la fase di compilazione per rilevare gli overflow aritmetici. È abilitato per impostazione predefinita in vari componenti della piattaforma, ad esempio /platform/external/libnl/Android.bp .

Implementazione

IntSan utilizza disinfettanti per overflow di interi firmati e non firmati di UBSan. Questa mitigazione è abilitata a livello di modulo. Aiuta a mantenere i componenti critici di Android al sicuro e non dovrebbe essere disabilitato.

Ti consigliamo vivamente di abilitare la sanificazione dell'overflow di numeri interi per componenti aggiuntivi. I candidati ideali sono codice nativo privilegiato o codice nativo che analizza l'input utente non attendibile. C'è un piccolo sovraccarico di prestazioni associato al disinfettante che dipende dall'utilizzo del codice e dalla prevalenza delle operazioni aritmetiche. Aspettati una piccola percentuale di sovraccarico e verifica se le prestazioni sono un problema.

Supporto di IntSan nei makefile

Per abilitare IntSan in un makefile, aggiungi:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE accetta un elenco di disinfettanti separati da virgole, con integer_overflow che è un set preconfezionato di opzioni per i disinfettanti di overflow di interi firmati e non firmati individuali con una lista nera predefinita .
  • LOCAL_SANITIZE_DIAG attiva la modalità diagnostica per i disinfettanti. Utilizzare la modalità diagnostica solo durante il test perché non si interromperà in caso di overflow, annullando completamente il vantaggio in termini di sicurezza della mitigazione. Vedere Risoluzione dei problemi per ulteriori dettagli.
  • LOCAL_SANITIZE_BLACKLIST consente di specificare un file di blacklist per impedire la sanificazione di funzioni e file di origine. Vedere Risoluzione dei problemi per ulteriori dettagli.

Se vuoi un controllo più granulare, abilita i sanificanti singolarmente utilizzando uno o entrambi i flag:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

Supporto di IntSan nei file di progetto

Per abilitare la sanificazione dell'overflow di interi in un file di blueprint, come /platform/external/libnl/Android.bp , aggiungi:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

Come per i file make, la proprietà integer_overflow è un insieme preconfezionato di opzioni per i singoli disinfettanti di overflow di interi firmati e non firmati con una blacklist predefinita .

Il set di proprietà diag abilita la modalità diagnostica per i disinfettanti. Utilizzare la modalità diagnostica solo durante il test. La modalità di diagnostica non si interrompe in caso di overflow, il che annulla completamente il vantaggio in termini di sicurezza della mitigazione nelle build degli utenti. Vedere Risoluzione dei problemi per ulteriori dettagli.

La proprietà blacklist consente di specificare un file di blacklist che consente agli sviluppatori di impedire la sanificazione di funzioni e file di origine. Vedere Risoluzione dei problemi per ulteriori dettagli.

Per abilitare i disinfettanti singolarmente, utilizzare:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Risoluzione dei problemi

Se si abilita la sanificazione dell'overflow di interi in nuovi componenti o si fa affidamento su librerie di piattaforma che hanno avuto la sanificazione dell'overflow di interi, è possibile che si verifichino alcuni problemi con overflow benigni di interi che causano interruzioni. È necessario testare i componenti con la sanificazione abilitata per garantire che possano emergere traboccamenti benigni.

Per trovare interruzioni causate dalla sanificazione nelle build degli utenti, cerca SIGABRT arresti anomali con messaggi di interruzione che indicano un overflow rilevato da UBSan, ad esempio:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

La traccia dello stack dovrebbe includere la funzione che causa l'interruzione, tuttavia, gli overflow che si verificano nelle funzioni inline potrebbero non essere evidenti nella traccia dello stack.

Per determinare più facilmente la causa principale, abilitare la diagnostica nella libreria che attiva l'interruzione e provare a riprodurre l'errore. Con la diagnostica abilitata, il processo non verrà interrotto e continuerà invece a essere eseguito. La mancata interruzione aiuta a massimizzare il numero di overflow benigni in un particolare percorso di esecuzione senza dover ricompilare dopo aver corretto ogni bug. La diagnostica genera un messaggio di errore che include il numero di riga e il file di origine che causa l'interruzione:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

Una volta individuata l'operazione aritmetica problematica, assicurarsi che l'overflow sia benigno e previsto (ad es. non abbia implicazioni sulla sicurezza). Puoi risolvere l'interruzione del disinfettante:

  • Refactoring del codice per evitare l'overflow ( esempio )
  • Overflow esplicitamente tramite le funzioni __builtin_*_overflow di Clang ( esempio )
  • Disabilitazione della sanificazione nella funzione specificando l'attributo no_sanitize ( esempio )
  • Disabilitazione della sanificazione di una funzione o di un file sorgente tramite un file di blacklist ( esempio )

Dovresti usare la soluzione più granulare possibile. Ad esempio, una funzione di grandi dimensioni con molte operazioni aritmetiche e una singola operazione in overflow dovrebbe avere il refactoring della singola operazione anziché l'intera funzione nella lista nera.

I modelli comuni che possono causare overflow benigni includono:

  • Cast impliciti in cui si verifica un overflow senza segno prima di essere convertito in un tipo firmato ( esempio )
  • Eliminazioni di elenchi collegati che decrementano l'indice del ciclo all'eliminazione ( esempio )
  • Assegnazione di un tipo senza segno a -1 invece di specificare il valore massimo effettivo ( esempio )
  • Cicli che decrementano un intero senza segno nella condizione ( esempio , esempio )

Si consiglia agli sviluppatori di assicurare che i casi in cui il disinfettante rilevi un overflow che sia effettivamente benigno senza effetti collaterali o implicazioni di sicurezza non intenzionali prima di disabilitare la sanificazione.

Disabilitazione di IntSan

Puoi disabilitare IntSan con blacklist o attributi di funzione. Disattivare con moderazione e solo quando il refactoring del codice è altrimenti irragionevole o se si verificano problemi di sovraccarico delle prestazioni.

Vedere la documentazione a monte di Clang per ulteriori informazioni sulla disabilitazione di IntSan con gli attributi delle funzioni e la formattazione dei file della blacklist . La lista nera dovrebbe essere limitata al disinfettante specifico utilizzando i nomi delle sezioni che specificano il disinfettante di destinazione per evitare l'impatto su altri disinfettanti.

Convalida

Al momento, non sono disponibili test CTS specifici per la sanificazione dell'overflow di numeri interi. Assicurati invece che i test CTS superino con o senza IntSan abilitato per verificare che non influisca sul dispositivo.