Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

**Fixes**:

- native: Read frame records at pointer width in the crash daemon's frame-pointer walk, so 32-bit targets no longer read two stack slots per pointer. ([#2052](https://github.com/getsentry/sentry-native/pull/2052))
- Prevent backend state races when `sentry_reinstall_backend` runs concurrently with scope observer callbacks. ([#2041](https://github.com/getsentry/sentry-native/pull/2041))
- `sentry_set_trace` omits `parent_span_id` when the caller does not provide one, instead of serializing it as `null`. ([#2047](https://github.com/getsentry/sentry-native/pull/2047))
- Native/Linux i386: write valid thread stack descriptors to minidumps when stack addresses use the upper half of the 32-bit address space. ([#2054](https://github.com/getsentry/sentry-native/pull/2054))
Expand Down
19 changes: 13 additions & 6 deletions src/backends/native/sentry_crash_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,19 @@ static bool
read_stack_value(const uint8_t *stack_buf, uint64_t stack_start,
uint64_t stack_size, uint64_t addr, uint64_t *out_value)
{
if (addr < stack_start
|| addr + sizeof(uint64_t) > stack_start + stack_size) {
// Range-check by subtraction: `addr` comes from a frame pointer in a
// crashed process, and a corrupted value near the top of the address
// space would wrap an `addr + size` sum past the naive comparison.
if (addr < stack_start) {
return false;
}
uint64_t offset = addr - stack_start;
memcpy(out_value, stack_buf + offset, sizeof(uint64_t));
if (offset > stack_size || stack_size - offset < sizeof(uintptr_t)) {
return false;
}
uintptr_t value = 0;
memcpy(&value, stack_buf + (size_t)offset, sizeof(value));
*out_value = (uint64_t)value;
return true;
}

Expand Down Expand Up @@ -1112,7 +1119,7 @@ build_stacktrace_for_thread(
uint64_t return_addr = 0;

// Read saved frame pointer and return address
// Frame layout: [FP+0] = saved FP, [FP+8] = return addr
// Frame layout: [FP] = saved FP, [FP + pointer size] = return addr
if (!read_stack_value(stack_buf, stack_start, stack_size,
current_fp, &saved_fp)) {
SENTRY_TRACEF(
Expand All @@ -1123,9 +1130,9 @@ build_stacktrace_for_thread(
break;
}
if (!read_stack_value(stack_buf, stack_start, stack_size,
current_fp + sizeof(uint64_t), &return_addr)) {
current_fp + sizeof(uintptr_t), &return_addr)) {
SENTRY_TRACEF("Cannot read return addr at 0x%llx",
(unsigned long long)(current_fp + sizeof(uint64_t)));
(unsigned long long)(current_fp + sizeof(uintptr_t)));
break;
}
saved_fp = SENTRY__STRIP_PAC(saved_fp);
Expand Down
Loading