Attaques DMA 101 : comment l’IOMMU empêche un périphérique PCIe de prendre possession de votre RAM

Cet article vous a aidé ?

Votre CPU peut avoir toutes les protections modernes activées — durcissement du noyau, SELinux/AppArmor, disques chiffrés, démarrage mesuré — et un seul
périphérique PCIe peut toujours lire et écrire dans votre RAM sans demander la permission. Ce n’est pas hypothétique. C’est le DMA.

Si vous exploitez des flottes, construisez des postes de travail sécurisés, ou faites du passthrough PCIe dans des environnements virtualisés, l’IOMMU est l’un de ces
contrôles « soit il est activé et correct, soit vous vous faites des illusions ». Concrètement : quelles sont les attaques DMA, ce que l’IOMMU
applique réellement, et comment prouver que votre système fait ce que vous pensez qu’il fait.

DMA en termes simples : pourquoi les périphériques peuvent toucher votre mémoire

DMA signifie « Direct Memory Access ». Le nom est franc : un périphérique transfère des données vers ou depuis la mémoire système sans que le CPU
les copie octet par octet. Le CPU prépare le transfert (buffers, adresses, tailles), puis le périphérique devient maître du bus
et déplace la charge utile. C’est ainsi que le stockage, les GPU, les NIC et les contrôleurs haut débit atteignent les débits promis par le marketing.

Le problème de sécurité est tout aussi franc : si un périphérique peut écrire dans la mémoire physique arbitraire, il peut écraser le code du noyau,
modifier des tables de pages, voler des clés et lire tout ce que vous croyiez « protégé » par le modèle de privilèges du CPU. Les niveaux de ring du CPU
ne s’appliquent pas à un périphérique PCIe. Le bus se moque de vos sentiments.

Un pilote bien conçu programme le périphérique pour DMA uniquement dans des buffers alloués par l’OS. Mais « bien conçu » est un choix de politique,
et les attaquants adorent exploiter les politiques. Un périphérique malveillant, un firmware compromis, ou un bug dans le pilote peut transformer le DMA en
« accès mémoire sans supervision ».

Vous ne pouvez pas contourner cela avec de meilleurs ACL. Il faut une application matérielle entre les périphériques et la mémoire. Cette application
est l’IOMMU.

Pourquoi le DMA existe (et pourquoi on ne peut pas simplement l’interdire)

Si le CPU devait copier chaque paquet d’un NIC dans la RAM et chaque bloc de disque dans le cache de pages manuellement, vous obtiendriez soit :
(a) un débit risible, soit (b) des cœurs consommés par le mouvement de données au lieu de faire du travail. Les systèmes modernes utilisent le DMA plus
la modération des interruptions, les paires de queues et le scatter-gather pour garder le CPU à l’écart.

Dans le stockage et le réseau en particulier, le DMA permet d’atteindre le débit ligne et une faible latence. NVMe utilise des queues de soumission/complétion
en mémoire ; le périphérique DMA les écrit en RAM. Les NICs hautes performances DMA des buffers de paquets dans des hugepages.
RDMA le dit explicitement : « laissez le NIC lire/écrire la mémoire applicative. » Tout cela est excellent — jusqu’à ce que vous vous rappeliez que
le périphérique se trouve hors de la frontière de privilèges du CPU.

Deux modèles de menace que l’on confond souvent

Attaquant physique avec un périphérique : quelqu’un branche un périphérique sur Thunderbolt/PCIe, échange une carte interne,
ou abuse d’un port exposé dans une borne ou une salle serveurs non surveillée. Il n’a pas besoin de votre mot de passe s’il peut lire la RAM.

Attaquant logiciel contrôlant le DMA d’un périphérique : un pilote compromis, une faille du noyau dans la pile d’un périphérique,
une VM malveillante avec passthrough PCI, ou un malware de firmware à l’intérieur d’un périphérique PCIe. L’attaquant n’a pas besoin d’accès physique ; il lui faut un chemin
pour programmer les moteurs DMA.

L’IOMMU aide pour les deux cas, mais les atténuations et les habitudes opérationnelles diffèrent.

Comment les attaques DMA se produisent en pratique

Les attaques DMA ne sont pas de la magie. Ce sont une chaîne : obtenir un périphérique capable d’émettre du DMA, le mettre sur le bus, puis le diriger vers la mémoire.
La partie intéressante est la facilité avec laquelle on peut placer ce périphérique, et jusqu’où on peut aller une fois qu’on peut lire la RAM.

Voie d’attaque 1 : ports externes haut débit

Thunderbolt est essentiellement du PCIe externe. C’est la fonctionnalité. C’est aussi le risque : branchez un périphérique, et vous attachez potentiellement
un maître de bus avec DMA. Les systèmes modernes ajoutent des couches comme les niveaux de sécurité Thunderbolt et l’autorisation OS, mais ce ne sont pas
la même chose que « ce périphérique peut seulement DMA dans un bac à sable ».

Si l’IOMMU est désactivé ou mal configuré, un périphérique malveillant peut scanner la mémoire physique à la recherche de matériel d’identification, de structures noyau, ou de tables de pages.
Si vous avez de la chance, vous « fuitez » juste des secrets. Si vous avez pas de chance, le périphérique écrit et transforme cette fuite en persistance.

Voie d’attaque 2 : firmware de périphérique compromis

