Détails techniques sur l'intégrité du flux de contrôle
"La disponibilité d'un grand nombre de pointeurs de fonctions dans le noyau contribue à la popularité de ce modèle d'attaque. Même si les attaquants ne peuvent pas injecter leur propre code exécutable, des parties arbitraires du code du noyau existant peuvent être exécutées pour mener à bien leur exploit.
LLVMLe CFI de tente d'atténuer ces attaques en restreignant les cibles d'appel valides et en forçant une panique du noyau lors de la détection d'une violation du CFI. Une vérification est ajoutée avant chaque branche indirecte pour confirmer que l'adresse cible pointe vers une fonction valide avec une signature correcte. Cela empêche une branche indirecte de sauter vers un emplacement de code arbitraire et limite même les fonctions pouvant être appelées. Un attaquant pourra toujours modifier un pointeur de fonction, si un bug en autorise l'accès. Mais le CFI de LLVM limite 55 % des appels indirects à 5 cibles possibles au maximum et 80 % à 20 cibles au maximum. Afin de déterminer toutes les cibles d'appel valides pour chaque branche indirecte, le compilateur doit voir tout le code du noyau en même temps.
L'utilisation de LTO (Optimisation du temps de liaison) rend cela possible. Le CFI de LLVM nécessite l'utilisation de LTO, où le compilateur produit un bitcode spécifique à LLVM pour tous les C. unités de compilation, et un éditeur de liens compatible LTO utilise le backend LLVM pour combiner le bitcode et le compiler dans code natif.
En plus de permettre l'utilisation de CFI, LTO permet d'obtenir de meilleures performances d'exécution grâce à l'analyse de l'ensemble du programme et à l'optimisation entre modules.
MinceLTO a presque rattrapé l’amélioration des performances des LTO. En mode ThinLTO, comme avec le LTO standard, Bruit émet le bitcode LLVM après la phase de compilation. Le bitcode ThinLTO est complété par un résumé compact du module. Au cours de l'étape de liaison, seuls les résumés sont lus et fusionnés dans un index récapitulatif combiné, qui comprend un index des emplacements de fonctions pour une importation ultérieure de fonctions inter-modules. Ensuite, une analyse rapide et efficace de l’ensemble du programme est effectuée sur l’index récapitulatif combiné. ThinLTO permet un processus de liaison multithread, ce qui réduit le temps de compilation.
En raison du fait que CFI interrompt l'exécution du programme lorsqu'il atteint certaines classes de bogues, il est également classé comme outil de recherche de bogues, comme mentionné précédemment, lorsqu'il est utilisé en mode permissif. Permissive CFI affichera les violations CFI dans le journal du noyau, sans forcer une panique du noyau. Les noyaux Core 4.9 (appareils de génération Pixel 3) et 4.14 (appareils de génération Pixel 4) avaient plusieurs types de fonctions. incohérences entraînant des violations CFI, qui ont été corrigées par Google dans des ensembles de correctifs disponibles sur le noyau/common repos.
Cependant, en raison de la nature de l'écosystème Android, ces disparités sont susceptibles de se retrouver également dans le code spécifique du fabricant du SoC (dans ce cas, Qualcomm) ou du OEM (OnePlus). Plusieurs violations CFI dans le code Qualcomm distinctes du noyau 4.19 ont été corrigées sur le noyau Kirisakura pour le OnePlus 8 Pro (exemple: 1, 2, 3).
L'exécution du noyau en mode CFI permissif a également révélé des violations CFI dans le code lié aux pilotes OnePlus (les commits pertinents peuvent être trouvés). ici et ici). Le noyau Kirisakura pour le OnePlus 8 Pro fonctionne avec CFI appliqué, protégeant ainsi ses utilisateurs contre ce type d'attaques de réutilisation de code.
En savoir plus
Passionné de bricolage (c'est-à-dire récupérateur de vieilles pièces de PC). Fervent utilisateur d'Android depuis l'époque d'Eclair, Skanda aime également suivre les récentes tendances de développement dans le monde de l'informatique monocarte.