From: "Mario Limonciello (AMD)" <superm1@kernel.org>
To: "Joerg Roedel (AMD)" <joro@8bytes.org>,
Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
Nicolas Bouchinet <nicolas.bouchinet@oss.cyber.gouv.fr>,
Xiu Jianfeng <xiujianfeng@huawei.com>,
Paul Moore <paul@paul-moore.com>,
James Morris <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>
Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org,
"Mario Limonciello (AMD)" <superm1@kernel.org>
Subject: [PATCH 2/2] security: lockdown: Prevent boot with lockdown but no IOMMU
Date: Mon, 02 Nov 2026 08:00:26 -0600 [thread overview]
Message-ID: <20261102-lockdown-iommu-v1-2-00f3c2be4c9f@kernel.org> (raw)
In-Reply-To: <20261102-lockdown-iommu-v1-0-00f3c2be4c9f@kernel.org>
Lockdown is a kernel LSM that restricts access to sensitive kernel
resources (e.g. /dev/mem, kernel modules, perf, tracing, kprobes,
BPF access to kernel memory). However, without IOMMU, any PCI/PCIe
device can perform DMA to arbitrary physical memory, effectively
bypassing all lockdown protections.
A malicious or compromised device can:
- Read kernel memory directly (encryption keys, credentials, secrets)
- Write to kernel memory directly (code patches, rootkits, backdoors)
- Circumvent all lockdown LSM checks (which run inside the kernel)
Add a two-phase check to prevent booting with lockdown enabled and
IOMMU disabled:
1. Early check (in lockdown_lsm_init()): On x86, check the no_iommu
flag, which is set early by the 'iommu=off' kernel cmdline option.
If lockdown is active and no_iommu is set, panic with a clear error.
2. Late check (late_initcall): On all architectures, check
iommu_is_available() which returns true if any IOMMU driver
registered successfully. This catches cases where:
- IOMMU hardware is absent on the platform
- IOMMU was disabled by driver initialization failure
- IOMMU was not detected (broken firmware, missing ACPI tables)
This follows the precedent set by s390 UV code which panics when
security cannot be guaranteed ("System security cannot be guaranteed
unless the system panics now").
Also update iommu_device_register() to call iommu_set_available() on
successful registration, so all IOMMU drivers automatically signal
their availability.
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
---
security/lockdown/lockdown.c | 65 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 8d46886d2cca0..6ce1490188d5d 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -13,8 +13,14 @@
#include <linux/security.h>
#include <linux/export.h>
#include <linux/lsm_hooks.h>
+#include <linux/init.h>
#include <uapi/linux/lsm.h>
+#if IS_ENABLED(CONFIG_X86)
+#include <asm/iommu.h>
+#endif
+#include <linux/iommu.h>
+
static enum lockdown_reason kernel_locked_down;
static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
@@ -88,6 +94,25 @@ static int __init lockdown_lsm_init(void)
#elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY)
lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);
#endif
+
+ /*
+ * If lockdown was activated (via command line or kernel config)
+ * and IOMMU is disabled, refuse to boot. Without IOMMU, any
+ * PCI/PCIe device can perform DMA to arbitrary physical memory,
+ * completely bypassing lockdown protections.
+ *
+ * On x86, 'no_iommu' is set early by the 'iommu=off' cmdline
+ * option during parse_early_param(), before this init function.
+ */
+#if IS_ENABLED(CONFIG_X86)
+ if (kernel_locked_down > LOCKDOWN_NONE && no_iommu) {
+ pr_err("FATAL: Lockdown is active but IOMMU is disabled.\n");
+ pr_err("FATAL: PCI devices can perform DMA to arbitrary memory,\n");
+ pr_err("FATAL: bypassing all lockdown protections.\n");
+ panic("Lockdown enabled but IOMMU is disabled (no_iommu)\n");
+ }
+#endif
+
security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),
&lockdown_lsmid);
return 0;
@@ -170,3 +195,43 @@ DEFINE_LSM(lockdown) = {
.init = lockdown_lsm_init,
.initcall_core = lockdown_secfs_init,
};
+
+/*
+ * Late init call to verify IOMMU availability when lockdown is active.
+ * This catches cases where:
+ * - IOMMU hardware is absent on the platform
+ * - IOMMU was disabled by driver initialization failure
+ * - IOMMU was not detected (e.g. broken firmware, missing ACPI tables)
+ *
+ * On x86, we also check no_iommu here as a double-check. The early check
+ * in lockdown_lsm_init() catches 'iommu=off' from the cmdline before
+ * lockdown_lsm_init() runs, but this late check covers any missed cases.
+ */
+static int __init lockdown_check_iommu(void)
+{
+ if (kernel_locked_down > LOCKDOWN_NONE) {
+ /*
+ * Check generic IOMMU availability (all architectures).
+ * iommu_is_available() returns true if any IOMMU driver
+ * registered successfully.
+ */
+ if (!iommu_is_available()) {
+ pr_err("FATAL: Lockdown is active but no IOMMU driver\n");
+ pr_err("FATAL: registered. PCI devices can DMA to\n");
+ pr_err("FATAL: arbitrary memory, bypassing lockdown.\n");
+ panic("Lockdown enabled but IOMMU not available\n");
+ }
+#if IS_ENABLED(CONFIG_X86)
+ /*
+ * Also double-check x86-specific flag.
+ */
+ if (no_iommu) {
+ pr_err("FATAL: Lockdown is active but IOMMU disabled\n");
+ pr_err("FATAL: via kernel command line (iommu=off).\n");
+ panic("Lockdown enabled but IOMMU disabled (iommu=off)\n");
+ }
+#endif
+ }
+ return 0;
+}
+late_initcall(lockdown_check_iommu);
--
2.53.0
prev parent reply other threads:[~2026-11-02 14:00 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 14:00 [PATCH 0/2] lockdown: Prevent booting with lockdown enabled but IOMMU disabled Mario Limonciello (AMD)
2026-11-02 14:00 ` [PATCH 1/2] iommu: Add iommu_is_available() API Mario Limonciello (AMD)
2026-11-02 14:00 ` Mario Limonciello (AMD) [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261102-lockdown-iommu-v1-2-00f3c2be4c9f@kernel.org \
--to=superm1@kernel.org \
--cc=iommu@lists.linux.dev \
--cc=jmorris@namei.org \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=nicolas.bouchinet@oss.cyber.gouv.fr \
--cc=paul@paul-moore.com \
--cc=robin.murphy@arm.com \
--cc=serge@hallyn.com \
--cc=will@kernel.org \
--cc=xiujianfeng@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®