Extension d'ajout de tags de mémoire ARM

<ph type="x-smartling-placeholder">

Arm v9 introduit la mémoire Arm L'extension de taggage (MTE), une implémentation matérielle de mémoire taguée.

De manière générale, MTE ajoute un tag à chaque allocation/désallocation de mémoire des métadonnées supplémentaires. Il attribue un tag à un emplacement de mémoire, qui peut ensuite être associés aux pointeurs qui font référence à cet emplacement de mémoire. Au moment de l'exécution, le processeur vérifie que le pointeur et les balises de métadonnées correspondent à chaque chargement et magasin.

Sous Android 12, le noyau et l'outil d'allocation de mémoire de segment de mémoire de l'espace utilisateur chaque allocation avec des métadonnées. Cela permet de détecter les utilisations après libération les bugs de dépassement de mémoire tampon, qui sont la source la plus courante de bugs de sécurité de la mémoire dans nos codebases.

Modes de fonctionnement avec MTE

MTE propose trois modes de fonctionnement:

  • Mode synchrone (SYNC)
  • Mode asynchrone (ASYNC)
  • Mode asymétrique (ASYMM)

Mode synchrone (SYNC)

Ce mode est optimisé pour détecter les bugs de façon plus précise que la performance. peut être utilisé comme un outil précis de détection des bugs, lorsqu'un impact plus important sur les performances acceptable. Lorsqu'il est activé, MTE SYNC agit comme une mesure de sécurité. En cas de non-concordance des tags, le processeur annule immédiatement l'exécution et termine le processus avec SIGSEGV (le code SEGV_MTESERR) et des informations complètes sur l'accès à la mémoire et l'adresse défaillante.

Nous vous recommandons d'utiliser ce mode pendant les tests au lieu de HWASan/KASAN ou en production lorsque le processus cible représente un sur votre surface d'attaque. En outre, lorsque le mode ASYNC a indiqué la présence d'un vous pouvez obtenir un rapport de bug précis en utilisant les API d'exécution l'exécution en mode SYNC.

En mode SYNC, l'outil d'allocation Android enregistre les traces de la pile pour toutes les allocations et désallocations, les utilise pour fournir de meilleurs rapports d'erreur, qui incluent une explication d'une mémoire comme "use-after-free" ou "buffer-overflow", ainsi que les traces de pile de l'objet les événements de mémoire pertinents. Ces rapports fournissent plus d'informations contextuelles et faciliter le traçage et la correction des bogues.

Mode asynchrone (ASYNC)

Ce mode est optimisé pour les performances plutôt que pour la précision des rapports de bug. être utilisé comme une détection à faible coût pour les bugs de sécurité de la mémoire.
En cas de non-concordance des tags, le processeur continue l'exécution jusqu'à ce que le plus proche l'entrée du noyau (par exemple, un appel système ou une interruption de minuteur), où elle s'arrête le processus avec SIGSEGV (code SEGV_MTEAERR) sans en enregistrant l'adresse défaillante ou l'accès à la mémoire.
Nous vous recommandons d'utiliser ce mode en production sur des codebases bien testés, la densité des bugs de sécurité de la mémoire est connue pour être faible, ce qui est obtenu en utilisant le mode SYNC pendant les tests.

Mode asymétrique (ASYMM)

Une fonctionnalité supplémentaire dans Arm v8.7-A : le mode MTE asymétrique fournit des métriques des vérifications des lectures de la mémoire et des vérifications asynchrones des écritures dans la mémoire, avec des performances similaires à celles du mode ASYNC. Dans la plupart des cas, est une amélioration par rapport au mode ASYNC. Nous vous recommandons de l'utiliser plutôt que ASYNC dès qu'il est disponible.

Pour cette raison, aucune des API décrites ci-dessous ne mentionne le service . Au lieu de cela, le système d’exploitation peut être configuré pour toujours utiliser le mode asymétrique lorsque La requête asynchrone est demandée. Reportez-vous à la section "Configuration niveau MTE souhaité" pour en savoir plus.

