https://sourceware.org/bugzilla/show_bug.cgi?id=34498
Bug ID: 34498
Summary: eu-stacktrace: aarch64 SP register number is used as
packed perf-array index, causing out-of-frame 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 16916
--> https://sourceware.org/bugzilla/attachment.cgi?id=16916&action=edit
Detailed analysis and aarch64 runtime reproduction of a register-number versus
packed perf-array index mismatch causing an out-of-frame read in eu-stacktrace.
On aarch64, eu-stacktrace uses the architectural stack-pointer register
number (31) directly as an index into the packed PERF_SAMPLE_REGS_USER
register array.
The perf register array contains only the registers selected by the sample
mask, packed in ascending mask-bit order. Therefore an architectural register
number is not necessarily the physical array index.
In src/stacktrace.c, sp_reg_index() returns 31 for 64-bit aarch64 and the
result is used directly as:
regs->regs[31]
The existing expected_frame_nregs() check accepts 14 registers for
EM_AARCH64, so it does not protect the later index-31 access.
For the aarch64 register masks, SP is at packed index 12 or 25 depending on
the mask being used; index 31 is outside the array in either case.
The issue is reachable through the normal:
eu-stacktrace -i <capture>
path on aarch64.
Testing against origin/main
fb5473ac7368bbbbc2ea9d86241bd6c882e3fcb5 using a cross-built aarch64
eu-stacktrace under qemu-aarch64-static confirmed:
- n_regs=14 while index 31 is still read
- the access is 17 elements / 136 bytes beyond the declared register array
- with a tightly sized STACK_USER frame, the value read comes from the next
capture frame
- reproduced 3/3
- ABI32 control uses index 13 and remains in bounds
This demonstrates an out-of-bounds read of the declared register array that
crosses the enclosing STACK_USER frame.
I have not demonstrated escape beyond the larger Sysprof reader allocation,
information disclosure of secret process memory, a crash, code execution, or
RCE.
Separately, because register number 31 is not the physical packed index of SP
under the aarch64 masks, the last_sp value is incorrect even for normal valid
aarch64 samples.
The correct fix needs to translate the architectural SP register number
through the perf register mapping/mask before indexing the packed array and
then validate the resulting physical index against the number of registers
present.
A detailed root-cause analysis and runtime validation 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.