Votre NIC a un firmware. Votre SSD a un firmware. Votre GPU a un firmware. Votre contrôleur USB « simple » a aussi un firmware.
Le firmware peut être mis à jour, parfois automatiquement, parfois via des utilitaires du fournisseur, parfois via le pilote.

Si un attaquant exécute du firmware malveillant dans un périphérique PCIe, ce périphérique devient un moteur DMA non surveillé. L’OS ne peut pas
l’introspecter comme il peut introspecter un processus. C’est pourquoi l’IOMMU est traité comme un niveau de base dans les systèmes à haute sûreté : il rapproche la frontière de confiance de la RAM.

Voie d’attaque 3 : virtualisation et passthrough

Le passthrough PCI (VFIO) donne à une VM un accès direct à un périphérique physique. L’intérêt est la performance et l’accès aux fonctions.
Sans IOMMU, le passthrough n’est pas « dangereux ». C’est « vous avez donné une fourchette à la VM et l’avez pointée vers la mémoire de l’hôte. »

Avec un IOMMU correctement configuré, le périphérique est restreint à la mémoire assignée à l’invité. Voilà tout
le modèle de sécurité derrière le passthrough sûr.

Voie d’attaque 4 : bugs de pilotes et « DMA au mauvais endroit »

Tous les incidents DMA ne proviennent pas d’un attaquant en hoodie. Beaucoup sont : « le pilote a programmé une adresse DMA incorrecte », ou « le périphérique
a écrit au-delà de la fin d’un ring buffer », ou « bug dans un mapping IOVA a causé une corruption mémoire. »

L’IOMMU peut transformer ces bugs en « plantage bruyant et radius de dégâts contenu » plutôt qu’en « corruption silencieuse ». C’est une victoire même
quand vous ne pensez pas être attaqué.

Ce que l’IOMMU fait vraiment (et ce qu’il ne fait pas)

Une IOMMU est une unité de gestion de la mémoire pour les E/S. Le CPU a un MMU qui mappe les adresses virtuelles vers la mémoire physique avec
des permissions. L’IOMMU mappe les adresses visibles par le périphérique vers la mémoire physique, également avec des permissions. Les périphériques ne
parlent pas forcément « adresses virtuelles », donc l’IOMMU leur fournit un espace d’adresses (IOVA) et impose ce qu’ils peuvent toucher.

Le mécanisme central : traduction et vérifications de permission pour le DMA

Quand un périphérique tente de DMA vers une adresse, cette adresse est interprétée dans un domaine contrôlé par l’OS. L’IOMMU traduit
cet IOVA vers une adresse physique et vérifie les permissions. Si le mapping n’existe pas, ou si les permissions n’autorisent pas l’opération, l’IOMMU bloque
et signale généralement une faute.

En pratique, cela signifie :

  • Les périphériques ne peuvent pas DMA dans la RAM arbitraire simplement parce qu’ils sont maîtres du bus.
  • Chaque périphérique (ou groupe de périphériques) peut être placé dans un domaine d’isolation.
  • La virtualisation peut assigner un périphérique à un invité et restreindre le DMA à la mémoire de l’invité.
  • Les pilotes bogués provoquent des fautes bruyantes plutôt que des corruptions silencieuses — si l’IOMMU est configurée en mode appliqué.

L’IOMMU ≠ bouclier magique

L’IOMMU ne vous sauve pas si vous ne l’activez jamais, ou si vous l’activez mais laissez les périphériques dans un domaine en mappage identité
où IOVA==physique pour « compatibilité ». Elle ne protège pas non plus contre un périphérique autorisé à DMA dans un buffer où vous déposez ensuite des secrets.
Le principe du moindre privilège reste valable.

Elle ne peut pas non plus empêcher un périphérique malveillant de faire des dégâts à l’intérieur de sa région autorisée. Si vous donnez à un GPU l’accès à la moitié de votre
RAM pour « la performance », vous avez fait un choix. L’IOMMU appliquera fidèlement ce choix.

Intel VT-d, AMD-Vi, et comment Linux nomme les choses

Chez Intel, l’IOMMU est typiquement VT-d. Chez AMD, AMD-Vi (aussi appelée IOMMU, parfois « IVRS » dans les contextes ACPI).
Dans les logs Linux vous verrez « DMAR » sur les plateformes Intel, et « AMD-Vi » ou « IOMMU » sur AMD.

Linux utilise des API et des pilotes IOMMU. Les périphériques sont assignés à des groupes IOMMU, qui comptent énormément pour la virtualisation :
un groupe est la granularité d’isolation la plus petite que le noyau peut appliquer en toute sécurité en fonction de la façon dont les périphériques sont connectés et comment
ACS (Access Control Services) est implémenté dans votre topologie PCIe. Si deux fonctions peuvent se sonder mutuellement le trafic,
elles se retrouvent dans un même groupe, et vous ne pouvez pas passer en toute sécurité l’une sans l’autre.

Performance : le coût est réel, mais souvent moindre que la peur

La traduction IOMMU ajoute des frais : il y a une TLB de traduction (IOTLB), des parcours de tables de pages, et des vérifications supplémentaires.
Les périphériques à haut débit peuvent la solliciter fortement. Mais les IOMMU modernes sont rapides, et Linux propose des atténuations comme le batching, les hugepages,
et des modes passthrough par périphérique quand approprié.

La position opérationnelle que je recommande : traiter l’application complète de l’IOMMU comme valeur par défaut. Se désengager par périphérique seulement après
mesure, et uniquement lorsque le modèle de menace le permet. « Nous l’avons désactivée parce que quelqu’un a dit que c’était plus lent » n’est pas une décision d’ingénierie.
C’est une rumeur avec des privilèges root.

Une citation pour rester honnête

idée paraphrasée — Werner Vogels : vous le construisez pour qu’il échoue en toute sécurité ; vous n’assumez pas qu’il ne tombera pas en panne.

Faits intéressants et contexte historique

Voici des éléments concrets d’histoire qui expliquent pourquoi ce sujet réapparaît tous les quelques années comme une mauvaise dépendance.

  1. Le DMA précède les modèles de sécurité modernes des OS. Les systèmes anciens utilisaient le DMA pour décharger des CPU lents ; la sécurité n’était pas le moteur principal de conception.
  2. PCI a rendu le bus mastering courant. PCI puis PCIe ont standardisé l’accès hautes performances des périphériques, rendant le DMA une capacité par défaut pour beaucoup de contrôleurs.
  3. FireWire a été un des premiers signaux d’alerte « DMA externe ».  IEEE 1394 a exposé un accès de type DMA d’une manière qui a surpris les utilisateurs de portables et les équipes sécurité.
  4. VT-d/AMD-Vi ont mûri avec la virtualisation. Les fournisseurs matériels ont investi lourdement parce que l’affectation sûre de périphériques aux VM l’exigeait.
  5. Les « groupes IOMMU » sont façonnés par la topologie PCIe. Le groupement n’est pas une lubie Linux ; il reflète quels périphériques peuvent être isolés compte tenu des bridges, ACS et du routage.
  6. Thunderbolt a popularisé le PCIe externe pour les consommateurs. Idéal pour les docks et eGPU ; aussi un vecteur DMA emballé si vous ne le contrôlez pas.
  7. Les fautes IOMMU peuvent être une mine d’or diagnostique. En production, les logs de fautes IOMMU ont permis de détecter des bugs de pilotes qui semblaient autrement être des erreurs RAM aléatoires.
  8. Certains systèmes ont été livrés des années avec l’IOMMU désactivée par défaut. Les craintes de compatibilité et de performance étaient réelles ; la dette de sécurité aussi.
  9. Les noyaux modernes supportent des fonctionnalités de protection DMA par périphérique. Le noyau peut choisir un comportement de mapping strict ou paresseux, et certains périphériques peuvent fonctionner en « passthrough » tandis que d’autres sont isolés.

Trois mini-récits en entreprise depuis le terrain

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise SaaS de taille moyenne exploitait un cluster de virtualisation privé pour des workloads CI. Les développeurs pouvaient lancer des VMs avec passthrough GPU
pour accélérer les builds et certains tests ML. L’équipe plateforme a supposé que parce que les hôtes se trouvaient dans une armoire sécurisée et que les VMs étaient « internes »,
le principal risque était les voisins bruyants et le coût.

Un chercheur de l’équipe sécurité a fait ce que font les bons chercheurs : il a demandé « et si la VM est hostile ? » Ils ont obtenu l’autorisation de tester dans un environnement de staging reproduisant le matériel de production.
En staging, ils ont passé un NIC de rechange à un invité pour tester le comportement SR-IOV. L’invité pouvait DMA dans la mémoire de l’hôte. Pas toujours. Pas de manière fiable. Mais suffisamment
pour démontrer la lecture de structures de données qui ne devraient jamais franchir cette frontière.

La cause racine n’était pas exotique. Le BIOS avait « Intel VT-d » disponible mais désactivé. Les docs de provisioning disaient « activer VT-x » pour la virtualisation, et quelqu’un a supposé que VT-x impliquait VT-d.
Ce n’est pas le cas. On peut exécuter des VMs sans isolation DMA de périphériques, jusqu’au moment où on fait du passthrough ou qu’on attache quelque chose de hostile.

La correction fut simple : activer VT-d, forcer l’IOMMU dans le noyau, et mettre à jour la baseline plateforme pour qu’elle refuse les déploiements sans. La partie douloureuse fut l’audit :
ils ont dû re-valider tout le cluster, parce que « on supposait que c’était activé » n’est pas une preuve.

La leçon qui a perduré : si vous opérez une infrastructure virtualisée et prévoyez du passthrough, SR-IOV, ou tout ce qui est « près du hardware », considérez « IOMMU activée et stricte » comme une exigence dure, pas un réglage.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une autre société exploitait des analyses de trading sensibles à la latence sur bare metal avec des NICs spécialisés. Ils tenaient à la microseconde comme d’autres tiennent à l’oxygène.
Lors d’une recherche de performances, quelqu’un a proposé d’activer un mode « IOMMU passthrough » global, arguant que l’IOMMU n’apportait que de la surcharge de traduction et que les systèmes
étaient physiquement sécurisés de toute façon.

Ils ont testé le débit et observé de petites améliorations sur un benchmark synthétique. Victoire. Le changement a été propagé. Quelques jours plus tard, des crashes sporadiques sont apparus :
kernel panics, sk_buffs corrompus, messages d’allocation étranges. Ça ressemblait à de la RAM défaillante. Ça sentait le pilote instable. Ça ne se reproduisait qu’en charge maximale.

La cause réelle était banale et brutale : un bug de pilote programmait parfois un mapping DMA incorrect dans une condition rare de wraparound. Avec l’IOMMU stricte, le DMA hors limites aurait généré une faute.
En mode passthrough, il a écrit dans la mémoire adjacente et transformé un bug récupérable en corruption silencieuse.

Ils ont annulé l’« optimisation », et les crashes ont cessé. Plus tard, ils ont travaillé avec le fournisseur pour corriger le pilote et re-benchmarquer avec des mappings plus stricts mais des pages IOVA plus grandes et un meilleur dimensionnement des queues.
Ils ont récupéré la plupart des performances sans transformer le système mémoire en zone libre.

La leçon : l’IOMMU n’est pas seulement une fonctionnalité de sécurité. C’est la ceinture de sécurité du DMA. La désactiver peut rendre la voiture plus rapide sur une piste droite. Jusqu’au virage.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une organisation de santé avait une politique : chaque ligne de commande du noyau était gérée centralement, et chaque log de démarrage était scrappé pour des signatures spécifiques.
L’une de ces signatures était « IOMMU enabled » et « DMAR: IOMMU enabled » (Intel) ou « AMD-Vi: IOMMU enabled » (AMD). Si elle n’apparaissait pas, l’hôte était mis en quarantaine pour workloads sensibles.

Lors d’un renouvellement matériel de routine, une série de serveurs est arrivée avec des valeurs BIOS par défaut différentes de la génération précédente. Les hôtes ont démarré.
Ils ont rejoint l’inventaire. Ils ont passé des checks basiques. Mais le scrapper de logs a signalé l’absence d’activation de l’IOMMU sur un sous-ensemble.

La réaction immédiate de l’équipe projet fut de l’agacement. « Ils sont dans le même datacenter verrouillé. » « On n’utilise pas Thunderbolt. » « On règlera ça plus tard. » L’SRE de garde a dit non,
parce que tout l’intérêt des baselines est que vous ne négociez pas à 2 h du matin. Ils ont arrêté le déploiement et corrigé les réglages BIOS avant de déplacer des workloads.

Deux semaines plus tard, un sous-traitant a été surpris en train de brancher un périphérique PCIe non autorisé sur une machine de labo dans un autre environnement. Cet incident n’a pas touché la prod,
mais il a rappelé que les hypothèses physiques se dégradent avec le temps. La vérification ennuyeuse des logs a évité une classe de défaillances « on n’y a pas cru important » dans des systèmes régulés.

La leçon : on n’obtient pas la fiabilité par des actes héroïques. On l’obtient par l’automatisation terne qui refuse de négocier.

Tâches pratiques : commandes, sorties et décisions

Voici des vérifications pratiques que vous pouvez exécuter sur des systèmes Linux. Chaque tâche inclut : une commande, ce que signifie une sortie typique,
et la décision à prendre. Ce ne sont pas des exercices académiques ; ce sont les étapes exactes que vous utilisez quand quelqu’un demande
« IOMMU est-elle activée ? » ou « Pourquoi VFIO échoue ? » ou « Pourquoi la NIC bloque sous charge ? »

Task 1: Check kernel boot parameters for IOMMU enablement

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.8.0 root=/dev/mapper/vg0-root ro quiet intel_iommu=on iommu=pt

Ce que cela signifie : intel_iommu=on demande Intel VT-d. iommu=pt est le mode « passthrough »
pour les périphériques qui n’utilisent pas les mappings de l’API DMA (souvent un choix de performance).

Décision : Si vous sécurisez contre le DMA, évitez iommu=pt système-wide sauf si vous comprenez
quels périphériques seront en passthrough et pourquoi. Préférez la traduction stricte/par défaut quand le modèle de menace inclut des périphériques hostiles.

Task 2: Confirm IOMMU actually initialized (Intel DMAR)

cr0x@server:~$ dmesg | grep -E 'DMAR|IOMMU'
[    0.842113] DMAR: IOMMU enabled
[    0.842981] DMAR: Host address width 46
[    0.843540] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[    0.848992] DMAR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
[    0.850220] DMAR: Interrupt remapping enabled

Ce que cela signifie : Vous voulez voir « IOMMU enabled » et idéalement « Interrupt remapping enabled. » Le remappage d’interruptions compte
car MSI/MSI-X peut aussi être abusé ; le remappage réduit ce radius d’impact.

Décision : Si la ligne manque, vous n’êtes pas protégé. Corrigez d’abord les réglages BIOS/UEFI, puis les paramètres du noyau.

Task 3: Confirm IOMMU initialized (AMD-Vi)

cr0x@server:~$ dmesg | grep -E 'AMD-Vi|IOMMU'
[    0.611234] AMD-Vi: IOMMU performance counters supported
[    0.611290] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[    0.611542] AMD-Vi: Extended features (0xf77ef22294ada): PPR NX GT IA GA PC GA_vAPIC
[    0.611910] AMD-Vi: Interrupt remapping enabled

Ce que cela signifie : L’IOMMU AMD est active et le remappage d’interruptions est activé.

Décision : Si vous ne le voyez pas, traitez l’hôte comme non conforme pour le passthrough et pour les environnements physiques à haut risque.

Task 4: Check if the IOMMU filesystem view is present

cr0x@server:~$ ls -1 /sys/kernel/iommu_groups | head
0
1
10
11
12

Ce que cela signifie : Des groupes IOMMU existent. C’est un bon signe, bien que ce ne soit pas une garantie complète du mode strict.

Décision : Si ce chemin n’existe pas, soit vous n’avez pas l’IOMMU activée, soit votre noyau/config la masque. Enquêtez avant de tenter VFIO.

Task 5: List devices and their IOMMU groups (for passthrough planning)

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group ${g##*/}"; lspci -nns $(basename -a $g/devices/*); echo; done
Group 7
00:1f.0 ISA bridge [0601]: Intel Corporation Device [8086:7a06]

Group 8
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684]
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:22ba]

Ce que cela signifie : Votre GPU et sa fonction audio HDMI sont dans le même groupe. C’est normal. Si votre GPU
partage un groupe avec des composants chipset aléatoires, c’est un signal d’alerte pour l’isolation en passthrough.

Décision : Ne passez que des groupes entiers. Si le groupement est trop grossier, envisagez d’autres emplacements PCIe,
l’activation d’ACS dans le BIOS, ou un changement de matériel. Évitez les « patches ACS override » en production sauf si vous acceptez les compromis de sécurité.

Task 6: Verify VFIO is using an IOMMU domain for a passed-through device

cr0x@server:~$ dmesg | grep -E 'vfio|IOMMU' | tail -n 20
[  124.332910] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[  124.341210] vfio_iommu_type1: DMA mapping enabled
[  124.341985] vfio_pci: add [10de:2684[ffffffff:ffffffff]] class 0x000000/00000000

Ce que cela signifie : vfio_iommu_type1 indique que le backend IOMMU VFIO est utilisé, mappant le DMA pour l’invité.

Décision : Si VFIO se plaint de l’absence d’IOMMU, ne pas « forcer ». Corrigez la configuration plateforme. Sinon vous construisez une salle d’évasion sans murs.

Task 7: Check whether the kernel is in strict DMA mode or using lazy mapping

cr0x@server:~$ cat /sys/module/iommu/parameters/strict
Y

Ce que cela signifie : Le mode strict est activé (unmap immédiat, protection plus stricte, parfois plus de surcharge).
Sur certains systèmes vous verrez N, indiquant un unmap différé/paresseux.

Décision : Pour les hôtes sensibles, préférez strict. Pour des appliances orientées performance dans des environnements contrôlés,
vous pouvez accepter le non-strict si vous comprenez le risque et mesurez le gain.

Task 8: Detect IOMMU faults (the “your device tried something illegal” signal)

cr0x@server:~$ dmesg | grep -i -E 'DMAR:.*fault|IOMMU.*fault|AMD-Vi:.*event' | tail -n 20
[ 9231.112233] DMAR: DRHD: handling fault status reg 2
[ 9231.112241] DMAR: [DMA Read] Request device [01:00.0] fault addr 0x0000000f3a200000 [fault reason 0x06] PTE Read access is not set

Ce que cela signifie : Un périphérique a tenté de DMA lire une adresse sans permission. Cela peut être une attaque, un bug de pilote,
ou une condition de reset du périphérique.

Décision : Traitez les fautes répétées comme un incident. Identifiez le périphérique, mettez à jour pilotes/firmware, et envisagez de le retirer du service.
Si c’est un cas isolé pendant un reset, corrélez avec les logs et événements matériels.

Task 9: Identify a device by BDF and map it to a driver

cr0x@server:~$ lspci -s 01:00.0 -nnk
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2684] (rev a1)
	Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:5123]
	Kernel driver in use: vfio-pci
	Kernel modules: nvidiafb, nouveau

Ce que cela signifie : Le périphérique à 01:00.0 est lié à vfio-pci. Cela implique que vous avez l’intention de l’assigner.

Décision : Si vous n’aviez pas l’intention de l’assigner, corrigez le binding du pilote. Si oui, assurez-vous que le groupe est isolé et que l’invité est correctement configuré.

Task 10: Check whether interrupt remapping is active (security + stability)

cr0x@server:~$ dmesg | grep -i 'remapping' | head
[    0.850220] DMAR: Interrupt remapping enabled
[    0.850232] DMAR-IR: Enabled IRQ remapping in x2apic mode

Ce que cela signifie : Le remappage d’IRQ est activé ; cela aide à contenir des périphériques pouvant générer des interruptions de façon inattendue.

Décision : Si ce n’est pas activé, vérifiez les réglages BIOS et les paramètres du noyau. Certaines plateformes le désactivent quand elles sont mal configurées ; corrigez cela avant de faire confiance au passthrough.

Task 11: Confirm a Thunderbolt controller exists and how it’s authorized

cr0x@server:~$ lspci | grep -i thunderbolt
3d:00.0 USB controller: Intel Corporation Thunderbolt 4 NHI [Maple Ridge]

Ce que cela signifie : Vous avez un contrôleur Thunderbolt. C’est un point d’entrée PCIe externe.

Décision : Sur portables/postes de travail, associez IOMMU à une politique de sécurité Thunderbolt. Sur serveurs, envisagez de désactiver les ports PCIe externes si vous n’en avez pas besoin.

Task 12: Check kernel lockdown / Secure Boot state (helps enforce policy, not IOMMU itself)

cr0x@server:~$ cat /sys/kernel/security/lockdown
integrity

Ce que cela signifie : Le verrouillage du noyau est en mode integrity (commun sous Secure Boot). Cela peut réduire la capacité
du root à effectuer certaines actions risquées, comme l’accès arbitraire à la mémoire du noyau.

Décision : Ne confondez pas cela avec la protection DMA. C’est complémentaire. Gardez-le activé pour des workloads à haute confiance, mais vérifiez toujours l’IOMMU.

Task 13: Inspect DMA mask / addressing capability (helps explain mapping failures)

cr0x@server:~$ cat /sys/bus/pci/devices/0000:01:00.0/dma_mask_bits
64

Ce que cela signifie : Le périphérique peut DMA des adresses 64-bit. Les périphériques limités à 32-bit peuvent provoquer du bounce buffering
et des pénalités de performance, et augmentent la pression sur les zones mémoire basses.

Décision : Si vous voyez 32-bit sur un périphérique haut débit, attendez-vous à de la surcharge. Envisagez de remplacer le matériel, ou des stratégies de pin/bounce selon votre pile.

Task 14: Check hugepages (performance tuning for DMA-heavy workloads)

cr0x@server:~$ grep -E 'HugePages|Hugepagesize' /proc/meminfo
HugePages_Total:      2048
HugePages_Free:       1980
HugePages_Rsvd:         12
Hugepagesize:        2048 kB

Ce que cela signifie : Des hugepages de 2MB sont configurées. Les grandes pages peuvent réduire la surcharge des mappings IOMMU en diminuant le nombre
de traductions IOVA nécessaires pour de grands buffers.

Décision : Si vous luttez contre des IOTLB misses ou une surcharge de mapping DMA, envisagez les hugepages — mais seulement après mesure et en vérifiant que votre application en bénéficie.

Task 15: Watch IOMMU-related kernel messages live during device resets

cr0x@server:~$ journalctl -k -f
Feb 04 12:11:19 server kernel: vfio-pci 0000:01:00.0: Resetting device
Feb 04 12:11:19 server kernel: DMAR: [DMA Write] Request device [01:00.0] fault addr 0x0000000f3a210000 [fault reason 0x05] PTE Write access is not set

Ce que cela signifie : Vous observez des fautes pendant un reset. Certains périphériques se comportent mal pendant la transition.

Décision : Si les fautes sont corrélées strictement aux opérations de reset puis cessent, documentez-le et validez avec les recommandations du fournisseur. Si elles continuent, traitez comme un dysfonctionnement ou une compromission.

Blague #1 : Un périphérique PCIe sans IOMMU c’est comme donner la clé générale de votre appartement à votre bambin. Il va « aider », de façon créative.

Playbook de diagnostic rapide

Quand quelque chose sent mauvais — erreurs VFIO, corruptions aléatoires, baisses de performance inattendues — ne creusez pas pendant des heures. Utilisez une
séquence qui réduit rapidement le domaine de la défaillance. Voici le playbook que je garde en tête.

Première étape : l’IOMMU est-elle réellement activée et appliquée ?

  • Vérifiez /proc/cmdline pour intel_iommu=on ou amd_iommu=on, et méfiez-vous des valeurs risquées comme iommu=pt.
  • Vérifiez dmesg pour « IOMMU enabled » et « Interrupt remapping enabled. »
  • Vérifiez que /sys/kernel/iommu_groups/ existe.

Si cela manque, arrêtez-vous. Corrigez le firmware + les paramètres du noyau. Tout le reste est du bruit.

Deuxième étape : votre isolation de périphérique est-elle réelle (groupes et topologie) ?

  • Listez les groupes IOMMU et confirmez que le périphérique ciblé n’est pas groupé avec des périphériques non liés.
  • Vérifiez si ACS est présent/fonctionnel ; si non, ne prétendez pas avoir de l’isolation.

Si le groupement est trop grossier, votre « plan de passthrough » est en fait un plan pour partager des frontières de confiance.

Troisième étape : y a-t-il des fautes IOMMU ou des échecs de mapping ?

  • Cherchez dans les logs des fautes DMAR/AMD-Vi.
  • Si des fautes existent : identifiez le périphérique par BDF, vérifiez les versions de pilote et firmware, corrélez avec les resets et les pics de charge.

Les fautes fréquentes ne sont pas « normales ». Elles sont soit un bug, soit une mauvaise configuration, soit un périphérique à retirer.

Quatrième étape : si le problème est de la performance, mesurez le vrai point de pression

  • Vérifiez si vous utilisez des hugepages là où cela a du sens.
  • Confirmez le DMA mask du périphérique (les limites 32-bit entraînent du bounce buffering).
  • Confirmez les paramètres de strictness IOMMU et envisagez un réglage ciblé plutôt que le passthrough global.

Erreurs courantes : symptôme → cause racine → correction

Voici les schémas que je vois de façon répétée, même dans des environnements « matures ». La plupart sont évitables si vous traitez l’IOMMU comme
partie de votre baseline, pas comme un projet spécial.

1) VFIO indique « No IOMMU detected »

Symptôme : Le passthrough VM échoue ; les logs se plaignent du manque de support IOMMU.

Cause racine : VT-d/AMD-Vi désactivé dans le BIOS/UEFI, ou paramètres de boot noyau manquants/incorrects.

Correction : Activez VT-d/AMD-Vi dans le firmware ; ajoutez intel_iommu=on ou amd_iommu=on ; vérifiez via dmesg qu’elle s’est initialisée.

2) Le passthrough fonctionne, mais l’isolation est factice

Symptôme : Vous pouvez assigner un périphérique, mais il partage un groupe IOMMU avec des composants chipset ou d’autres périphériques.

