Add fields for shadow stack registers to x64 snapshot

This will be used in a later CL to shuttle shadow stack information
from capture to minidumps. For now these fields are zeroed and have
no effect on any platform.

The x64 snapshot context we use no longer directly maps to the early
CONTEXT structure used by Windows (the prelude still matches). This
may cause confusion if people use the size of a snapshot context when
they meant to use sizeof(CONTEXT).

Bug: 1250098
Change-Id: Idac7d888b9e606ceb250c4027e0e7f29f4c0a55f
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3536963
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Alex Gough <ajgo@chromium.org>
This commit is contained in:
Alex Gough 2022-05-14 22:40:17 -07:00 committed by Crashpad LUCI CQ
parent a5b7e504c6
commit 25222891c7
3 changed files with 52 additions and 0 deletions

View File

@ -192,6 +192,35 @@ uint64_t CPUContext::StackPointer() const {
}
}
uint64_t CPUContext::ShadowStackPointer() const {
switch (architecture) {
case kCPUArchitectureX86:
case kCPUArchitectureARM:
case kCPUArchitectureARM64:
NOTREACHED();
return 0;
case kCPUArchitectureX86_64:
return x86_64->xstate.cet_u.ssp;
default:
NOTREACHED();
return ~0ull;
}
}
bool CPUContext::HasShadowStack() const {
switch (architecture) {
case kCPUArchitectureX86:
case kCPUArchitectureARM:
case kCPUArchitectureARM64:
return false;
case kCPUArchitectureX86_64:
return x86_64->xstate.cet_u.cetmsr != 0;
default:
NOTREACHED();
return false;
}
}
bool CPUContext::Is64Bit() const {
switch (architecture) {
case kCPUArchitectureX86_64:

View File

@ -257,6 +257,16 @@ struct CPUContextX86_64 {
uint64_t dr5; // obsolete, normally an alias for dr7
uint64_t dr6;
uint64_t dr7;
struct {
// If 0 then none of the xsave areas are valid.
uint64_t enabled_features;
// CET_U registers if XSTATE_CET_U bit is set in enabled_features.
struct {
uint64_t cetmsr;
uint64_t ssp;
} cet_u;
} xstate;
};
//! \brief A context structure carrying ARM CPU state.
@ -369,9 +379,19 @@ struct CPUContext {
//! context structure.
uint64_t StackPointer() const;
//! \brief Returns the shadow stack pointer value from the context structure.
//!
//! This is a CPU architecture-independent method that is capable of
//! recovering the shadow stack pointer from any supported CPU architectures
//! context structure.
uint64_t ShadowStackPointer() const;
//! \brief Returns `true` if this context is for a 64-bit architecture.
bool Is64Bit() const;
//! \brief Returns `true` if this context has an active shadow stack pointer.
bool HasShadowStack() const;
//! \brief The CPU architecture of a context structure. This field controls
//! the expression of the union.
CPUArchitecture architecture;

View File

@ -161,6 +161,9 @@ void InitializeCPUContextX86_64(CPUContext* context, uint32_t seed) {
context->x86_64->dr5 = value++;
context->x86_64->dr6 = value++;
context->x86_64->dr7 = value++;
// Make sure this is sensible. When supplied the size/state come from the OS.
memset(&context->x86_64->xstate, 0, sizeof(context->x86_64->xstate));
}
void InitializeCPUContextARM(CPUContext* context, uint32_t seed) {