From f6e42357d412e6d24a6a637752ae126c15819c9b Mon Sep 17 00:00:00 2001 From: Alex Gough Date: Tue, 28 Mar 2023 22:47:20 +0000 Subject: [PATCH] Add maxsize for xstate areas Breakpad skips the xstate area in x64 contexts but allowed this area to be of unconstrained size. This hits problems if the size is greater than Chrome's maximum allocation size, so we change to skipping a maximum size. The maximum is chosen to allow the full set of states today, plus some slack for the future: Based on Intel x64 manual 13.5 XSAVE-MANAGED STATE * => further bytes might be reserved | Size | Region | | 576 | Legacy + header | | 384 | AVX State | | 80 | MPX State | | 1600 | AVX-512 State | | 72*| PT State | | 8 | pkru state | | 8 | pasid state | | 16 | CET state | | 8 | HDC State | | 96?| uintr state | | 808*| lbr state | | 8 | hwp state | | 16 | amx state | == 3680 so jump up a bit for the future to 2**12. Bug:1425631 Change-Id: Ie08555651977cdbfa1c351c661118f13238213c4 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4379497 Reviewed-by: Ivan Penkov --- src/processor/minidump.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 63f48ffe..45e4a524 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -76,6 +76,11 @@ using std::vector; namespace { +// Limit arrived at by adding up possible states in Intel Ch. 13.5 X-SAVE +// MANAGED STATE +// (~ 3680 bytes) plus some extra for the future. +const uint32_t kMaxXSaveAreaSize = 16384; + // Returns true iff |context_size| matches exactly one of the sizes of the // various MDRawContext* types. // TODO(blundell): This function can be removed once @@ -507,6 +512,10 @@ bool MinidumpContext::Read(uint32_t expected_size) { // sizeof(MDRawContextAMD64). For now we skip this extended data. if (expected_size > sizeof(MDRawContextAMD64)) { size_t bytes_left = expected_size - sizeof(MDRawContextAMD64); + if (bytes_left > kMaxXSaveAreaSize) { + BPLOG(ERROR) << "MinidumpContext oversized xstate area"; + return false; + } std::vector xstate(bytes_left); if (!minidump_->ReadBytes(xstate.data(), bytes_left)) {