Google si impegna a promuovere l'equità razziale per le comunità nere. Vedi come.
Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Sanificazione di overflow di numeri interi

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

Questo è progettato per aggiungere controlli intorno alle operazioni / istruzioni aritmetiche — che potrebbero traboccare — per interrompere in sicurezza un processo se si verifica un overflow. Questi disinfettanti possono mitigare un'intera classe di vulnerabilità della corruzione della memoria e della divulgazione di 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 il tempo di compilazione per rilevare overflow aritmetici. È abilitato per impostazione predefinita in vari componenti in tutta la piattaforma, ad esempio /platform/external/libnl/Android.bp .

Implementazione

IntSan utilizza i disinfettanti per overflow di numeri interi firmati e non firmati di UBSan. Questa mitigazione è abilitata a livello per modulo. Aiuta a proteggere i componenti critici di Android e non deve essere disabilitato.

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

Supporto di IntSan nei makefile

Per abilitare IntSan in un makefile, aggiungere:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE accetta un elenco di disinfettanti separato da virgole, con integer_overflow è un insieme preconfezionato di opzioni per i singoli disinfettanti di overflow di numeri interi con segno e senza segno 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 di sicurezza della mitigazione. Vedere Risoluzione dei problemi per ulteriori dettagli.
  • LOCAL_SANITIZE_BLACKLIST consente di specificare un file della blacklist per impedire la sanificazione di funzioni e file di origine. Vedere Risoluzione dei problemi per ulteriori dettagli.

Se si desidera un controllo più granulare, abilitare i disinfettanti 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 di overflow di numeri interi in un file di modello, come /platform/external/libnl/Android.bp , aggiungere:

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

Come per i file di creazione, la proprietà integer_overflow è una serie preconfezionata di opzioni per i singoli disinfettanti di overflow di numeri interi con segno e senza segno con una lista nera predefinita .

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

La proprietà della blacklist consente la specifica di un file della lista nera 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 sta abilitando la sanificazione di overflow di numeri interi in nuovi componenti o si fa affidamento su librerie di piattaforme che hanno avuto la sanificazione di overflow di numeri interi, è possibile che si verifichino alcuni problemi con overflow di numeri interi benigni che causano interruzioni. È necessario testare i componenti con la sanificazione abilitata per assicurarsi che possano essere superati gli overflow benigni.

Per trovare, gli abort causati dalla sanificazione nelle build degli utenti, cerca SIGABRT arresta in modo SIGABRT con i messaggi Abort che indicano un overflow rilevato da UBSan, come:

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 attivando l'interruzione e tentare di riprodurre l'errore. Con la diagnostica abilitata, il processo non verrà interrotto e continuerà invece a essere eseguito. La non interruzione aiuta a massimizzare il numero di overflow benigni in un particolare percorso di esecuzione senza dover ricompilare dopo aver corretto ciascun bug. La diagnostica produce 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. Senza implicazioni di sicurezza). È possibile indirizzare il disinfettante interrompere:

  • Rifattorizzare il codice per evitare l'overflow ( esempio )
  • Overflow esplicitamente tramite le funzioni di overflow __builtin _ * _ di Clang ( esempio )
  • Disabilitare la sanificazione nella funzione specificando l'attributo no_sanitize ( esempio )
  • Disabilitazione della sanificazione di una funzione o di un file sorgente tramite un file della lista nera ( esempio )

È necessario utilizzare la soluzione più granulare possibile. Ad esempio, una grande funzione con molte operazioni aritmetiche e una singola operazione di overflow dovrebbe essere refactored la singola operazione piuttosto che l'intera funzione nella lista nera.

I modelli comuni che possono provocare overflow benigni includono:

  • Cast impliciti in cui si verifica un overflow senza segno prima di essere trasmessi a un tipo con segno ( esempio )
  • Eliminazioni di elenchi collegati che riducono l'indice di loop all'eliminazione ( esempio )
  • Assegnare un tipo senza segno a -1 invece di specificare il valore massimo effettivo ( esempio )
  • Loop che diminuiscono un numero intero senza segno nella condizione ( esempio , esempio )

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

Disabilitazione di IntSan

È possibile disabilitare IntSan con liste nere o attributi di funzione. Disabilitare con parsimonia e solo quando il refactoring del codice è altrimenti irragionevole o se si verificano problemi di prestazioni.

Vedere la documentazione di Clang a monte per ulteriori informazioni sulla disabilitazione di IntSan con attributi di funzione e formattazione dei file della blacklist . La lista nera dovrebbe essere portata al particolare disinfettante usando i nomi delle sezioni specificando il disinfettante di destinazione per evitare di avere un impatto su altri disinfettanti.

Validazione

Attualmente, non esistono test CTS specifici per la sanificazione di overflow di interi. Assicurati invece che i test CTS vengano superati con o senza IntSan abilitato per verificare che non abbia alcun impatto sul dispositivo.