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 <ivanpe@chromium.org>
This commit is contained in:
Alex Gough 2023-03-28 22:47:20 +00:00 committed by Ivan Penkov
parent 4d8bb33976
commit f6e42357d4

View file

@ -76,6 +76,11 @@ using std::vector;
namespace { 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 // Returns true iff |context_size| matches exactly one of the sizes of the
// various MDRawContext* types. // various MDRawContext* types.
// TODO(blundell): This function can be removed once // 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. // sizeof(MDRawContextAMD64). For now we skip this extended data.
if (expected_size > sizeof(MDRawContextAMD64)) { if (expected_size > sizeof(MDRawContextAMD64)) {
size_t bytes_left = 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<uint8_t> xstate(bytes_left); std::vector<uint8_t> xstate(bytes_left);
if (!minidump_->ReadBytes(xstate.data(), if (!minidump_->ReadBytes(xstate.data(),
bytes_left)) { bytes_left)) {