Questa pagina descrive problemi importanti e correzioni di bug rilevati su android-mainline
che potrebbero essere significativi per i partner.
15 novembre 2024
Clang è aggiornato alla versione 19.0.1 per
android-mainline
eandroid16-6.12
- Riepilogo: la nuova versione di Clang introduce un'analisi di sicurezza dei limiti per gli array,
dove le dimensioni dell'array vengono memorizzate in una variabile separata collegata all'array
utilizzando l'attributo
__counted_by
. Questa funzionalità potrebbe causare un panico del kernel se la dimensione dell'array non viene aggiornata correttamente. Il messaggio di errore ha il seguente aspetto:
UBSAN: array-index-out-of-bounds in common/net/wireless/nl80211.c index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]')
Dettagli: lo strumento di contenimento degli accessi non autorizzati è essenziale per proteggere l'integrità del kernel rilevando gli accessi non autorizzati. Se
CONFIG_UBSAN_TRAP
è attivato, lo strumento di contenimento degli errori attiva un panico del kernel per qualsiasi esito.- La versione precedente dello strumento di convalida dei limiti controllava solo gli array di dimensioni fisse
e non poteva controllare gli array allocati dinamicamente. La nuova versione utilizza l'attributo
__counted_by
per determinare i limiti dell'array in fase di esecuzione e rilevare più casi di accesso fuori limite. Tuttavia, in alcuni casi, viene eseguito l'accesso all'array prima dell'impostazione della variabile size, attivando l'analizzatore di sicurezza dei limiti e causando un panico del kernel. Per risolvere il problema, imposta le dimensioni dell'array immediatamente dopo l'allocazione della memoria sottostante, come illustrato in aosp/3343204.
- La versione precedente dello strumento di convalida dei limiti controllava solo gli array di dimensioni fisse
e non poteva controllare gli array allocati dinamicamente. La nuova versione utilizza l'attributo
Informazioni su
CONFIG_UBSAN_SIGNED_WRAP
: la nuova versione di Clang esegue la sanitizzazione degli overflow e degli underflow di interi firmati nonostante il flag del compilatore-fwrapv
. Il-fwrapv
flag è progettato per trattare gli interi con segno come interi senza segno con complemento a due con comportamento di overflow definito.- Sebbene la sanitizzazione dell'overflow di interi con segno nel kernel di Linux possa aiutare a identificare i bug, esistono casi in cui l'overflow è intenzionale, ad esempio con
atomic_long_t
. Di conseguenza,CONFIG_UBSAN_SIGNED_WRAP
è stato disattivato per consentire a UBSAN di funzionare esclusivamente come sanificatore dei limiti.
- Sebbene la sanitizzazione dell'overflow di interi con segno nel kernel di Linux possa aiutare a identificare i bug, esistono casi in cui l'overflow è intenzionale, ad esempio con
Informazioni su
CONFIG_UBSAN_TRAP
: UBSAN è configurato per attivare un kernel panic quando rileva un problema per proteggere l'integrità del kernel. Tuttavia, abbiamo disattivato questo comportamento dal 23 ottobre al 12 novembre. Lo abbiamo fatto per sbloccare l'aggiornamento del compilatore e risolvere i problemi__counted_by
noti.
- Riepilogo: la nuova versione di Clang introduce un'analisi di sicurezza dei limiti per gli array,
dove le dimensioni dell'array vengono memorizzate in una variabile separata collegata all'array
utilizzando l'attributo
1° novembre 2024
- Lanciato Linux 6.12-rc4
- Riepilogo:
CONFIG_OF_DYNAMIC
potrebbe causare gravi regressioni per i driver con errori. - I dettagli: durante l'unione di Linux
6.12-rc1
inandroid-mainline
abbiamo riscontrato problemi di mancato caricamento dei driver out-of-tree. La modifica che ha esposto i bug del driver è stata identificata come commit274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")
e abbiamo annullato temporaneamente la modifica in aosp/3287735. La modifica selezionaCONFIG_OF_OVERLAY
, che selezionaCONFIG_OF_DYNAMIC
. Con!OF_DYNAMIC
, il conteggio dei riferimenti suof_node_get()
eof_node_put()
è effettivamente disattivato in quanto implementati comenoops
. La re-attivazione diOF_DYNAMIC
mostra di nuovo i problemi nei driver che implementano erroneamente il conteggio dei riferimenti perstruct device_node
. Ciò causa vari tipi di errori, come la corruzione della memoria, l'uso dopo il rilascio e le perdite di memoria. - Tutti gli utilizzi delle API correlate all'analisi OF devono essere controllati. Il seguente elenco è
parziale, ma contiene casi che abbiamo osservato:
- Use after free (UAF):
- Riutilizzo dello stesso argomento
device_node
: queste funzioni chiamanoof_node_put()
sul nodo specificato e potrebbero dover aggiungere unof_node_get()
prima di chiamarle (ad esempio, quando vengono chiamate più volte con lo stesso nodo come argomento):of_find_compatible_node()
of_find_node_by_name()
of_find_node_by_path()
of_find_node_by_type()
of_get_next_cpu_node()
of_get_next_parent()
of_get_next_child()
of_get_next_available_child()
of_get_next_reserved_child()
of_find_node_with_property()
of_find_matching_node_and_match()
- Utilizzo di
device_node
dopo qualsiasi tipo di uscita da determinati loop:for_each_available_child_of_node_scoped()
for_each_available_child_of_node()
for_each_child_of_node_scoped()
for_each_child_of_node()
- Mantieni i puntatori diretti alle proprietà
char *
dadevice_node
in giro, ad esempio utilizzando:const char *foo = struct device_node::name
of_property_read_string()
of_property_read_string_array()
of_property_read_string_index()
of_get_property()
- Riutilizzo dello stesso argomento
- Perdite di memoria:
- Ottenere un
device_node
e dimenticarsi di annullarne il riferimento (of_node_put()
). I nodi restituiti da questi devono essere liberati a un certo punto:of_find_compatible_node()
of_find_node_by_name()
of_find_node_by_path()
of_find_node_by_type()
of_find_node_by_phandle()
of_parse_phandle()
of_find_node_opts_by_path()
of_get_next_cpu_node()
of_get_compatible_child()
of_get_child_by_name()
of_get_parent()
of_get_next_parent()
of_get_next_child()
of_get_next_available_child()
of_get_next_reserved_child()
of_find_node_with_property()
of_find_matching_node_and_match()
- Ottenere un
- Mantenimento di un
device_node
da un'iterazione del ciclo. Se torni o interrompi da quanto segue, devi eliminare il riferimento rimanente a un certo punto:for_each_available_child_of_node()
for_each_child_of_node()
for_each_node_by_type()
for_each_compatible_node()
of_for_each_phandle()
- Use after free (UAF):
- La modifica menzionata in precedenza è stata ripristinata durante il caricamento di Linux
6.12-rc4
(vedi aosp/3315251) riattivandoCONFIG_OF_DYNAMIC
e potenzialmente esponendo driver con errori.
- Riepilogo: