summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Georgi <patrick@georgi-clan.de>2015-09-05 20:21:24 +0200
committerPatrick Georgi <pgeorgi@google.com>2015-10-29 10:27:00 +0100
commitce2564ac519fd974eeaa070ccb30d5a12e0c3334 (patch)
tree03be9390f1ce681e8b3f70a3d09daf4515faa4d2
parent6fecb7106ef6846e7f75cff59b8d2f9d7ed1109a (diff)
downloadcoreboot-ce2564ac519fd974eeaa070ccb30d5a12e0c3334.tar.gz
coreboot-ce2564ac519fd974eeaa070ccb30d5a12e0c3334.tar.bz2
coreboot-ce2564ac519fd974eeaa070ccb30d5a12e0c3334.zip
smmhandler: on i945..nehalem, crash if LAPIC overlaps with ASEG
This mitigates the Memory Sinkhole issue (described on https://github.com/xoreaxeaxeax/sinkhole) by checking for the issue and crashing the system explicitly if LAPIC overlaps ASEG. This needs to happen without a data access (only code fetches) because data accesses could be tampered with. Don't try to recover because, if somebody tried to do shenanigans like these, we have to expect more. Sandybridge is safe because it does the same test in hardware, and crashes. Newer chipsets presumably do the same. This needs to be extended to deal with overlapping TSEG as well. Change-Id: I508c0b10ab88779da81d18a94b08dcfeca6f5a6f Signed-off-by: Patrick Georgi <patrick@georgi-clan.de> Reviewed-on: http://review.coreboot.org/11519 Reviewed-by: Aaron Durbin <adurbin@chromium.org> Tested-by: build bot (Jenkins)
-rw-r--r--src/cpu/x86/Kconfig7
-rw-r--r--src/cpu/x86/smm/smmhandler.S39
2 files changed, 46 insertions, 0 deletions
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 9e5f6155fece..131cbf24bb36 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -89,6 +89,13 @@ config SMM_MODULE_HEAP_SIZE
This option determines the size of the heap within the SMM handler
modules.
+config SMM_LAPIC_REMAP_MITIGATION
+ bool
+ default y if NORTHBRIDGE_INTEL_I945
+ default y if NORTHBRIDGE_INTEL_GM45
+ default y if NORTHBRIDGE_INTEL_NEHALEM
+ default n
+
config X86_AMD_FIXED_MTRRS
bool
default n
diff --git a/src/cpu/x86/smm/smmhandler.S b/src/cpu/x86/smm/smmhandler.S
index 7b70ce9585a5..9cc6582ffea2 100644
--- a/src/cpu/x86/smm/smmhandler.S
+++ b/src/cpu/x86/smm/smmhandler.S
@@ -25,6 +25,10 @@
* to 64k if we can though.
*/
+#include <kconfig.h>
+#include <config.h>
+#define LAPIC_BASE_MSR 0x1b
+
/*
* +--------------------------------+ 0xaffff
* | Save State Map Node 0 |
@@ -74,8 +78,43 @@
*
* All the bad magic is not all that bad after all.
*/
+#define SMM_START 0xa0000
+#define SMM_END 0xb0000
+#if SMM_END <= SMM_START
+#error invalid SMM configuration
+#endif
.global smm_handler_start
smm_handler_start:
+#if IS_ENABLED(CONFIG_SMM_LAPIC_REMAP_MITIGATION)
+ /* Check if the LAPIC register block overlaps with SMM.
+ * This block needs to work without data accesses because they
+ * may be routed into the LAPIC register block.
+ * Code accesses, on the other hand, are never routed to LAPIC,
+ * which is what makes this work in the first place.
+ */
+ mov $LAPIC_BASE_MSR, %ecx
+ rdmsr
+ and $(~0xfff), %eax
+ sub $(SMM_START), %eax
+ cmp $(SMM_END - SMM_START), %eax
+ ja untampered_lapic
+1:
+ /* emit "Crash" on serial */
+ mov $(CONFIG_TTYS0_BASE), %dx
+ mov $'C', %al
+ out %al, (%dx)
+ mov $'r', %al
+ out %al, (%dx)
+ mov $'a', %al
+ out %al, (%dx)
+ mov $'s', %al
+ out %al, (%dx)
+ mov $'h', %al
+ out %al, (%dx)
+ /* now crash for real */
+ ud2
+untampered_lapic:
+#endif
movw $(smm_gdtptr16 - smm_handler_start + SMM_HANDLER_OFFSET), %bx
data32 lgdt %cs:(%bx)