MTE dans l'espace utilisateur

Les sections suivantes décrivent comment activer MTE pour les processus système et des applications. MTE est désactivé par défaut, sauf si l'une des options ci-dessous est pour un processus particulier (voir les composants qui sont activés pour MTE ci-dessous).

<ph type="x-smartling-placeholder">

Activer MTE à l'aide du système de compilation

En tant que propriété à l'échelle du processus, MTE est contrôlé par le paramètre de durée de compilation de l'exécutable principal. Les options suivantes permettent de modifier ce paramètre pour des exécutables individuels, ou pour des sous-répertoires entiers de l'arborescence source. La est ignoré sur les bibliothèques, ou sur toute cible qui n'est ni exécutable, ni test.

1. Activation de MTE dans Android.bp (exemple) pour un projet particulier:

Mode MTE Paramètre
MTE asynchrone
  sanitize: {
  memtag_heap: true,
  }
MTE synchrone
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

ou dans Android.mk:

Mode MTE Paramètre
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

2. Activer MTE sur un sous-répertoire de l'arborescence source à l'aide d'un produit :

Mode MTE Inclure la liste Exclure une liste
asynchrone PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
Synchronisation PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

ou

Mode MTE Paramètre
MTE asynchrone MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MTE synchrone MEMTAG_HEAP_SYNC_INCLUDE_PATHS

ou en spécifiant le chemin d'exclusion d'un exécutable:

Mode MTE Paramètre
MTE asynchrone PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
MTE synchrone

Exemple (utilisation semblable à PRODUCT_CFI_INCLUDE_PATHS)

  PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
  PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
                                    vendor/$(vendor)/projectB

Activer MTE à l'aide des propriétés système

Les paramètres de compilation ci-dessus peuvent être remplacés au moment de l'exécution en définissant le la propriété système suivante:

arm64.memtag.process.<basename> = (off|sync|async)

basename correspond au nom de base de l'exécutable.

Par exemple, pour définir /system/bin/ping ou /data/local/tmp/ping Pour utiliser MTE asynchrone, utilisez adb shell setprop arm64.memtag.process.ping async.

<ph type="x-smartling-placeholder">

Activer MTE à l'aide d'une variable d'environnement

Une autre façon de remplacer le paramètre de compilation consiste à définir l'environnement variable: MEMTAG_OPTIONS=(off|sync|async) Si la variable d'environnement et la propriété système sont toutes deux définies, est prioritaire.

Activer MTE pour les applications

S'il n'est pas spécifié, MTE est désactivé par défaut, mais les applications qui souhaitent utiliser MTE peuvent le faire en définissant android:memtagMode sous le <application> ou Balise <process> dans AndroidManifest.xml

<ph type="x-smartling-placeholder"> android:memtagMode=(off|default|sync|async)

Lorsqu'elle est définie sur la balise <application>, affecte tous les processus utilisés par l'application et peut être ignoré pour chaque processus en définissant Balise <process>.

Pour les tests, la compatibilité changes peuvent être utilisés pour définir la valeur par défaut memtagMode pour une application n'indique aucune valeur dans le fichier manifeste (ou indique default).
Vous les trouverez sous System > Advanced > Developer options > App Compatibility Changes dans le menu des paramètres généraux. Paramètre NATIVE_MEMTAG_ASYNC ou NATIVE_MEMTAG_SYNC active MTE pour une application spécifique.
Vous pouvez également définir ce paramètre à l'aide de am comme suit:

$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name

Créer une image système MTE

Nous vous recommandons vivement d'activer MTE sur tous les binaires natifs pendant le développement. et lever le pied. Cela permet de détecter rapidement les bugs de sécurité de la mémoire et fournit la couverture utilisateur, si elle est activée dans les versions de test.

Nous vous recommandons vivement d'activer MTE en mode synchrone sur tous les binaires natifs pendant le développement.

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

Comme pour toute variable du système de compilation, SANITIZE_TARGET peut être utilisée comme variable d'environnement ou comme paramètre make (par exemple, dans un fichier product.mk).
Notez que cette opération active MTE pour tous les processus natifs, mais pas pour applications (dupliquées à partir de zygote64) pour lesquelles MTE peut être en suivant les instructions ci-dessus.

Configurer le niveau MTE préféré spécifique au processeur

Sur certains processeurs, les performances de MTE en mode ASYMM ou même SYNC peuvent être similaires à celui d'ASYNC. Il est donc intéressant d'activer des contrôles plus stricts sur ces CPU lorsqu'un mode de vérification moins strict est demandé, dans afin de bénéficier des avantages de détection des erreurs grâce aux contrôles les plus stricts, et peut nuire aux performances.
Par défaut, les processus configurés pour s'exécuter en mode ASYNC s'exécutent dans ASYNC. sur tous les CPU. Pour configurer le noyau afin qu'il exécute ces processus en mode SYNC sur processeurs spécifiques, la valeur "sync" doit être écrite dans le sysfs entrée /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred au démarrage en temps réel. Pour ce faire, vous pouvez utiliser un script d'initialisation. Par exemple, pour configurer les processeurs de 0 à 1 pour exécuter les processus en mode ASYNC en mode SYNC, et les CPU 2 à 3 à utiliser s'exécutent en mode ASYMM, Le code suivant peut être ajouté à la clause init d'un script d'initialisation du fournisseur:

  write /sys/devices/system/cpu/cpu0/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu1/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu2/mte_tcf_preferred asymm
  write /sys/devices/system/cpu/cpu3/mte_tcf_preferred asymm

Les tombstones des processus en mode ASYNC s'exécutant en mode SYNC contiennent un élément une trace précise de la pile indiquant l'emplacement de l'erreur de mémoire. Toutefois, ils ne peuvent inclure une trace de la pile d'allocation ou de désallocation. Ces traces de pile ne sont disponible si le processus est configuré pour s'exécuter en mode SYNC.

<ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder"> int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

level est égal à 0 ou 1.
Désactive l'initialisation de la mémoire dans malloc et évite de modifier les tags de mémoire sauf si c'est nécessaire pour des raisons d'exactitude.

<ph type="x-smartling-placeholder"> int mallopt(M_MEMTAG_TUNING, level)

level est:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

Sélectionne la stratégie d'allocation de tags.

  • Le paramètre par défaut est M_MEMTAG_TUNING_BUFFER_OVERFLOW.
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW : active un mode déterministe Détection des bugs de dépassement/dépassement de mémoire tampon linéaire par l'attribution de tags distincts aux allocations adjacentes. Ce mode a un risque légèrement réduit de détecter les bugs d'utilisation après libération, car seule la moitié des valeurs de balise possibles sont disponible pour chaque emplacement de mémoire. N'oubliez pas que MTE ne peut pas détecter dans le même fragment de tag (bloc aligné de 16 octets) et peut passer à côté même dans ce mode. Un tel débordement ne peut pas être la cause d'un problème de mémoire la mémoire d'un granule n'est jamais utilisée pour plusieurs allocations généreuses.
  • M_MEMTAG_TUNING_UAF : active les tags aléatoires indépendants pour une probabilité uniforme d'environ 93% de détection à la fois des signaux spatiaux (dépassement de mémoire tampon) et les bugs temporels (utilisation après libération).

Outre les API décrites ci-dessus, les utilisateurs expérimentés peuvent souhaiter être tenir compte de ce qui suit:

  • La définition du registre matériel PSTATE.TCO peut temporairement supprimer la vérification des balises (exemple). Par exemple, lors de la copie d'une plage de mémoire dont le contenu de tag est inconnu, ou en éliminant un goulot d'étranglement des performances dans une boucle chaude.
  • Lorsque vous utilisez M_HEAP_TAGGING_LEVEL_SYNC, le gestionnaire de plantages du système fournit des informations supplémentaires, telles que les traces de la pile d'allocation et de désallocation. Cette fonctionnalité nécessite un accès aux bits de tag et est activée en transmettant le SA_EXPOSE_TAGBITS lors de la définition du gestionnaire de signaux. Tout programme qui définit son propre signal et délègue les plantages inconnus au système 1, même chose.

