Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context size is invalid (0x66f) #243

Closed
expend20 opened this issue Sep 24, 2021 · 18 comments
Closed

Context size is invalid (0x66f) #243

expend20 opened this issue Sep 24, 2021 · 18 comments

Comments

@expend20
Copy link

expend20 commented Sep 24, 2021

Sup!

It looks like the thread_context.data_size is wrong for some reason, thus it's impossible to decide the architecture and parse the context registers (( no context) note).

thread[0]                                                                                                                                                   MINIDUMP_THREAD                                                                                                                                               thread_id                   = 0x2218                                                                                                                        suspend_count               = 1                                                                                                                             priority_class              = 0x20                                                                                                                          priority                    = 0x0
  teb                         = 0xa96271d000                                                                                                                  stack.start_of_memory_range = 0xa96259f688
  stack.memory.data_size      = 0x978
  stack.memory.rva            = 0x0
  thread_context.data_size    = 0x66f
  thread_context.rva          = 0x1fcf

  (no context)

Attaching the .dmp file: fuzzme1.windbg.zip

The code used:

fn work() -> Result<(), Error> {
    let mut dump = minidump::Minidump::read_path("./dump-samples/fuzzme1.windbg.dmp")?;
    let thread_list: MinidumpThreadList = dump.get_stream()?;
    drop(thread_list.print(&mut io::stdout()));
    Ok(())
}

Thank you!

@gabrielesvelto
Copy link
Collaborator

This is a problem we had already run into with Breakpad when dealing with new minidumps that use XSTATE data. See bug 1683232 on our tracker. The context size is variable depending on the combination of state that gets saved and so cannot be identified by its size. Additionally the context doesn't have the CPU flags immediately available and so the CPU type can't be directly extracted from there. I fixed it by patching breakpad this way: in a nutshell we take the CPU type from the system info stream (if present) and assume the context matches it. The only case when this can fail is if the system info stream is not present (which means the minidump would lack some pretty critical information) or if the CPU type of the threads' context is different from the CPU type of the minidump which would be odd... It shouldn't be hard to apply the same change here.

@gabrielesvelto
Copy link
Collaborator

One additional note: in my Breakpad patch I simply skipped over the XSTATE info because we didn't want to spend too much time on it. Here it's a different matter, we'd like to properly parse and include the XSTATE in the context.

@expend20
Copy link
Author

expend20 commented Sep 25, 2021

Is XSTATE is regular context + AVX? If yes, and we know it, then what else we want to know?

@expend20
Copy link
Author

   ... InitializeContext(0, CONTEXT_ALL | CONTEXT_XSTATE, 0, &len);

returns exactly 0x66f

@expend20
Copy link
Author

expend20 commented Sep 25, 2021

Some more scratches, at least we know something...

    DWORD64 FeatureMask;
    DWORD FeatureLength;
    ULONG Index;
    PM128A Xmm;
    PM128A Ymm;

    CONTEXT* ctx;
    BOOL r;
    DWORD len = 0;
    void* buf = 0;
    r = InitializeContext(0, CONTEXT_ALL | CONTEXT_XSTATE, 0, &len);
    printf("init1: %d %x\n", r, len);
    buf = malloc(len);
    memset(buf, 0, len);
    printf("buf: %p\n", buf);
    r = InitializeContext(buf, CONTEXT_ALL | CONTEXT_XSTATE, &ctx, &len);
    printf("init2: %d %x\n", r, len);
    r = SetXStateFeaturesMask(ctx, XSTATE_MASK_AVX);
    printf("set: %d\n", r);
    ctx->ContextFlags = CONTEXT_ALL | CONTEXT_XSTATE;
    r = GetThreadContext(GetCurrentThread(), ctx);
    printf("getthread: %d\n", r);
    r = GetXStateFeaturesMask(ctx, &FeatureMask);
    printf("getfeatures: %d (XSTATE_MASK_AVX = %x) %x\n", r, XSTATE_MASK_AVX, FeatureMask);

    Xmm = (PM128A)LocateXStateFeature(ctx, XSTATE_LEGACY_SSE, &FeatureLength);
    Ymm = (PM128A)LocateXStateFeature(ctx, XSTATE_AVX, NULL);
    printf("FeatureLength = %x\n", FeatureLength);
    printf("CONTEXT offset: %x\n", (size_t)ctx - (size_t)buf);
    printf("Xmm offset = 0x%x\n", (size_t)Xmm - (size_t)buf);
    printf("Ymm offset = 0x%x\n", (size_t)Ymm - (size_t)buf);

    for (Index = 0; Index < FeatureLength / sizeof(Xmm[0]); Index += 1)
    {
        printf("Ymm%d: %I64d %I64d %I64d %I64d\n",
                 Index,
                 Xmm[Index].Low,
                 Xmm[Index].High,
                 Ymm[Index].Low,
                 Ymm[Index].High);
    }

