https://sourceware.org/bugzilla/show_bug.cgi?id=34497

            Bug ID: 34497
           Summary: eu-stacktrace: malformed STACK_USER size can move
                    register trailer outside frame and cause out-of-bounds
                    read
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: tools
          Assignee: unassigned at sourceware dot org
          Reporter: karankurani3k at gmail dot com
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 16915
  --> https://sourceware.org/bugzilla/attachment.cgi?id=16915&action=edit
Detailed analysis and reproduction of malformed STACK_USER size handling
causing an out-of-frame register pointer, invalid read, and deterministic crash
in eu-stacktrace.

eu-stacktrace trusts the file-controlled SysprofCaptureStackUser.size value
when locating the register trailer that follows a STACK_USER frame.

The outer Sysprof reader validates frame->len, but sysprof_unwind_cb() does
not verify that the declared stack data, the SysprofCaptureUserRegs header,
and the variable-length register array all fit inside the enclosing frame
before deriving and dereferencing the register pointer.

The relevant calculation is effectively:

    tail_ptr += sizeof(SysprofCaptureStackUser) + ev->size;
    SysprofCaptureUserRegs *regs =
        (SysprofCaptureUserRegs *)tail_ptr;

ev->size is a uint64_t from the input capture, while frame->len is uint16_t.

A malformed STACK_USER frame with:

    frame.len = 40
    size      = 0x100000

is accepted by the outer frame reader and causes the derived register pointer
to land approximately 1 MiB beyond the frame. sysprof_find_dwfl() then
dereferences the invalid pointer to access the register trailer.

The issue is reachable through the normal:

    eu-stacktrace -i <capture>

input path.

Testing against origin/main
fb5473ac7368bbbbc2ea9d86241bd6c882e3fcb5 confirmed:

- malformed STACK_USER.size produces an invalid derived register pointer
- deterministic segmentation fault in the sysprof_find_dwfl path
- reproduced 3/3
- reproduced with NDEBUG
- valid control input does not trigger the fault

The missing invariant is that the complete nested STACK_USER layout must fit
inside frame->len before any nested field is consumed.

I have not demonstrated code execution and am not making an RCE claim.

A detailed root-cause analysis, validation results, and expected bounds
invariant are included in the attached report.

Reporter:

Karan Kurani <[email protected]>

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to