Cette page décrit les problèmes importants et les corrections de bugs détectés sur android-mainline
qui peuvent être importants pour les partenaires.
15 novembre 2024
Clang est mis à jour vers la version 19.0.1 pour
android-mainline
etandroid16-6.12
- Résumé: La nouvelle version de Clang introduit un outil de nettoyage des limites pour les tableaux, où la taille du tableau est stockée dans une variable distincte liée au tableau à l'aide de l'attribut
__counted_by
. Cette fonctionnalité peut provoquer une panique du noyau si la taille du tableau n'est pas correctement mise à jour. Le message d'erreur se présente comme suit:
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 *[]')
Détails: Le nettoyeur de limites est essentiel pour protéger l'intégrité du noyau en détectant les accès hors limites. Lorsque
CONFIG_UBSAN_TRAP
est activé, le nettoyeur de limites déclenche une panique du noyau en cas de découverte.- La version précédente du nettoyeur de limites ne vérifiait que les tableaux de taille fixe et ne pouvait pas vérifier les tableaux alloués de manière dynamique. La nouvelle version utilise l'attribut
__counted_by
pour déterminer les limites du tableau au moment de l'exécution et détecter davantage de cas d'accès hors limite. Toutefois, dans certains cas, le tableau est accessible avant que la variable de taille ne soit définie, ce qui déclenche le nettoyeur de limites et provoque un plantage du kernel. Pour résoudre ce problème, définissez la taille du tableau immédiatement après avoir alloué la mémoire sous-jacente, comme illustré dans aosp/3343204.
- La version précédente du nettoyeur de limites ne vérifiait que les tableaux de taille fixe et ne pouvait pas vérifier les tableaux alloués de manière dynamique. La nouvelle version utilise l'attribut
À propos de
CONFIG_UBSAN_SIGNED_WRAP
: la nouvelle version de Clang assainit le débordement et le sous-dépassement des entiers signés malgré l'indicateur de compilation-fwrapv
. L'indicateur-fwrapv
est conçu pour traiter les entiers signés comme des entiers non signés en complément à deux avec un comportement de débordement défini.- Bien que la désinfection de l'excédent d'entiers signés dans le noyau Linux puisse aider à identifier les bugs, il existe des cas où l'excédent est intentionnel, par exemple avec
atomic_long_t
. Par conséquent,CONFIG_UBSAN_SIGNED_WRAP
a été désactivé pour permettre à UBSAN de fonctionner uniquement en tant que nettoyeur de limites.
- Bien que la désinfection de l'excédent d'entiers signés dans le noyau Linux puisse aider à identifier les bugs, il existe des cas où l'excédent est intentionnel, par exemple avec
À propos de
CONFIG_UBSAN_TRAP
: UBSAN est configuré pour déclencher une panique du noyau lorsqu'il détecte un problème afin de protéger l'intégrité du noyau. Toutefois, nous avons désactivé ce comportement du 23 octobre au 12 novembre. Nous avons fait cela pour débloquer la mise à jour du compilateur pendant que nous corrigions les problèmes__counted_by
connus.
- Résumé: La nouvelle version de Clang introduit un outil de nettoyage des limites pour les tableaux, où la taille du tableau est stockée dans une variable distincte liée au tableau à l'aide de l'attribut
1er novembre 2024
- Lancement de Linux 6.12-rc4
- Résumé:
CONFIG_OF_DYNAMIC
peut entraîner des régressions graves pour les pilotes défectueux. - Détails: lors de la fusion de
6.12-rc1
Linux dansandroid-mainline
, nous avons constaté des problèmes de chargement des pilotes hors du noyau. La modification qui a exposé les bugs du pilote a été identifiée comme étant le commit274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")
. Nous l'avons temporairement annulée dans aosp/3287735. La modification sélectionneCONFIG_OF_OVERLAY
, qui sélectionneCONFIG_OF_DYNAMIC
. Avec!OF_DYNAMIC
, le comptage des références surof_node_get()
etof_node_put()
est effectivement désactivé, car ils sont implémentés en tant quenoops
. L'activation deOF_DYNAMIC
expose à nouveau des problèmes dans les pilotes qui implémentent de manière incorrecte le comptage des références pourstruct device_node
. Cela entraîne divers types d'erreurs, telles que la corruption de la mémoire, l'utilisation après libération et les fuites de mémoire. - Toutes les utilisations des API liées à l'analyse OF doivent être inspectées. La liste suivante est partielle, mais contient les cas que nous avons observés :
- Utilisation après libération (UAF) :
- Réutilisation du même argument
device_node
: ces fonctions appellentof_node_put()
sur le nœud donné et doivent peut-être ajouter unof_node_get()
avant de les appeler (par exemple, lors d'appels répétés avec le même nœud comme argument) :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()
- Utilisation de
device_node
après tout type de sortie de certaines boucles :for_each_available_child_of_node_scoped()
for_each_available_child_of_node()
for_each_child_of_node_scoped()
for_each_child_of_node()
- Conserver des pointeurs directs vers les propriétés
char *
à partir dedevice_node
, par exemple, à l'aide des éléments suivants :const char *foo = struct device_node::name
of_property_read_string()
of_property_read_string_array()
of_property_read_string_index()
of_get_property()
- Réutilisation du même argument
- Fuites de mémoire :
- Obtenir un
device_node
et oublier de le désenregistrer (of_node_put()
). Les nœuds renvoyés par ces éléments doivent être libérés à un moment donné :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()
- Obtenir un
- Conserver un
device_node
à partir d'une itération de boucle. Si vous revenez ou interrompez l'exécution à partir des éléments suivants, vous devez supprimer la référence restante à un moment donné :for_each_available_child_of_node()
for_each_child_of_node()
for_each_node_by_type()
for_each_compatible_node()
of_for_each_phandle()
- Utilisation après libération (UAF) :
- Le changement mentionné précédemment a été restauré lors du déploiement de
6.12-rc4
Linux (voir aosp/3315251), ce qui a réactivéCONFIG_OF_DYNAMIC
et potentiellement exposé des pilotes défectueux.
- Résumé: