Prevent DMA attacks over the LPC bus
The LPC bus is an internal bus in x86 computers connected to the SuperIO which connects various low-speed legacy devices. Unfortunately it also is a vector of DMA attacks, which cannot be mitigated by blacklisting kernel modules in the way Firewire or Thunderbolt can. Any device attached to the LPC bus can send specific signals to the host. One of these signals is called LDRQ#, or “Bus master request”. A device which is bus master can DMA into the host memory. Even though LPC is slow and DMA is limited to about 4 MiB/s read, 6 MiB/s write, that’s plenty to identify kernel structures and overwrite them with shellcode. There are public PoCs which do that already, and law enforcement has already used similar tools.
I believe this is an issue for Tails, both because many people are requesting a lock screen (and it’s likely that one will be added), and because an attacker who gains physical access to an unlocked machine should not be able to get access to raw memory (bugs allowing going back to the greeter screen to enter a new password aside). Because of this, and because #11581 seems in scope, I think it should be within Tails’ threat model to defend from this vector of attack. I don’t believe blacklisting the kernel module it typically uses (lpc_ich) would have any effect on its ability to abuse LDRQ# requests, so a more complex solution than blacklisting the kernel module is required.
There are a few ways I can think of to defend from this. The simplest way I can think of is to load the VFIO kernel module, remove any drivers associated with the LPC bus, and bind the LPC bus’ PCI ID to the VFIO stub driver. This should effectively disable its DMA ability. Obviously, computers without an IOMMU will not be able to do this, and computers with an IOMMU that does not support interrupt remapping or with x2apic disabled in the BIOS may or may not be able to do this effectively. For computers with modern IOMMUs, which are probably the majority of machines running Tails, this technique should eliminate the LPC as a DMA vector, with no regressions or drawbacks of any kind.
The overview of the process should be as simple as:
1) make sure the host has an IOMMU
2) locate LPC bus PCI ID and make sure it is in its own IOMMU group
3) load necessary VFIO drivers
4) unbind any driver the LPC bus is using
5) bind vfio-pci to the LPC bus
Information on LDRQ# (see sections 6 and 7):