MTE dans le noyau

Pour activer l'authentification KASAN accélérée par MTE pour le noyau, configurez celui-ci avec CONFIG_KASAN=y, CONFIG_KASAN_HW_TAGS=y. Ces configurations sont activés par défaut sur les noyaux GKI, à partir de Android 12-5.10.
Vous pouvez contrôler cette option au démarrage à l'aide des arguments de ligne de commande suivants:

  • kasan=[on|off] : activer ou désactiver KASAN (valeur par défaut : on).
  • kasan.mode=[sync|async] – choisir entre les modes synchrone et asynchrone (par défaut: sync) ;
  • kasan.stacktrace=[on|off] - collecte ou non traces de la pile (par défaut: on) <ph type="x-smartling-placeholder">
      </ph>
    • La collecte des traces de piles nécessite également stack_depot_disable=off
  • kasan.fault=[report|panic] : indique si le rapport doit uniquement être imprimé, ou paniquer le noyau (par défaut: report). Dans tous les cas, , la vérification des balises est désactivée après la première erreur signalée.
<ph type="x-smartling-placeholder">

Nous vous recommandons vivement d'utiliser le mode SYNC pendant la mise en route, le développement et tests. Cette option doit être activée de manière globale pour tous les processus à l'aide de la variable d'environnement ou du système de compilation. Dans ce mode, les bugs sont détectés au début du processus de développement, le codebase est stabilisé plus rapidement et les coûts liés à la détection des bugs à un stade ultérieur de la production est évité.

En production, nous vous recommandons vivement d'utiliser le mode ASYNC. Cela offre une faiblesse pour détecter la présence de bugs de sécurité de la mémoire au cours d'un processus, ainsi qu'une défense en profondeur. Lorsqu'un bug est détecté, le développeur peut utiliser les API d'exécution pour passer en mode SYNC et obtenir une trace de pile précise ; auprès d'un échantillon d'utilisateurs.

Nous vous recommandons vivement de configurer le niveau MTE préféré spécifique au processeur pour le SoC. Le mode Asymm présente généralement les mêmes caractéristiques de performance qu'ASYNC, et est presque toujours préférable. Les cœurs de petite taille présentent souvent des des performances dans les trois modes et peut être configuré de façon à privilégier la fonctionnalité SYNC.

<ph type="x-smartling-placeholder">

Les développeurs doivent vérifier la présence de plantages /data/tombstones, logcat ou en surveillant le fournisseur DropboxManager pour détecter les bugs des utilisateurs finaux. Pour en savoir plus sur le débogage du code natif Android, consultez cliquez ici pour en savoir plus.

Composants de la plate-forme compatibles avec MTE

Dans Android 12, un certain nombre de composants système critiques de sécurité utilisent MTE ASYNC. pour détecter les plantages des utilisateurs finaux et agir en tant que couche supplémentaire une défense en profondeur. Ces composants sont les suivants:

  • Les daemons et les utilitaires de mise en réseau (à l'exception des netd).
  • Bluetooth, SecureElement, HAL NFC et applications système
  • Démon statsd
  • system_server
  • zygote64 (pour autoriser les applications à utiliser MTE)

Ces cibles ont été sélectionnées selon les critères suivants:

  • Un processus privilégié (défini comme un processus ayant accès à quelque chose que le domaine SELinux unprivileged_app)
  • Traitement des entrées non fiables (Règle sur deux).
  • Ralentissement acceptable des performances (le ralentissement ne rend pas visible l'utilisateur la latence)

Nous encourageons les fournisseurs à activer MTE en production pour plus de composants, répondant aux critères mentionnés ci-dessus. Pendant le développement, nous vous recommandons ces composants à l'aide du mode SYNC, afin de détecter les bugs facilement corrigés et d'évaluer les sur leurs performances.
À l'avenir, Android prévoit d'étendre la liste des composants système MTE est activé, guidés par les caractéristiques de performance des conceptions matérielles à venir.