Output:

init1: 0 66f
buf: 00000299B14F6790
init2: 1 66f
set: 1
getthread: 1
getfeatures: 1 (XSTATE_MASK_AVX = 4) 3
FeatureLength = 100
CONTEXT offset: 0
Xmm offset = 0x1a0
Ymm offset = 0x530
Ymm0: 34359738368 0 0 0
Ymm1: 0 0 0 0
Ymm2: 0 0 0 0
Ymm3: 0 0 0 0
Ymm4: 0 0 0 0
Ymm5: 0 0 0 0
Ymm6: 0 0 0 0
Ymm7: 0 0 0 0
Ymm8: 0 0 0 0
Ymm9: 0 0 0 0
Ymm10: 0 0 0 0
Ymm11: 0 0 0 0
Ymm12: 0 0 0 0
Ymm13: 0 0 0 0
Ymm14: 0 0 0 0
Ymm15: 0 0 0 0

raw memory:

0:000> db buf L66f
00000299`b14f6790  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f67a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f67b0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f67c0  5f 00 10 00 80 1f 00 00-33 00 2b 00 2b 00 53 00  _.......3.+.+.S.
00000299`b14f67d0  2b 00 2b 00 46 02 00 00-00 00 00 00 00 00 00 00  +.+.F...........
00000299`b14f67e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f67f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6800  00 00 00 00 00 00 00 00-f2 00 00 00 00 00 00 00  ................
00000299`b14f6810  fe ff ff ff ff ff ff ff-90 67 4f b1 99 02 00 00  .........gO.....
00000299`b14f6820  00 00 00 00 00 00 00 00-d8 fb 7b 3c bf 00 00 00  ..........{<....
00000299`b14f6830  00 00 00 00 00 00 00 00-90 67 4f b1 99 02 00 00  .........gO.....
00000299`b14f6840  90 67 4f b1 99 02 00 00-28 e0 7b 3c bf 00 00 00  .gO.....(.{<....
00000299`b14f6850  87 57 4f b1 99 02 00 00-00 00 00 00 00 00 00 00  .WO.............
00000299`b14f6860  10 fb 7b 3c bf 00 00 00-00 00 00 00 00 00 00 00  ..{<............
00000299`b14f6870  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6880  00 00 00 00 00 00 00 00-a4 eb e6 c8 fc 7f 00 00  ................
00000299`b14f6890  7f 02 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f68a0  00 00 00 00 00 00 00 00-80 1f 00 00 ff ff 00 00  ................
00000299`b14f68b0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f68c0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f68d0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f68e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f68f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6900  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6910  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6920  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6930  00 00 00 00 08 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6940  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6950  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6960  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6970  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6980  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6990  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69b0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69c0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69d0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f69f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a00  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a10  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a30  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a50  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a60  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a70  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a80  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6a90  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6aa0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ab0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ac0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ad0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ae0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6af0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b00  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b10  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b30  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b50  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b60  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b70  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b80  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6b90  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ba0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6bb0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6bc0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6bd0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6be0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6bf0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c00  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c10  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c30  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c50  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6c60  30 fb ff ff 30 06 00 00-30 fb ff ff d0 04 00 00  0...0...0.......
00000299`b14f6c70  20 00 00 00 40 01 00 00-00 00 00 00 00 00 00 00   ...@...........
00000299`b14f6c80  00 00 00 00 00 00 00 00-04 00 00 00 00 00 00 80  ................
00000299`b14f6c90  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ca0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6cb0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6cc0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6cd0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6ce0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6cf0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d00  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d10  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d20  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d30  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d40  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d50  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d60  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d70  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d80  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6d90  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6da0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6db0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6dc0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6dd0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6de0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00000299`b14f6df0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00     ...............

