lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed,  6 Feb 2013 19:08:24 -0800
From:	Andy Lutomirski <luto@...capital.net>
To:	unlisted-recipients:; (no To-header on input)
Cc:	Gleb Natapov <gleb@...hat.com>,
	LKML <linux-kernel@...r.kernel.org>, x86@...nel.org,
	"H. Peter Anvin" <hpa@...or.com>,
	Andy Lutomirski <luto@...capital.net>,
	Alex Williamson <alex.williamson@...hat.com>,
	Don Zickus <dzickus@...hat.com>,
	Prarit Bhargava <prarit@...hat.com>,
	David Woodhouse <dwmw2@...radead.org>
Subject: [PATCH] intel_iommu: Disable vfio and kvm interrupt assignment when unsafe

We currently report IOMMU_CAP_INTR_REMAP whenever interrupt remapping
is enabled.  Users of that capability expect it to mean that remapping
is secure (i.e. compatibility format interrupts are blocked).  Explicitly
check whether CFIs are blocked and, if not, don't report the capability.

Cc: Alex Williamson <alex.williamson@...hat.com>
Cc: Don Zickus <dzickus@...hat.com>
Cc: Prarit Bhargava <prarit@...hat.com>
Cc: David Woodhouse <dwmw2@...radead.org>
Signed-off-by: Andy Lutomirski <luto@...capital.net>
---

This applies on top of my previous patch:

http://git.kernel.org/tip/af8d102f999a41c0189bd2cce488bac2ee88c29b

This is poorly tested.  My x2apic-opted-out server boots and appears
to work.  My x2apic-supporting server is busy doing production
things, so I can't reboot it to test.  I don't have anything that
uses vfio or kvm device assignment.

 drivers/iommu/intel-iommu.c         |  9 +++++++--
 drivers/iommu/intel_irq_remapping.c | 25 ++++++++++++++-----------
 include/linux/intel-iommu.h         |  7 +++++++
 3 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c2c07a4..b764117 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4129,8 +4129,13 @@ static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
 
 	if (cap == IOMMU_CAP_CACHE_COHERENCY)
 		return dmar_domain->iommu_snooping;
-	if (cap == IOMMU_CAP_INTR_REMAP)
-		return irq_remapping_enabled;
+	if (cap == IOMMU_CAP_INTR_REMAP) {
+		/*
+		 * This could be per-domain, but unless something's wrong,
+		 * we should have CFIs blocked on all domains.
+		 */
+		return irq_remapping_enabled && irq_remapping_is_secure;
+	}
 
 	return 0;
 }
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index eca8832..c7eda74 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -37,6 +37,7 @@ struct hpet_scope {
 static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
 static struct hpet_scope ir_hpet[MAX_HPET_TBS];
 static int ir_ioapic_num, ir_hpet_num;
+bool irq_remapping_is_secure;
 
 static DEFINE_RAW_SPINLOCK(irq_2_ir_lock);
 
@@ -436,10 +437,15 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode)
 	 * protected from dangerous (i.e. compatibility) interrupts
 	 * regardless of x2apic status.  Check just to be sure.
 	 */
-	if (sts & DMA_GSTS_CFIS)
+	if (sts & DMA_GSTS_CFIS) {
+		/* This should not happen unless the hardware is broken. */
 		WARN(1, KERN_WARNING
-			"Compatibility-format IRQs enabled despite intr remapping;\n"
-			"you are vulnerable to IRQ injection.\n");
+			"Failed to block compatibility format interrupts.\n");
+		iommu->cfi_blocked = false;
+	} else {
+		/* We are now secure against irq injection attack. */
+		iommu->cfi_blocked = true;
+	}
 
 	raw_spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
@@ -537,18 +543,15 @@ static int __init intel_irq_remapping_supported(void)
 static int __init intel_enable_irq_remapping(void)
 {
 	struct dmar_drhd_unit *drhd;
-	bool x2apic_present;
 	int setup = 0;
 	int eim = 0;
 
-	x2apic_present = x2apic_supported();
-
 	if (parse_ioapics_under_ir() != 1) {
 		printk(KERN_INFO "Not enable interrupt remapping\n");
 		goto error;
 	}
 
-	if (x2apic_present) {
+	if (x2apic_supported()) {
 		eim = !dmar_x2apic_optout();
 		if (!eim)
 			printk(KERN_WARNING
@@ -616,6 +619,7 @@ static int __init intel_enable_irq_remapping(void)
 	/*
 	 * Setup Interrupt-remapping for all the DRHD's now.
 	 */
+	irq_remapping_is_secure = 1;
 	for_each_drhd_unit(drhd) {
 		struct intel_iommu *iommu = drhd->iommu;
 
@@ -624,6 +628,8 @@ static int __init intel_enable_irq_remapping(void)
 
 		if (intel_setup_irq_remapping(iommu, eim))
 			goto error;
+		if (!iommu->cfi_blocked)
+			irq_remapping_is_secure = 0;
 
 		setup = 1;
 	}
@@ -641,10 +647,7 @@ error:
 	 * handle error condition gracefully here!
 	 */
 
-	if (x2apic_present)
-		WARN(1, KERN_WARNING
-			"Failed to enable irq remapping.  You are vulnerable to irq-injection attacks.\n");
-
+	irq_remapping_is_secure = 0;
 	return -1;
 }
 
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 78e2ada..85cb711 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -333,6 +333,7 @@ struct intel_iommu {
 
 #ifdef CONFIG_IRQ_REMAP
 	struct ir_table *ir_table;	/* Interrupt remapping info */
+	bool cfi_blocked;
 #endif
 	int		node;
 };
@@ -365,4 +366,10 @@ extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
 extern int dmar_ir_support(void);
 
+#ifdef CONFIG_IRQ_REMAP
+extern bool irq_remapping_is_secure;  /* Do all iommus block CFI? */
+#else
+#define irq_remapping_is_secure 0
+#endif
+
 #endif
-- 
1.8.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