Kernel DMA Protection helps keep your computer secure by mediating all Thunderbolt Direct Memory Access operations through an IOMMU. Many systems produced after 2013 have an IOMMU, but their BIOS does not enable Kernel DMA Protection. In the absence of vendor BIOS updates retroactively adding this protection, this leaves about 9 years worth of systems vulnerable to Thunderspy forever. This project aims to bring Kernel DMA Protection to systems that do not ship Kernel DMA Protection, but are in fact technically capable.
In our vulnerability disclosure procedure for Thunderspy, Intel has stated that Kernel DMA Protection mitigates the Thunderspy vulnerabilities. While this protection may address the DMA attack vector portion of Thunderspy, it is only available on a limited number of systems shipping since 2019. Hence, all systems released between 2011-2019, and more recent systems that do not ship Kernel DMA Protection, will remain fully vulnerable to Thunderspy forever.
Starting from Haswell (2013), a lot of Intel CPUs are IOMMU-equipped. Hence, systems shipping these CPUs should technically be capable of supporting DMA remapping Thunderbolt devices through Kernel DMA Protection. However, in the absence of vendor BIOS updates, this protection has never been available for any pre-2019 systems.
As part of our on-going research, we present two options that aim to bring Kernel DMA Protection to Thunderbolt-equipped systems that do not ship Kernel DMA Protection, but do satisfy all hardware and firmware requirements. These options currently include:
- kdmap-patcher: An experimental, OS-agnostic UEFI extension that serves as a drop-in patch requiring no changes to the operating system. Access the project repo.
- Upgrading ACPI tables via initrd (this document): A guide outlining how to manually patch the ACPI DMAR table on Linux.
-
Obtain a raw dump of your system's DMAR table:
# cat /sys/firmware/acpi/tables/DMAR > /tmp/dmar.bin
-
Obtain
acpica-tools
using your distro's package manager. For example, on Debian/Ubuntu:# apt-get install acpica-tools
-
Run iasl on the raw dump:
$ iasl -d /tmp/dmar.bin Intel ACPI Component Architecture ASL+ Optimizing Compiler/Disassembler version 20200528 Copyright (c) 2000 - 2020 Intel Corporation File appears to be binary: found 133 non-ASCII characters, disassembling Binary file appears to be a valid ACPI table, disassembling Input file dmar.bin, Length 0xA8 (168) bytes ACPI: DMAR 0x0000000000000000 0000A8 (v01 INTEL EDK2 00000003 INTL 20200528) Acpi Data Table [DMAR] decoded Formatted output: dmar.dsl - 4997 bytes
-
Using your favorite text editor, open
dmar.dsl
. The output should look similar to the following:$ cat /tmp/dmar.dsl /* * Intel ACPI Component Architecture * AML/ASL+ Disassembler version 20180105 (64-bit version) * Copyright (c) 2000 - 2018 Intel Corporation * * Disassembly of dmar-org.bin, Sun Apr 5 15:51:13 2020 * * ACPI Data Table [DMAR] * * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue */ [000h 0000 4] Signature : "DMAR" [DMA Remapping table] [004h 0004 4] Table Length : 000000A8 [008h 0008 1] Revision : 01 [009h 0009 1] Checksum : F5 [00Ah 0010 6] Oem ID : "INTEL " [010h 0016 8] Oem Table ID : "EDK2 " [018h 0024 4] Oem Revision : 00000002 [01Ch 0028 4] Asl Compiler ID : " " [020h 0032 4] Asl Compiler Revision : 01000013 [024h 0036 1] Host Address Width : 26 [025h 0037 1] Flags : 01 [026h 0038 10] Reserved : 00 00 00 00 00 00 00 00 00 00 [030h 0048 2] Subtable Type : 0000 [Hardware Unit Definition] [032h 0050 2] Length : 0018 (..snip..)
-
The
Flags
attribute on offset 25h denotes which DMA remapping features have been enabled. For Kernel DMA Protection to function, we need both interrupt remapping and DMA control platform opt-in to be enabled. To assert these bits, changeFlags
value to05
. -
Increase the
Oem Revision
value to have the kernel apply the modified table. For example, change00000002
to00000003
. -
Compile the DMAR table:
$ iasl /tmp/dmar.dsl Intel ACPI Component Architecture ASL+ Optimizing Compiler/Disassembler version 20200528 Copyright (c) 2000 - 2020 Intel Corporation Table Input: dmar.dsl - 4975 bytes 66 fields 104 source lines Binary Output: dmar.aml - 168 bytes
-
To use the custom DMAR table, create a CPIO archive that is loaded by your bootloader. This is a one-time procedure; updating the kernel will not make it necessary to repeat these steps. First, create the following folder structure:
$ mkdir -p kernel/firmware/acpi
-
Copy the patched DMAR table into the just created folder. For example:
$ cp dmar.aml kernel/firmware/acpi
-
Within the same folder where the newly created
kernel/
folder resides, create the CPIO archive containing the patched DMAR table:$ find kernel | cpio -H newc --create > acpi_override
-
Copy the CPIO archive to the boot directory:
# cp acpi_override /boot
-
Finally, configure your bootloader to load the CPIO archive.
-
If using GRUB2, create a file
/etc/grub.d/09_custom
with these contents (adjust as necessary):#!/bin/sh exec tail -n +3 $0 # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. menuentry 'Ubuntu' { linux (hd0,msdos1)/vmlinuz root=/dev/sda1 initrd /acpi_override initrd (hd0,msdos1)/initrd.img }
-
If using systemd-boot, update
/boot/loader/entries/arch.conf
to (adjust as necessary):title Arch Linux linux /vmlinuz-linux initrd /acpi_override initrd /initramfs-linux.img options root=PARTUUID=ec9d5998-a9db-4bd8-8ea0-35a45df04701 resume=PARTUUID=58d0aa86-d39b-4fe1-81cf-45e7add275a0 ...
-
-
Reboot and verify the result:
- Run
$ dmesg | grep ACPI
and look for clues that suggest a DMAR table override. - Observe that
cat /sys/bus/thunderbolt/devices/domain0/iommu_dma_protection
returns the value 1. All done!
- Run
Special thanks to the Arch Linux wiki, on which steps 9-13 are based.