upd:
_CONTEXT structure

   +0x000 P1Home           : 0
   +0x008 P2Home           : 0
   +0x010 P3Home           : 0
   +0x018 P4Home           : 0
   +0x020 P5Home           : 0
   +0x028 P6Home           : 0
   +0x030 ContextFlags     : 0x10005f
   +0x034 MxCsr            : 0x1f80
   +0x038 SegCs            : 0x33
   +0x03a SegDs            : 0x2b
   +0x03c SegEs            : 0x2b
   +0x03e SegFs            : 0x53
   +0x040 SegGs            : 0x2b
   +0x042 SegSs            : 0x2b
   +0x044 EFlags           : 0x246
   +0x048 Dr0              : 0
   +0x050 Dr1              : 0
   +0x058 Dr2              : 0
   +0x060 Dr3              : 0
   +0x068 Dr6              : 0
   +0x070 Dr7              : 0
   +0x078 Rax              : 0xf2
   +0x080 Rcx              : 0xffffffff`fffffffe
   +0x088 Rdx              : 0x00000214`9b0a4830
   +0x090 Rbx              : 0
   +0x098 Rsp              : 0x000000a3`823bf9b8
   +0x0a0 Rbp              : 0
   +0x0a8 Rsi              : 0x00000214`9b0a4830
   +0x0b0 Rdi              : 0x00000214`9b0a4830
   +0x0b8 R8               : 0x000000a3`823bde08
   +0x0c0 R9               : 0x00000214`9b0a3827
   +0x0c8 R10              : 0
   +0x0d0 R11              : 0x000000a3`823bf8f0
   +0x0d8 R12              : 0
   +0x0e0 R13              : 0
   +0x0e8 R14              : 0
   +0x0f0 R15              : 0
   +0x0f8 Rip              : 0x00007ffc`c8e6eba4
   +0x100 FltSave          : _XSAVE_FORMAT
   +0x100 Header           : [2] _M128A
   +0x120 Legacy           : [8] _M128A
   +0x1a0 Xmm0             : _M128A
   +0x1b0 Xmm1             : _M128A
   +0x1c0 Xmm2             : _M128A
   +0x1d0 Xmm3             : _M128A
   +0x1e0 Xmm4             : _M128A
   +0x1f0 Xmm5             : _M128A
   +0x200 Xmm6             : _M128A
   +0x210 Xmm7             : _M128A
   +0x220 Xmm8             : _M128A
   +0x230 Xmm9             : _M128A
   +0x240 Xmm10            : _M128A
   +0x250 Xmm11            : _M128A
   +0x260 Xmm12            : _M128A
   +0x270 Xmm13            : _M128A
   +0x280 Xmm14            : _M128A
   +0x290 Xmm15            : _M128A
   +0x300 VectorRegister   : [26] _M128A
   +0x4a0 VectorControl    : 0
   +0x4a8 DebugControl     : 0
   +0x4b0 LastBranchToRip  : 0
   +0x4b8 LastBranchFromRip : 0
   +0x4c0 LastExceptionToRip : 0
   +0x4c8 LastExceptionFromRip : 0

@expend20
Copy link
Author

So, the _CONTEXT starts with 0 offset

@expend20
Copy link
Author

expend20 commented Oct 1, 2021

@gabrielesvelto can I be of some more help?

@gabrielesvelto
Copy link
Collaborator

Thank you, that's more than enough info. We know already how the context is stored because we parse the XSAVE context information. We just need to pass the CPU type we've parsed from the system info stream to the context reader here and here and then use that to parse the context, instead of the context's size.

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

Looking into this, sorry for the delay. Took me a while to get all the machinery in the right place.

I'm a bit perplexed by the values that XSTATE is giving me for your minidump. Some debug logs I added to MinidumpContext::read:

buffer size: 1647        (bytes.len())
xstate size: 1647        (XSTATE_CONFIG_FEATURE_MSC_INFO.context_size)
    feature  0 - LEGACY_FLOATING_POINT :  offset    0, size  160
    feature  1 - LEGACY_SSE            :  offset  160, size  256
    feature  2 - GSSE_AND_AVX          :  offset  576, size  256
sections size: 832          (difference between min and max bytes of all sections)
reduced size: 815           (difference between buffer size and sections size)
   
expected AMD64 size: 1232
delta from buffer size: 415      (buffer size - amd64 size)

I don't see any way that the values in xstate can be combined to form the expected AMD64 size. Although it's been so long since I've thought about this stuff that maybe I just totally forget what these mean. In the comments I left I assert that all this XSTATE stuff is just "after the context" so I would have assumed that I could do some subtraction or something to get the right size. But the xstate leaves only ~800 bytes left while we expect ~1200 bytes for AMD64.

Just blindly parsing from offset 0 produces this, which, idk seems vaguely reasonable?

Thread 0  (crashed)
 0  AccTest.dll + 0x2e50
    rax = 0x0000000000000032   rdx = 0x0000000000000400
    rcx = 0x000001ef65d96120   rbx = 0x000001ef65d86428
    rsi = 0x0000000000000000   rdi = 0x0000000000000006
    rbp = 0x000000a96259f790   rsp = 0x000000a96259f688
     r8 = 0x000000a96259da78    r9 = 0x000001ef65d8de02
    r10 = 0x0000000000000000   r11 = 0x000000a96259f560
    r12 = 0x0000000000000000   r13 = 0x0000000000000000
    r14 = 0x000001ef65d96120   r15 = 0x00007ff6c04b144c
    rip = 0x00007ffdbb812e50
    Found by: given as instruction pointer in context

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

I'm assuming there's overlap between the "legacy region" and what we normally parse as context, but these diagrams seem pretty hard to reconcile with that theory, unless rax and friends have some alias here that I'm not familiar with.

image

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

Also it's just weird that the xstate header says that is has exactly the size of the buffer and everything starts at offset 0, but ostensibly the "hack fix" is to just assume the normal amd64 context starts at offset 0?

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

(It's not impossible that our xsave parsing is totally messed up BUT the values it produces seem VERY plausible...)

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

For comparison, the AMD64 context we use:

/// An x86-64 (amd64) CPU context
///
/// This struct matches the definition of `CONTEXT` in WinNT.h for x86-64.
#[derive(Debug, SmartDefault, Clone, Pread, SizeWith)]
pub struct CONTEXT_AMD64 {
    pub p1_home: u64,
    pub p2_home: u64,
    pub p3_home: u64,
    pub p4_home: u64,
    pub p5_home: u64,
    pub p6_home: u64,
    pub context_flags: u32,
    pub mx_csr: u32,
    pub cs: u16,
    pub ds: u16,
    pub es: u16,
    pub fs: u16,
    pub gs: u16,
    pub ss: u16,
    pub eflags: u32,
    pub dr0: u64,
    pub dr1: u64,
    pub dr2: u64,
    pub dr3: u64,
    pub dr6: u64,
    pub dr7: u64,
    pub rax: u64,
    pub rcx: u64,
    pub rdx: u64,
    pub rbx: u64,
    pub rsp: u64,
    pub rbp: u64,
    pub rsi: u64,
    pub rdi: u64,
    pub r8: u64,
    pub r9: u64,
    pub r10: u64,
    pub r11: u64,
    pub r12: u64,
    pub r13: u64,
    pub r14: u64,
    pub r15: u64,
    pub rip: u64,
    /// Floating point state
    ///
    /// This is defined as a union in the C headers, but also
    /// ` MAXIMUM_SUPPORTED_EXTENSION` is defined as 512 bytes.
    ///
    /// Callers that want to access the underlying data can use [`Pread`] to read either
    /// an [`XMM_SAVE_AREA32`] or [`SSE_REGISTERS`] struct from this raw data as appropriate.
    #[default([0; 512])]
    pub float_save: [u8; 512],
    #[default([0; 26])]
    pub vector_register: [u128; 26],
    pub vector_control: u64,
    pub debug_control: u64,
    pub last_branch_to_rip: u64,
    pub last_branch_from_rip: u64,
    pub last_exception_to_rip: u64,
    pub last_exception_from_rip: u64,
}

In this struct, float_save starts at offset 256. Its size is congruent with the diagram from Intel. So maybe there's a secret 256 byte prefix that is the "core" context, and then all the xsave stuff comes after it.

This still leaves ~160 unaccounted for bytes in the buffer size (which is the size of LEGACY_FLOATING_POINT? HMM???)

@Gankra
Copy link
Collaborator

Gankra commented Nov 4, 2021

Looking closer at our definition of XMM_SAVE_AREA_32:

pub struct XMM_SAVE_AREA32 {
    pub control_word: u16,
    pub status_word: u16,
    pub tag_word: u8,
    pub reserved1: u8,
    pub error_opcode: u16,
    pub error_offset: u32,
    pub error_selector: u16,
    pub reserved2: u16,
    pub data_offset: u32,
    pub data_selector: u16,
    pub reserved3: u16,
    pub mx_csr: u32,
    pub mx_csr_mask: u32,
    pub float_registers: [u128; 8],
    pub xmm_registers: [u128; 16],
    pub reserved4: [u8; 96],
}

That looks exactly like the Intel diagram.

@Gankra
Copy link
Collaborator

Gankra commented Nov 5, 2021

Ok so after mulling this over my guess is:

  • If there's XSTATE then the "classic" CONTEXT layout still applies, but our size heuristic is no longer valid because there's extra stuff at the end that may or may not actually be specified by the XSTATE tables.
    • So we have to use SYSTEM_INFO
    • But we can seemingly do extra validation in this case:
      • microsoft appears to set bit 0x00000040L of ContextFlags to indicate XSTATE is being used
      • (not validated, just seen in headers)
  • The XSTATE region implicitly starts at offset 256
  • This is because the first 256 bytes of the context are a Microsoft-specific format (because AMD64 does not define how to save/restore general purpose registers, it just tells you to individually PUSH them in whatever order you want).
  • Any place where an XSTATE Feature overlaps with the classic layout implies that's where that data is (and always has been?) stored in the classic layout, and can be ignored (we already have those layouts hardcoded).
  • There are some fields in the classic context (at offset 1184-1232) that are in the XSTATE region but seemingly don't map to any XSTATE feature. Possible these land in a region reserved for vendor-specific data?
    • vector_control, debug_control, ...

I've sent an email to the microsoft minidump tooling folks asking what's up with all of this.

@Gankra Gankra added this to the socorro parity milestone Nov 9, 2021
@Gankra
Copy link
Collaborator

Gankra commented Nov 9, 2021

email from microsoft seems to largely confirm all of the above!

@gabrielesvelto
Copy link
Collaborator

I'm glad they confirmed that we can still rely on the old stuff because we've processed minidumps for a while "assuming" that it would be that way. We can delay parsing the extra state to a follow-up bug and just go for the straightforward fix here which IMHO captures 99% of the functionality we care about.

@Gankra
Copy link
Collaborator

Gankra commented Nov 11, 2021

Fixed by #289

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants