Skip to content

Commit

Permalink
SpecuCheck v.1.1.0 Release -- L1TF and SSBD Support
Browse files Browse the repository at this point in the history
* Add detection of L1TF software and hardware mitigation support
* Add detection of SSBD software and hardware mitigation support
* Add detection of metldown-hardened Intel processors and existing AMD
processors
* Clarify that PCID support is now a separate optimization from INVPCID
usage
  • Loading branch information
ionescu007 committed Sep 29, 2018
1 parent 85e37fc commit 033ae8f
Showing 1 changed file with 128 additions and 13 deletions.
141 changes: 128 additions & 13 deletions specucheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION
ULONG IbrsPresent : 1;
ULONG StibpPresent : 1;
ULONG SmepPresent : 1;
ULONG SpeculativeStoreBypassDisableAvailable : 1;
ULONG SpeculativeStoreBypassDisableSupported : 1;
ULONG SpeculativeStoreBypassDisabledSystemWide : 1;
ULONG SpeculativeStoreBypassDisabledKernel : 1;
ULONG SpeculativeStoreBypassDisableRequired : 1;
ULONG BpbDisabledKernelToUser : 1;
ULONG SpecCtrlRetpolineEnabled : 1;
ULONG SpecCtrlImportOptimizationEnabled : 1;
ULONG Reserved : 24;
} SpeculationControlFlags;
} SYSTEM_SPECULATION_CONTROL_INFORMATION, *PSYSTEM_SPECULATION_CONTROL_INFORMATION;
Expand All @@ -60,7 +68,12 @@ typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION
ULONG KvaShadowUserGlobal : 1;
ULONG KvaShadowPcid : 1;
ULONG KvaShadowInvpcid : 1;
ULONG Reserved : 28;
ULONG KvaShadowRequired : 1;
ULONG KvaShadowRequiredAvailable : 1;
ULONG InvalidPteBit : 6;
ULONG L1DataCacheFlushSupported : 1;
ULONG L1TerminalFaultMitigationPresent : 1;
ULONG Reserved : 18;
} KvaShadowFlags;
} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION;
#pragma warning(pop)
Expand All @@ -74,9 +87,9 @@ BOOL g_SupportsAnsi;
// Welcome Banner
//
const WCHAR WelcomeString[] =
L"SpecuCheck v1.0.5 -- Copyright(c) 2018 Alex Ionescu\n"
L"https://ionescu007.github.io/SpecuCheck/ -- @aionescu\n"
L"-------------------------------------------------------\n\n";
L"SpecuCheck v1.1.0 -- Copyright(c) 2018 Alex Ionescu\n"
L"https://ionescu007.github.io/SpecuCheck/ -- @aionescu\n"
L"--------------------------------------------------------\n\n";

//
// Error String
Expand All @@ -90,25 +103,53 @@ const WCHAR UnpatchedString[] =
//
const WCHAR g_KvaStatusString[] =
L"%sMitigations for %sCVE-2017-5754 [rogue data cache load]%s\n"
L"-------------------------------------------------------\n"
L"--------------------------------------------------------\n"
L"[-] Kernel VA Shadowing Enabled: %s%s\n"
L" ├───> with User Pages Marked Global: %s%s\n"
L" └───> with PCID Flushing Optimization (INVPCID): %s%s\n\n";
L" ├───> Unnecessary due lack of CPU vulnerability: %s%s\n"
L" ├───> With User Pages Marked Global: %s%s\n"
L" ├───> With PCID Support: %s%s\n"
L" └───> With PCID Flushing Optimization (INVPCID): %s%s\n\n";

//
// L1Tf Status String
//
const WCHAR g_L1tfStatusString[] =
L"%sMitigations for %sCVE-2018-3620 [L1 terminal fault]%s\n"
L"--------------------------------------------------------\n"
L"[-] L1TF Mitigation Enabled: %s%s\n"
L" ├───> Unnecessary due lack of CPU vulnerability: %s%s\n"
L" ├───> CPU Microcode Supports Data Cache Flush: %s%s\n"
L" └───> With KVA Shadow and Invalid PTE Bit: %s%s\n\n";

//
// Speculation Control Status String
//
const WCHAR g_SpecControlStatusString[] =
L"%sMitigations for %sCVE-2017-5715 [branch target injection]%s\n"
L"-------------------------------------------------------\n"
L"--------------------------------------------------------\n"
L"[-] Branch Prediction Mitigations Enabled: %s%s\n"
L" ├───> Disabled due to System Policy (Registry): %s%s\n"
L" └───> Disabled due to Lack of Microcode Update: %s%s\n"
L" ├───> Disabled due to Lack of Microcode Update: %s%s\n"
L" └───> Disabled for kernel to user transitions: %s%s\n"
L"[-] Branch Prediction Mitigations Optimized: %s%s\n"
L" └───> With Import Address Table Optimization: %s%s\n"
L"[-] CPU Microcode Supports SPEC_CTRL MSR (048h): %s%s\n"
L" ───> Windows will use IBRS (01h): %s%s\n"
L" ───> Windows will use IBRS (01h): %s%s\n"
L" └───> Windows will use STIPB (02h): %s%s\n"
L"[-] CPU Microcode Supports PRED_CMD MSR (049h): %s%s\n"
L" └───> Windows will use IBPB (01h): %s%s\n";
L" └───> Windows will use IBPB (01h): %s%s\n\n";

