UndefinedBehaviorSanitizer (UBSan) esegue la strumentazione in fase di compilazione per verificare la presenza di vari tipi di comportamenti indefiniti. Sebbene UBSan sia in grado di rilevamento in corso... molti bug di comportamento non definiti, Android supporta:
- allineamento
- bool
- limiti
- enum
- overflow-cast-float
- divisione-mobile-per-zero
- divisione-intero-per-zero
- attributo non nullo
- null
- invio
- restituisce-attributo-nonnull
- turno-base
- esponente di spostamento
- overflow-integer-integro
- non raggiungibile
- overflow-integer-non firmato
- vla-bound
unSign-integer-overflow, anche se tecnicamente non definito comportamento, sia inclusa nel disinfettante e usata in molti moduli Android, inclusi i componenti mediaserver, per eliminare l'eventuale overflow di valori interi latenti le vulnerabilità.
Implementazione
Nel sistema di build Android, puoi attivare UBSan a livello globale o locale. Per attivare UBSan a livello globale, imposta SANITIZE_TARGET in Android.mk. Per attivare UBSan a un a livello di modulo, imposta LOCAL_SANITIZE e specifica i comportamenti non definiti che vuoi cercare in Android.mk. Ad esempio:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0 LOCAL_SRC_FILES:= sanitizer-status.c LOCAL_MODULE:= sanitizer-status LOCAL_SANITIZE := alignment bounds null unreachable integer LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer include $(BUILD_EXECUTABLE)
E la configurazione del progetto base equivalente (Android.bp):
cc_binary { cflags: [ "-std=c11", "-Wall", "-Werror", "-O0", ], srcs: ["sanitizer-status.c"], name: "sanitizer-status", sanitize: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], diag: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], }, }, }
Scorciatoie UBSan
Android ha anche due scorciatoie: integer
e
default-ub
, per attivare contemporaneamente un insieme di disinfettanti. numero intero
abilita integer-divide-by-zero
,
signed-integer-overflow
e unsigned-integer-overflow
.
default-ub
abilita i controlli con un compilatore minimo
problemi di prestazioni: bool, integer-divide-by-zero, return,
returns-nonnull-attribute, shift-exponent, unreachable and vla-bound
. La
classe sanitizer con numeri interi con SANITIZE_TARGET e LOCAL_SANITIZE,
mentre il valore default-ub può essere usato solo con SANITIZE_TARGET.
Segnalazione degli errori migliorata
L'implementazione UBSan predefinita di Android richiama una funzione specificata quando si è riscontrato un comportamento non definito. Per impostazione predefinita, questa funzione è interrotta. Tuttavia, a partire da ottobre 2016, UBSan su Android ha una libreria di runtime facoltativa fornisce report sugli errori più dettagliati, tra cui il tipo di comportamento non definito informazioni trovate, sul file e sulla riga del codice sorgente. Per attivare questo errore i report con controlli di numeri interi aggiungono quanto segue a un file Android.mk:
LOCAL_SANITIZE:=integer LOCAL_SANITIZE_DIAG:=integer
Il valore LOCAL_SANITIZE abilita il sanitizer durante la creazione. LOCAL_SANITIZE_DIAG attiva la modalità diagnostica per il sanitizer specificato. È è possibile impostare LOCAL_SANITIZE e LOCAL_SANITIZE_DIAG su valori diversi, ma sono abilitati solo i controlli in LOCAL_SANITIZE. Se un controllo non è specificato in LOCAL_SANITIZE, ma è specificato in LOCAL_SANITIZE_DIAG, il controllo non è abilitato e messaggi di diagnostica.
Ecco un esempio delle informazioni fornite dalla libreria di runtime UBSan:
pixel-xl:/ # sanitizer-status ubsan sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Sanificazione dell'overflow del numero intero
Gli overflow di numeri interi involontari possono causare il danneggiamento della memoria o delle informazioni vulnerabilità di divulgazione nelle variabili associate agli accessi alla memoria alla distribuzione della memoria. Per contrastare questa tendenza, abbiamo aggiunto UndefinedBehaviorSanitizer (UBSan) sanitizer di overflow di numeri interi firmati e non firmati a intensificare il framework multimediale in Android 7.0. In Android 9, espanso UBSan per coprire più componenti e migliorare il supporto del sistema di compilazione.
È progettato per aggiungere controlli aritmetici operazioni / istruzioni, che potrebbero overflow: per interrompere in sicurezza un processo se si verifica un overflow. Questi sanitizzatori possono mitigare un'intera classe di danneggiamento della memoria e vulnerabilità di divulgazione di informazioni in cui la causa principale è un numero intero come la vulnerabilità originale di Stagefright.
Esempi e fonte
La sanificazione dell'overflow intero (IntSan) è fornita dal compilatore e aggiunge
la strumentazione nel programma binario durante il tempo di compilazione per rilevare le operazioni aritmetiche
overflow. È attivata per impostazione predefinita in vari componenti durante
una piattaforma Google, ad esempio
/platform/external/libnl/Android.bp
Implementazione
IntSan utilizza sanitizer di overflow di interi senza firma e con segno di UBSan. Questo la mitigazione è abilitata a livello di modulo. Aiuta a mantenere i componenti critici di Android sicuro e non deve essere disattivato.
Ti consigliamo vivamente di abilitare la sanificazione dell'overflow intero per componenti. I candidati ideali sono un codice nativo privilegiato che analizza l'input utente non attendibile. Esiste un piccolo overhead di rendimento associato con il disinfettante che dipende dall'uso del codice e dalla prevalenza di operazioni aritmetiche. Aspettati una piccola percentuale di overhead 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_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
accetta un elenco separato da virgole di disinfettanti doveinteger_overflow
è un insieme predefinito di opzioni per i singoli sanitizzatori di overflow di numeri interi firmati e non firmati con un predefinita ELENCO BLOCCOLOCAL_SANITIZE_DIAG
attiva la modalità diagnostica per disinfettanti. Utilizza la modalità diagnostica solo durante i test perché interrompere gli overflow, annullando completamente il vantaggio in termini di sicurezza mitigazione dei rischi. Consulta la sezione Risoluzione dei problemi. per ulteriori dettagli.LOCAL_SANITIZE_BLOCKLIST
ti consente di specificare una LISTA BLOCCA per impedire la sanificazione di funzioni e file di origine. Consulta Risoluzione dei problemi per ulteriori i dettagli.
Se vuoi un controllo più granulare, abilita i disinfettanti individualmente utilizzando uno o entrambi:
LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow
Supportare IntSan nei file di progetto
Per abilitare la sanificazione dell'overflow di numeri interi in un file progetto, ad esempio
/platform/external/libnl/Android.bp
,
aggiungi:
sanitize: { integer_overflow: true, diag: { integer_overflow: true, }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Come nel caso dei file "make", la proprietà integer_overflow
è una proprietà
insieme di opzioni per l'overflow dei singoli numeri interi con e senza segno
disinfettanti con un'impostazione predefinita
ELENCO BLOCCA
L'insieme di proprietà diag
attiva la modalità diagnostica per
disinfettanti. Utilizza la modalità diagnostica solo durante i test. La modalità Diagnostica non
interrompere gli overflow, il che nega completamente il vantaggio in termini di sicurezza
nella mitigazione delle build degli utenti. Per ulteriori dettagli, consulta la sezione Risoluzione dei problemi.
La proprietà BLOCKLIST
consente di specificare un file BLOCKLIST
che consente agli sviluppatori di impedire che le funzioni
e i file di origine vengano
sterilizzato. Consulta la sezione Risoluzione dei problemi per
e ulteriori dettagli.
Per attivare singolarmente i disinfettanti, utilizza:
sanitize: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"], diag: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow",], }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Risoluzione dei problemi
Se attivi la sanificazione dell'overflow di valori interi nei nuovi componenti o fai affidamento delle librerie della piattaforma con sanitizzazione dell'overflow di numeri interi, alcuni problemi con overflow di numeri interi benigni che causano interruzioni. Dovresti verificare componenti con sanitizzazione abilitata per garantire overflow benigni.
Per trovare le interruzioni causate dalla sanificazione nelle build degli utenti, cerca
SIGABRT
ha un arresto anomalo 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'
L'analisi dello stack dovrebbe includere la funzione che ha causato l'interruzione, tuttavia gli overflow che si verificano nelle funzioni in linea potrebbero non essere evidenti nell'analisi dello stack.
Per determinare più facilmente la causa principale, abilita la diagnostica nella libreria che attivano l'interruzione e prova a riprodurre l'errore. Con di diagnostica abilitata, la procedura non verrà interrotta continuano a essere eseguiti. La mancata interruzione aiuta a massimizzare il numero di overflow benigni in una un particolare percorso di esecuzione senza doverlo ricompilare dopo aver corretto ogni bug. La diagnostica genera un messaggio di errore che include il numero di riga e l'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, assicurati che l'overflow è benigno e intenzionale (ad es. non ha implicazioni per la sicurezza). Puoi risolvere il problema interruzione del disinfettante da:
- Refactoring del codice per evitare l'overflow (esempio)
- Esegui l'overflow in modo esplicito tramite __builtin_*_overflow (esempio)
- Disabilita la sanitizzazione nella funzione specificando l'attributo
no_sanitize
(esempio) - Disabilitazione della sanificazione di una funzione o di un file di origine tramite un file BLOCKLIST (esempio)
Dovresti usare la soluzione più granulare possibile. Ad esempio, un grande funzione con molte operazioni aritmetiche e una singola operazione di overflow eseguire il refactoring della singola operazione anziché dell'intera funzione IN ELENCO BLOCCO.
Gli schemi comuni che possono causare overflow benigni includono:
- Implicito Cast in cui si verifica un overflow non firmato prima di essere trasmesso a un tipo firmato (esempio)
- Eliminazioni di elenchi collegati che riducono l'indice di loop al momento dell'eliminazione (esempio)
- Assegnare un tipo senza segno a -1 anziché specificare il valore massimo effettivo (esempio)
- Loop che riducono un numero intero senza segno nella condizione (esempio, esempio)
Consigliamo agli sviluppatori di garantire che nei casi in cui il disinfettante rilevi un overflow che è davvero benigno senza effetti collaterali involontari o le implicazioni prima di disabilitare la sanificazione.
Disabilita IntSan
Puoi disattivare IntSan con BLOCKLIST o attributi di funzione. Disabilita con parsimonia e solo nel caso in cui il refactoring del codice sia altrimenti irragionevole o se c'è un overhead di rendimento problematico.
Consulta la documentazione di Clang upstream per ulteriori informazioni sulla disattivazione di IntSan con funzione attributi e file BLOCKLIST formattazione. Le BLOCKLIST devono avere come ambito il particolare disinfettante usando nomi di sezioni che specifichino il sanitizer di destinazione per evitare di colpire disinfettanti.
Convalida
Al momento, non esistono test CTS specifici per la sanificazione degli overflow interi. Assicurati invece che i test CTS vengano superati con o senza IntSan abilitato per la verifica che questo non influisca sul dispositivo.
Sanificazione limiti
BoundsSanitizer (BoundSan) aggiunge la strumentazione ai file binari per inserire i limiti controlla gli accessi agli array. Questi controlli vengono aggiunti se il compilatore non può dimostrare al momento della compilazione che l'accesso sarà sicuro e che le dimensioni dell'array sarà nota in fase di runtime, in modo da poterla confrontare. Android 10 esegue il deployment di BoundSan Bluetooth e codec. BoundSan viene fornito dal compilatore ed è abilitato sono predefiniti in vari componenti della piattaforma.
Implementazione
BoundSan utilizza la tecnologia UBSan disinfettante. Questa mitigazione è abilitata a livello di modulo. Sono utili per mantenere al sicuro i componenti critici di Android e non deve essere disattivato.
Ti consigliamo vivamente di attivare BoundSan per componenti aggiuntivi. I candidati ideali sono un codice nativo con privilegi o un codice nativo complesso che analizza input utente non attendibile. L'overhead delle prestazioni associato all'attivazione di BoundSan dipende dal numero di accessi agli array che non possono essere dimostrati sicuri. È previsto un una piccola percentuale media di overhead e verifica se le prestazioni sono un problema.
Abilita BoundSan nei file di progetto
BoundSan può essere abilitato nei file di progetto aggiungendo "bounds"
alla proprietà misc_undefined
sanitize per file binari e librerie
moduli:
sanitize: { misc_undefined: ["bounds"], diag: { misc_undefined: ["bounds"], }, BLOCKLIST: "modulename_BLOCKLIST.txt",
diagramma
La proprietà diag
attiva la modalità diagnostica per i disinfettanti.
Utilizza la modalità diagnostica solo durante i test. La modalità di diagnostica non si interrompe su
overflow, il che nega il vantaggio per la sicurezza della mitigazione e comporta
in termini di overhead delle prestazioni maggiore, perciò è sconsigliato per le build di produzione.
ELENCO BLOCCO
La proprietà BLOCKLIST
consente la specifica di una LISTA BLOCCA
che gli sviluppatori possono utilizzare per impedire che le funzioni e i file di origine
sterilizzato. Utilizza questa proprietà solo se il rendimento è un problema e se il target
i file/le funzioni contribuiscono in modo sostanziale. Controlla manualmente questi file/funzioni
per garantire la sicurezza degli accessi agli array. Consulta la sezione Risoluzione dei problemi per ulteriori informazioni.
i dettagli.
Attiva BoundSan nei makefile
BoundSan può essere abilitato nei makefile aggiungendo "bounds"
alla variabile LOCAL_SANITIZE
per i moduli binari e delle librerie:
LOCAL_SANITIZE := bounds # Optional features LOCAL_SANITIZE_DIAG := bounds LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
accetta un elenco di disinfettanti separati da una
virgola.
LOCAL_SANITIZE_DIAG
attiva la modalità diagnostica. Utilizza la diagnostica
solo durante il test. La modalità di diagnostica non si interrompe in caso di overflow,
nega il vantaggio per la sicurezza della mitigazione e comporta un
in termini di overhead delle prestazioni, perciò è sconsigliato per le build di produzione.
LOCAL_SANITIZE_BLOCKLIST
consente di specificare una LISTA BLOCCA
che consente agli sviluppatori di impedire che le funzioni e i file di origine
sterilizzato. Utilizza questa proprietà solo se il rendimento è un problema e se il target
i file/le funzioni contribuiscono in modo sostanziale. Controlla manualmente questi file/funzioni
per garantire la sicurezza degli accessi agli array. Consulta la sezione Risoluzione dei problemi per ulteriori informazioni.
i dettagli.
Disattiva BoundSan
Puoi disabilitare BoundSan nelle funzioni e nei file sorgente con BLOCKLIST o di funzione. È meglio mantenere BoundSan abilitato, quindi disattivalo solo se la funzione o il file sta creando una grande quantità di sovraccarico delle prestazioni sia stata esaminata manualmente.
Per ulteriori informazioni sulla disattivazione di BoundSan con la funzione attributi e file BLOCKLIST formattazione, consulta la documentazione su LLVM Clang. Definisci l'ambito BLOCKLIST al specifico disinfettante utilizzando nomi di sezioni che specifichino disinfettante per non incorrere in problemi su altri disinfettanti.
Convalida
Non esistono test CTS specifici per BoundSan. Assicurati invece che CTS test superati con o senza BoundSan abilitato per verificare che non del dispositivo.
Risoluzione dei problemi
Testa attentamente i componenti dopo aver attivato BoundSan per assicurarti che eventuali e non rilevati gli accessi fuori intervallo.
Gli errori di BoundSan possono essere facilmente identificati poiché includono quanto segue: messaggio di interruzione tombstone:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/foobar <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: out-of-bounds'
Con l'esecuzione in modalità diagnostica, il file di origine, il numero di riga e l'indice
vengono stampati in logcat
. Per impostazione predefinita, questa modalità
invia un messaggio di interruzione. Controlla logcat
per verificare la presenza di eventuali
errori.
external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'