Google is committed to advancing racial equity for Black communities. See how.
Cette page a été traduite par l'API Cloud Translation.
Switch to English

Désinfection par débordement d'entier

Les débordements d'entiers non intentionnels peuvent entraîner une corruption de la mémoire ou des vulnérabilités de divulgation d'informations dans les variables associées aux accès à la mémoire ou aux allocations de mémoire. Pour lutter contre cela, nous avons ajouté les désinfectants de débordement d'entiers signés et non signés UndefinedBehaviorSanitizer (UBSan) de Clang pour renforcer le cadre multimédia dans Android 7.0. Dans Android 9, nous avons étendu UBSan pour couvrir plus de composants et amélioré la prise en charge du système de construction.

Ceci est conçu pour ajouter des vérifications autour des opérations / instructions arithmétiques - qui peuvent déborder - pour interrompre en toute sécurité un processus en cas de dépassement de capacité. Ces désinfectants peuvent atténuer une classe entière de vulnérabilités de corruption de mémoire et de divulgation d'informations dont la cause première est un débordement d'entier, comme la vulnérabilité Stagefright d'origine.

Exemples et source

La désinfection de débordement d'entier (IntSan) est fournie par le compilateur et ajoute une instrumentation dans le binaire pendant la compilation pour détecter les débordements arithmétiques. Il est activé par défaut dans divers composants de la plate-forme, par exemple /platform/external/libnl/Android.bp .

la mise en oeuvre

IntSan utilise les désinfectants de débordement d'entiers signés et non signés d'UBSan. Cette atténuation est activée au niveau par module. Il permet de sécuriser les composants critiques d'Android et ne doit pas être désactivé.

Nous vous encourageons vivement à activer la désinfection des débordements entiers pour les composants supplémentaires. Les candidats idéaux sont le code natif privilégié ou le code natif qui analyse les entrées utilisateur non fiables. Il y a une petite surcharge de performance associée à l'assainisseur qui dépend de l'utilisation du code et de la prévalence des opérations arithmétiques. Attendez-vous à un petit pourcentage de frais généraux et testez si les performances sont un problème.

Soutenir IntSan dans les makefiles

Pour activer IntSan dans un makefile, ajoutez:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE prend une liste de désinfectants séparés par des virgules, avec integer_overflow étant un ensemble d'options pré-emballées pour les désinfectants de débordement d'entiers signés et non signés individuels avec une liste noire par défaut .
  • LOCAL_SANITIZE_DIAG active le mode de diagnostic pour les désinfectants. Utilisez le mode de diagnostic uniquement pendant les tests, car cela n'interrompra pas les débordements, annulant complètement l'avantage de sécurité de l'atténuation. Voir Dépannage pour plus de détails.
  • LOCAL_SANITIZE_BLACKLIST vous permet de spécifier un fichier de liste noire pour empêcher le LOCAL_SANITIZE_BLACKLIST fonctions et des fichiers source. Voir Dépannage pour plus de détails.

Si vous souhaitez un contrôle plus granulaire, activez les désinfectants individuellement à l'aide d'un ou des deux indicateurs:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

Prise en charge d'IntSan dans les fichiers de plans

Pour activer la désinfection par débordement d'entier dans un fichier de plan directeur, tel que /platform/external/libnl/Android.bp , ajoutez:

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

Comme pour les fichiers make, la propriété integer_overflow est un ensemble d'options pré-emballées pour les nettoyeurs de débordement d'entiers signés et non signés individuels avec une liste noire par défaut .

L'ensemble de propriétés diag active le mode de diagnostic pour les désinfectants. Utilisez le mode de diagnostic uniquement pendant les tests. Le mode Diagnostics n'interrompt pas en cas de dépassement de capacité, ce qui annule complètement l'avantage de sécurité de l'atténuation dans les versions utilisateur. Voir Dépannage pour plus de détails.

La propriété de blacklist permet de spécifier un fichier de liste noire qui permet aux développeurs d'empêcher le nettoyage des fonctions et des fichiers source. Voir Dépannage pour plus de détails.

Pour activer les désinfectants individuellement, utilisez:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Dépannage

Si vous activez la désinfection par débordement d'entier dans de nouveaux composants ou si vous comptez sur des bibliothèques de plate-forme qui ont subi une désinfection par débordement d'entier, vous pouvez rencontrer quelques problèmes avec des débordements d'entiers bénins provoquant des abandons. Vous devez tester les composants avec la désinfection activée pour vous assurer que des débordements bénins peuvent apparaître.

Pour trouver les abandons provoqués par le nettoyage dans les builds utilisateur, recherchez les plantages SIGABRT avec des messages d'abandon indiquant un débordement intercepté par UBSan, tels que:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

La trace de pile doit inclure la fonction provoquant l'abandon, cependant, les débordements qui se produisent dans les fonctions en ligne peuvent ne pas être évidents dans la trace de pile.

Pour déterminer plus facilement la cause première, activez les diagnostics dans la bibliothèque déclenchant l'abandon et essayez de reproduire l'erreur. Avec les diagnostics activés, le processus n'interrompra pas et continuera à s'exécuter. Ne pas abandonner permet de maximiser le nombre de débordements bénins dans un chemin d'exécution particulier sans avoir à recompiler après avoir corrigé chaque bogue. Diagnostics génère un message d'erreur qui comprend le numéro de ligne et le fichier source à l'origine de l'abandon:

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')

Une fois l'opération arithmétique problématique localisée, assurez-vous que le débordement est inoffensif et intentionnel (par exemple, il n'a pas d'implications sur la sécurité). Vous pouvez résoudre le problème d'abandon du désinfectant en:

  • Refactoriser le code pour éviter le débordement ( exemple )
  • Débordement explicite via les fonctions de débordement __builtin _ * _ de Clang ( exemple )
  • Désactivation de la désinfection dans la fonction en spécifiant l'attribut no_sanitize ( exemple )
  • Désactiver le nettoyage d'une fonction ou d'un fichier source via un fichier de liste noire ( exemple )

Vous devez utiliser la solution la plus granulaire possible. Par exemple, une fonction volumineuse avec de nombreuses opérations arithmétiques et une seule opération de débordement devrait avoir l'opération unique refactorisée plutôt que la fonction entière sur la liste noire.

Les modèles courants qui peuvent entraîner des débordements bénins comprennent:

  • Casts implicites où un débordement non signé se produit avant d'être casté en un type signé ( exemple )
  • Suppressions de listes liées qui décrémentent l'index de la boucle lors de la suppression ( exemple )
  • Attribuer un type non signé à -1 au lieu de spécifier la valeur maximale réelle ( exemple )
  • Boucles qui décrémentent un entier non signé dans la condition ( exemple , exemple )

Il est recommandé aux développeurs de s'assurer que dans les cas où le désinfectant détecte un débordement, celui-ci est en effet bénin sans effets secondaires involontaires ni implications sur la sécurité avant de désactiver le nettoyage.

Désactivation d'IntSan

Vous pouvez désactiver IntSan avec des listes noires ou des attributs de fonction. Désactivez avec parcimonie et uniquement lorsque la refactorisation du code est par ailleurs déraisonnable ou en cas de surcharge de performances problématique.

Consultez la documentation Clang en amont pour plus d'informations sur la désactivation d'IntSan avec les attributs de fonction et le formatage des fichiers de liste noire . La liste noire doit être limitée au désinfectant particulier en utilisant des noms de section spécifiant le désinfectant cible pour éviter d'avoir un impact sur d'autres désinfectants.

Validation

Actuellement, il n'existe pas de test CTS spécifiquement pour la désinfection par débordement d'entier. Au lieu de cela, assurez-vous que les tests CTS réussissent avec ou sans IntSan activé pour vérifier qu'il n'affecte pas le périphérique.