//
// Speculation Control (2) Status String
//
const WCHAR g_SpecControlStatusString2[] =
L"%sMitigations for %sCVE-2018-3639 [speculative store bypass]%s\n"
L"--------------------------------------------------------\n"
L"[-] SSBD Mitigations Enabled: %s%s\n"
L" ├───> Disabled due to lack of OS Support: %s%s\n"
L" ├───> Disabled due to lack of Microcode Update: %s%s\n"
L" ├───> Disabled system-wide due to System Policy: %s%s\n"
L" └───> Disabled in kernel due to System Policy: %s%s\n";

//
// Error codes used for clarity
Expand Down Expand Up @@ -186,7 +227,7 @@ SpcMain (
SYSTEM_KERNEL_VA_SHADOW_INFORMATION kvaInfo;
SYSTEM_SPECULATION_CONTROL_INFORMATION specInfo;
SPC_ERROR_CODES errorCode;
WCHAR stateBuffer[1024];
WCHAR stateBuffer[2048];
INT charsWritten;

//
Expand All @@ -212,6 +253,7 @@ SpcMain (
g_SupportsAnsi = SetConsoleMode(hStdOut,
ENABLE_PROCESSED_OUTPUT |
ENABLE_VIRTUAL_TERMINAL_PROCESSING);
SetConsoleTitle(L"SpecuCheck v1.1.0");

//
// We now have display capabilities -- say hello!
Expand Down Expand Up @@ -260,9 +302,15 @@ SpcMain (
GetResetString(),
GetCyanString(),
GetResetString(),
kvaInfo.KvaShadowFlags.KvaShadowEnabled ?
((kvaInfo.KvaShadowFlags.KvaShadowEnabled) ||
((kvaInfo.KvaShadowFlags.KvaShadowRequiredAvailable) &&
!(kvaInfo.KvaShadowFlags.KvaShadowRequired))) ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
((kvaInfo.KvaShadowFlags.KvaShadowRequiredAvailable) &&
!(kvaInfo.KvaShadowFlags.KvaShadowRequired)) ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
kvaInfo.KvaShadowFlags.KvaShadowUserGlobal ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
Expand All @@ -274,6 +322,33 @@ SpcMain (
GetResetString());
WriteConsole(hStdOut, stateBuffer, charsWritten, NULL, NULL);

//
// Print status of L1TF Features
//
charsWritten = swprintf(stateBuffer,
ARRAYSIZE(stateBuffer),
g_L1tfStatusString,
GetResetString(),
GetCyanString(),
GetResetString(),
((kvaInfo.KvaShadowFlags.L1TerminalFaultMitigationPresent) ||
((kvaInfo.KvaShadowFlags.KvaShadowEnabled) &&
(kvaInfo.KvaShadowFlags.InvalidPteBit))) ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
((kvaInfo.KvaShadowFlags.KvaShadowRequiredAvailable) &&
!(kvaInfo.KvaShadowFlags.KvaShadowRequired)) ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
kvaInfo.KvaShadowFlags.L1DataCacheFlushSupported ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
((kvaInfo.KvaShadowFlags.KvaShadowEnabled) &&
(kvaInfo.KvaShadowFlags.InvalidPteBit)) ?
GetGreenYesString() : GetRedNoString(),
GetResetString());
WriteConsole(hStdOut, stateBuffer, charsWritten, NULL, NULL);

//
// Get the Speculation Control Information
//
Expand Down Expand Up @@ -318,6 +393,18 @@ SpcMain (
specInfo.SpeculationControlFlags.BpbDisabledNoHardwareSupport ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.BpbDisabledNoHardwareSupport ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.BpbDisabledKernelToUser ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpecCtrlRetpolineEnabled ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpecCtrlImportOptimizationEnabled ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpecCtrlEnumerated ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
Expand All @@ -335,6 +422,34 @@ SpcMain (
GetResetString());
WriteConsole(hStdOut, stateBuffer, charsWritten, NULL, NULL);

//
// Print status of Speculation Control SSBD Features
//
charsWritten = swprintf(stateBuffer,
ARRAYSIZE(stateBuffer),
g_SpecControlStatusString2,
GetResetString(),
GetCyanString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisableAvailable &&
(specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisableSupported ||
!specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisableRequired) ?
GetGreenYesString() : GetRedNoString(),
GetResetString(),
!specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisableAvailable ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
!specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisableSupported ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisabledSystemWide ?
GetRedYesString() : GetGreenNoString(),
GetResetString(),
specInfo.SpeculationControlFlags.SpeculativeStoreBypassDisabledKernel ?
GetRedYesString() : GetGreenNoString(),
GetResetString());
WriteConsole(hStdOut, stateBuffer, charsWritten, NULL, NULL);

//
// This is our happy path
//
Expand Down

0 comments on commit 033ae8f

Please sign in to comment.