Cause racine : La topologie PCIe ne supporte pas l’isolation (pas d’ACS, ou ports downstream partagés).

Correction : Utilisez des emplacements différents, ajoutez des switches PCIe avec support ACS, ou changez de plateforme. Ne livrez pas des hacks d’ACS override comme « sécurité ».

3) Corruption mémoire aléatoire sous forte I/O

Symptôme : Kernel panics, corruption d’allocation, crashes étranges qui ressemblent à de la RAM défectueuse.

Cause racine : L’IOMMU en mode passthrough/identité masque les bugs DMA ; le périphérique écrit hors limites.

Correction : Activez l’IOMMU stricte ; mettez à jour pilote/firmware ; réduisez les réglages agressifs qui augmentent les conditions de race (profondeur de queue, tempêtes de reset).

4) Le boot plante ou des périphériques disparaissent en activant l’IOMMU

Symptôme : Le système devient instable après activation de l’IOMMU ; certains périphériques échouent à s’initialiser.

Cause racine : Bugs de firmware, noyaux anciens, ou périphériques supposant un mapping identité.

Correction : Mettez à jour le BIOS/UEFI ; mettez à jour le noyau ; envisagez des quirks par périphérique plutôt que de désactiver l’IOMMU globalement. Si un périphérique ne peut pas coexister avec l’IOMMU, questionnez ce périphérique.

5) « Nous avons activé l’IOMMU, donc Thunderbolt est sûr »

Symptôme : La revue de sécurité valide le risque Thunderbolt sans vérifier la politique d’autorisation OS.

Cause racine : Confusion entre isolation DMA et autorisation d’accès au bus. L’IOMMU restreint la mémoire, mais ne décide pas qui monte sur le bus.

Correction : Appliquez les niveaux de sécurité Thunderbolt et l’autorisation OS ; désactivez les ports PCIe externes quand non nécessaires ; gardez l’IOMMU activée.

6) Régression de performance imputée à l’IOMMU sans preuve

Symptôme : Le débit chute ; quelqu’un propose iommu=pt ou de désactiver l’IOMMU.

Cause racine : Goulot non mesuré : petits mappings de pages, IOTLB misses, DMA mask 32-bit, ou tailles de queues sous-optimales.

Correction : Mesurez d’abord ; utilisez des hugepages quand approprié ; ajustez par périphérique ; conservez l’application pour le reste.

Blague #2 : Désactiver l’IOMMU pour « améliorer les performances » c’est comme enlever les freins pour « réduire le poids ». Ça fonctionne jusqu’au jour où ça ne marche plus.

Listes de contrôle / plan étape par étape

Checklist durcissement baseline (flotte / datacenter)

  1. Firmware : Activez VT-d (Intel) ou AMD-Vi (AMD). Activez le remappage d’interruptions si option séparée.
  2. Kernel cmdline : Configurez intel_iommu=on ou amd_iommu=on. Évitez iommu=pt global sauf si vous avez une raison et une liste d’exceptions.
  3. Vérification : Exigez un check au démarrage : dmesg contient « IOMMU enabled » et « Interrupt remapping enabled. »
  4. Inventaire : Collectez les cartes des groupes IOMMU par SKU matériel. Stockez-les dans la connaissance plateforme.
  5. Quarantaine : Les hôtes sans IOMMU activée ne font pas tourner de workloads nécessitant passthrough, SR-IOV, ou isolation mémoire à haute confiance.
  6. Logging : Alertez sur les fautes IOMMU répétées, pas sur le bruit isolé. La répétition sent le bug réel.

Checklist poste de travail sécurisé (Thunderbolt / docks / eGPU)

  1. Activez l’IOMMU dans le firmware et vérifiez via les logs.
  2. Verrouillez les ports PCIe externes quand vous voyagez ou êtes dans des environnements hostiles.
  3. Utilisez des politiques d’autorisation de périphériques pour Thunderbolt ; ne faites pas confiance automatiquement aux nouveaux périphériques.
  4. Supposez que les états sleep/hibernate modifient la posture de menace. Validez votre position à travers suspend/resume.
  5. Si vous manipulez des secrets (clés, credentials), envisagez le chiffrement mémoire si disponible — mais ne le considérez pas comme un substitut à l’IOMMU.

Plan étape par étape Virtualisation / VFIO (faire correctement)

  1. Prouvez que l’IOMMU est activée : vérifiez /proc/cmdline et dmesg.
  2. Mappez les groupes IOMMU : assurez-vous que le périphérique cible est dans un groupe propre que vous pouvez passer entièrement.
  3. Attachez le périphérique à vfio-pci : confirmez avec lspci -nnk.
  4. Démarrez la VM : regardez journalctl -k -f pour les erreurs VFIO et IOMMU.
  5. Validez sous charge : lancez un stress I/O ; surveillez les fautes DMAR/AMD-Vi.
  6. Décidez du niveau de strictness : conservez le mode strict pour la sécurité et la correction ; ne relâchez que si vous avez mesuré et mis en place des contrôles compensatoires.

FAQ

1) Si j’ai le chiffrement complet du disque, pourquoi les attaques DMA sont-elles importantes ?

Le chiffrement de disque protège les données au repos. Les attaques DMA ciblent la RAM : blocs de disque déchiffrés dans le cache, clés de session,
credentials, structures noyau. Si le système tourne, la RAM est le prix à payer.

2) L’activation de l’IOMMU ralentit-elle mon système ?

Cela peut, selon la charge et le périphérique. Pour beaucoup de charges générales, la surcharge est faible. Pour des NICs haut débit ou des accélérateurs spécialisés,
vous pouvez mesurer un coût notable si les mappings churnent ou si vous utilisez de petites pages. Mesurez avant de paniquer, et ajustez avant de désactiver.

3) Quelle est la différence entre VT-x/AMD-V et VT-d/AMD-Vi ?

VT-x/AMD-V sont des extensions de virtualisation CPU (exécuter le code invité efficacement). VT-d/AMD-Vi sont des extensions de virtualisation E/S
(contenir le DMA des périphériques et permettre l’assignation sûre de périphériques). Vous avez souvent besoin des deux, mais ce ne sont pas les mêmes commutateurs.

4) Le mode « iommu=pt » est-il sûr ?

C’est un compromis. Il signifie souvent que les périphériques utilisent des mappings identité par défaut, ce qui peut réduire la surcharge mais aussi réduire
la contention pour des périphériques qui n’utilisent pas l’API DMA de façon contrôlée. Sur des hôtes sensibles, préférez le comportement strict/par défaut
et appliquez le passthrough seulement quand vous pouvez le justifier.

5) Que sont les groupes IOMMU et pourquoi faut-il s’en soucier ?

Les groupes représentent l’ensemble minimal de périphériques pouvant être isolés les uns des autres selon le routage matériel et ACS.
Si deux périphériques partagent un groupe, considérez qu’ils ne peuvent pas être séparés pour le passthrough. Si vous ignorez cela, vous construisez
une frontière de sécurité basée sur l’espoir.

6) Un périphérique PCIe malveillant peut-il contourner une IOMMU activée ?

Pas dans le sens simple « DMA partout », en supposant du matériel et une configuration corrects. Mais vous pouvez toujours perdre si :
vous mappez trop de mémoire au périphérique, un bug firmware de plateforme sape l’isolation, ou l’attaquant exploite des buffers autorisés et des failles logiques de niveau supérieur.
L’IOMMU réduit le radius d’impact ; elle ne remplace pas la discipline de conception.

7) Ai-je aussi besoin du remappage d’interruptions ?

Oui quand il est disponible. Le DMA est le risque évident, mais les interruptions sont un autre canal par lequel les périphériques peuvent affecter le système.
Le remappage d’interruptions aide à empêcher les périphériques de cibler des vecteurs d’interruption inattendus. C’est à la fois sécurité et stabilité.

8) Pourquoi je vois des fautes IOMMU pendant le reset d’un périphérique ?

Certains périphériques effectuent des transactions de type DMA ou des écritures obsolètes pendant les transitions de reset. Une IOMMU stricte peut les signaler.
Si elles sont rares et strictement corrélées au reset, cela peut être un quirk connu. Si elles se répètent sous charge, traitez comme un bug ou une mauvaise configuration et escaladez.

9) Le SR-IOV est-il sûr sans IOMMU ?

Ne faites pas ça. SR-IOV expose des fonctions virtuelles qui peuvent DMA. L’IOMMU fait partie du modèle de sécurité qui empêche les locataires
de se toucher entre eux et d’atteindre l’hôte.

10) Comment cela se rapporte-t-il aux fonctionnalités de chiffrement mémoire ?

Le chiffrement mémoire (dépendant de la plateforme) peut réduire la valeur du contenu RAM volé dans certains scénarios, mais le DMA peut toujours
être utilisé pour corrompre la mémoire, et le chiffrement ne couvre peut-être pas tous les chemins DMA ou buffers visibles par le périphérique comme vous le supposez.
Conservez l’IOMMU comme baseline quoi qu’il arrive.

Prochaines étapes réalisables cette semaine

Vous n’avez pas besoin d’un labo, d’un budget, ou d’une initiative sécurité de trois mois pour améliorer la posture DMA. Il vous faut quelques
vérifications ennuyeuses et la volonté de les faire appliquer.

  1. Choisissez trois machines représentatives (serveur, poste de travail, hôte de virtualisation) et exécutez les tâches pratiques ci‑dessus. Sauvegardez les sorties.
  2. Standardisez les réglages firmware pour VT-d/AMD-Vi et le remappage d’interruptions. Traitez les écarts comme non conformes.
  3. Mettez en place une barrière sur le log de boot : si le noyau ne déclare pas IOMMU et remappage activés, l’hôte ne fait pas tourner de workloads sensibles.
  4. Inventoriez les groupes IOMMU par modèle matériel avant d’acheter plus de cette référence. Si vous ne pouvez pas isoler ce dont vous avez besoin, vous achetez de la douleur future.
  5. Décidez du strict vs passthrough intentionnellement. Par défaut strict. Autorisez des exceptions par périphérique seulement avec un besoin mesuré et un modèle de menace écrit.
  6. Alertez sur les fautes IOMMU répétées et traitez-les comme vous le feriez pour des erreurs ECC répétées : le système vous dit que quelque chose est cassé.

Si vous retenez une règle opérationnelle : ne faites pas confiance à un contrôle de sécurité que vous ne pouvez pas vérifier par une commande et une ligne de log.
Le DMA est trop puissant pour une configuration basée sur les impressions.

← Précédent
Performance Frontend : Core Web Vitals sans mythes — Ce qui fait la différence
Suivant →
Compte local sur Windows 11 : éviter le piège du compte Microsoft

Laisser un commentaire