Cette page décrit les problèmes importants et les corrections de bugs trouvés dans android-mainline qui peuvent être importants pour les partenaires.
15 novembre 2024
Mise à jour de Clang vers la version 19.0.1 pour
android-mainlineetandroid16-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 entraîner 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 : L'outil de nettoyage des limites est essentiel pour protéger l'intégrité du noyau en détectant les accès hors limites. Lorsque
CONFIG_UBSAN_TRAPest activé, l'outil de nettoyage des limites déclenche une panique du noyau pour chaque résultat.- La version précédente de l'outil de nettoyage des 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_bypour déterminer les limites du tableau au moment de l'exécution et détecter davantage de cas d'accès hors limites. Toutefois, dans certains cas, le tableau est accessible avant que la variable de taille ne soit définie, ce qui déclenche l'outil de nettoyage des limites et provoque une panique du noyau. Pour résoudre ce problème, définissez la taille du tableau immédiatement après l'allocation de la mémoire sous-jacente, comme illustré dans aosp/3343204.
- La version précédente de l'outil de nettoyage des 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 nettoie le dépassement et le dépassement négatif d'entiers signés malgré l'indicateur de compilateur-fwrapv. L'indicateur-fwrapvest conçu pour traiter les entiers signés comme des entiers non signés à complément à deux avec un comportement de dépassement défini.- Bien que le nettoyage du dépassement d'entiers signés dans le noyau Linux puisse aider à identifier les bugs, il existe des cas où le dépassement est intentionnel, par exemple avec
atomic_long_t. Par conséquent,CONFIG_UBSAN_SIGNED_WRAPa été désactivé pour permettre à UBSAN de fonctionner uniquement comme un outil de nettoyage des limites.
- Bien que le nettoyage du dépassement d'entiers signés dans le noyau Linux puisse aider à identifier les bugs, il existe des cas où le dépassement 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 procédé ainsi pour débloquer la mise à jour du compilateur pendant que nous corrigions les problèmes connus liés à__counted_by.
- 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
- Déploiement de Linux 6.12-rc4
- Résumé :
CONFIG_OF_DYNAMICpeut entraîner de graves régressions pour les pilotes défectueux. - Détails : Lors de la fusion de Linux
6.12-rc1dansandroid-mainline, nous avons remarqué que les pilotes hors arborescence ne parvenaient pas à se charger. La modification qui a exposé les bugs du pilote a été identifiée comme commit274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")et 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 il est implémenté en tant quenoops. L'activation deOF_DYNAMICexpose à 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 différents types d'erreurs, comme 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 de la mémoire (UAF) :
- Réutilisation du même argument
device_node: ces fonctions appellentof_node_put()sur le nœud donné. Il peut être nécessaire d'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_nodeaprè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()
- Conservation de pointeurs directs vers les propriétés
char *dedevice_node, par exemple à l'aide de :const char *foo = struct device_node::nameof_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 :
- Obtention d'un
device_nodeet oubli de le désactiver (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()
- Obtention d'un
- Conservation d'un
device_nodeà partir d'une itération de boucle. Si vous renvoyez ou interrompez l'exécution 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 de la mémoire (UAF) :
- La modification mentionnée précédemment a été restaurée lors du déploiement de Linux
6.12-rc4(voir aosp/3315251) ce qui a réactivéCONFIG_OF_DYNAMICet a potentiellement exposé des pilotes défectueux.
- Résumé :