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)
Où 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
.
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
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)
où 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.
int mallopt(M_MEMTAG_TUNING, level)
où 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 leSA_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
- La collecte des traces de piles nécessite également
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.
Utilisation recommandée
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.