Capture shadow stack region if available

Where shadow stacks are available, capture the entire shadow stack page
unconditionally.

Bug: 1250098
Change-Id: I5e2273c19b5f2d571195ff1252396df7dd70566a
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3493684
Commit-Queue: Alex Gough <ajgo@chromium.org>
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Alex Gough 2022-05-16 16:16:07 -07:00 committed by Crashpad LUCI CQ
parent 9ef737a26d
commit d8567ffc53
2 changed files with 21 additions and 5 deletions

View File

@ -90,10 +90,7 @@ void CaptureMemory::PointedToByContext(const CPUContext& context,
MaybeCaptureMemoryAround(delegate, context.x86_64->r14);
MaybeCaptureMemoryAround(delegate, context.x86_64->r15);
MaybeCaptureMemoryAround(delegate, context.x86_64->rip);
// Shadow stack region.
if (context.x86_64->xstate.enabled_features & XSTATE_MASK_CET_U) {
MaybeCaptureMemoryAround(delegate, context.x86_64->xstate.cet_u.ssp);
}
// Note: Shadow stack region is directly captured.
} else {
MaybeCaptureMemoryAround(delegate, context.x86->eax);
MaybeCaptureMemoryAround(delegate, context.x86->ebx);

View File

@ -18,6 +18,8 @@
#include <vector>
#include "base/check_op.h"
#include "base/memory/page_size.h"
#include "base/numerics/safe_conversions.h"
#include "snapshot/capture_memory.h"
#include "snapshot/win/capture_memory_delegate_win.h"
#include "snapshot/win/cpu_context_win.h"
@ -28,6 +30,7 @@ namespace internal {
namespace {
#if defined(ARCH_CPU_X86_64)
XSAVE_CET_U_FORMAT* LocateXStateCetU(CONTEXT* context) {
// GetEnabledXStateFeatures needs Windows 7 SP1.
static auto locate_xstate_feature = []() {
@ -98,7 +101,7 @@ bool ThreadSnapshotWin::Initialize(
// then this will not set any state in the context snapshot.
if (IsXStateFeatureEnabled(XSTATE_MASK_CET_U)) {
XSAVE_CET_U_FORMAT* cet_u = LocateXStateCetU(context);
if (cet_u) {
if (cet_u && cet_u->Ia32CetUMsr && cet_u->Ia32Pl3SspMsr) {
InitializeX64XStateCet(context, cet_u, context_.x86_64);
}
}
@ -117,6 +120,22 @@ bool ThreadSnapshotWin::Initialize(
#error Unsupported Windows Arch
#endif // ARCH_CPU_X86
#if defined(ARCH_CPU_X86_64)
// Unconditionally store page around ssp if it is present.
if (process_reader->Is64Bit() && context_.x86_64->xstate.cet_u.ssp) {
WinVMAddress page_size =
base::checked_cast<WinVMAddress>(base::GetPageSize());
WinVMAddress page_mask = ~(page_size - 1);
WinVMAddress ssp_base = context_.x86_64->xstate.cet_u.ssp & page_mask;
if (process_reader->GetProcessInfo().LoggingRangeIsFullyReadable(
CheckedRange<WinVMAddress, WinVMSize>(ssp_base, page_size))) {
auto region = std::make_unique<MemorySnapshotGeneric>();
region->Initialize(process_reader->Memory(), ssp_base, page_size);
pointed_to_memory_.push_back(std::move(region));
}
}
#endif // ARCH_CPU_X86_64
CaptureMemoryDelegateWin capture_memory_delegate(
process_reader,
thread_,