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 @@ -18,6 +18,7 @@
- Native: clean up stale envelopes after crashes with `SENTRY_TRANSPORT=none`. ([#2049](https://github.com/getsentry/sentry-native/pull/2049))
- `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))
- Native/Linux: cap ELF metadata section reads when resolving module SONAMEs. ([#2066](https://github.com/getsentry/sentry-native/pull/2066))
- Linux/ARM32: fix builds on 32-bit ARM systems, including 32-bit Raspberry Pi OS installations running a 64-bit kernel. ([#2063](https://github.com/getsentry/sentry-native/pull/2063))
- Guard size arithmetic when parsing envelopes and Linux OS release data, copying slices, and allocating memory during crash handling. ([#2059](https://github.com/getsentry/sentry-native/pull/2059))

Expand Down
32 changes: 6 additions & 26 deletions src/backends/native/minidump/sentry_minidump_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1123,45 +1123,25 @@ read_elf_soname(const char *elf_path, char *soname_buf, size_t soname_buf_size)
}

// Read .dynstr
size_t dynstr_size = dynstr_shdr->sh_size;
if (dynstr_size > 1024 * 1024) { // Sanity: max 1MB
sentry_free(shdr_buf);
close(fd);
return false;
}
char *dynstr = sentry_malloc(dynstr_size);
char *dynstr = sentry__elf_read_metadata_section(
fd, dynstr_shdr->sh_offset, dynstr_shdr->sh_size);
if (!dynstr) {
sentry_free(shdr_buf);
close(fd);
return false;
}
if (lseek(fd, dynstr_shdr->sh_offset, SEEK_SET)
!= (off_t)dynstr_shdr->sh_offset
|| read(fd, dynstr, dynstr_size) != (ssize_t)dynstr_size) {
sentry_free(dynstr);
sentry_free(shdr_buf);
close(fd);
return false;
}
size_t dynstr_size = (size_t)dynstr_shdr->sh_size;

// Read .dynamic entries and find DT_SONAME
size_t dyn_size = dynamic_shdr->sh_size;
void *dyn_buf = sentry_malloc(dyn_size);
void *dyn_buf = sentry__elf_read_metadata_section(
fd, dynamic_shdr->sh_offset, dynamic_shdr->sh_size);
if (!dyn_buf) {
sentry_free(dynstr);
sentry_free(shdr_buf);
close(fd);
return false;
}
if (lseek(fd, dynamic_shdr->sh_offset, SEEK_SET)
!= (off_t)dynamic_shdr->sh_offset
|| read(fd, dyn_buf, dyn_size) != (ssize_t)dyn_size) {
sentry_free(dyn_buf);
sentry_free(dynstr);
sentry_free(shdr_buf);
close(fd);
return false;
}
size_t dyn_size = (size_t)dynamic_shdr->sh_size;

DynT *dyn_entries = (DynT *)dyn_buf;
size_t dyn_count = dyn_size / sizeof(DynT);
Expand Down
28 changes: 28 additions & 0 deletions src/sentry_elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,34 @@ sentry__elf_has_phdr_size(
# endif
}

# define SENTRY_ELF_MAX_METADATA_SECTION_SIZE (1024 * 1024)

static inline void *
sentry__elf_read_metadata_section(int fd, uint64_t offset, uint64_t size)
{
if (size == 0 || size > SENTRY_ELF_MAX_METADATA_SECTION_SIZE) {
return NULL;
}

off_t file_offset = (off_t)offset;
if (file_offset < 0 || (uint64_t)file_offset != offset) {
return NULL;
}

size_t len = (size_t)size;
void *buf = sentry_malloc(len);
if (!buf) {
return NULL;
}

if (lseek(fd, file_offset, SEEK_SET) != file_offset
|| read(fd, buf, len) != (ssize_t)len) {
sentry_free(buf);
return NULL;
}
return buf;
}

/**
* Safely iterate ELF notes in a buffer to find one matching the given type
* and name. Alignment must be 4 or 8 (per ELF spec, PT_NOTE uses p_align,
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/test_modulefinder.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ SENTRY_TEST(module_addr)
#endif
}

SENTRY_TEST(elf_metadata_section)
{
#if !defined(SENTRY_PLATFORM_LINUX) || defined(SENTRY_PLATFORM_ANDROID)
SKIP_TEST();
#else
char tmp_path[] = "/tmp/sentry-native-elf-section-XXXXXX";
int fd = mkstemp(tmp_path);
TEST_ASSERT(fd >= 0);
TEST_ASSERT(write(fd, "test", 4) == 4);

char *buf = sentry__elf_read_metadata_section(fd, 1, 3);
TEST_ASSERT(!!buf);
TEST_CHECK(memcmp(buf, "est", 3) == 0);
sentry_free(buf);

TEST_CHECK(!sentry__elf_read_metadata_section(
fd, 0, SENTRY_ELF_MAX_METADATA_SECTION_SIZE + 1));
TEST_CHECK(!sentry__elf_read_metadata_section(fd, UINT64_MAX, 1));

close(fd);
unlink(tmp_path);
#endif
}

SENTRY_TEST(mmap_file_closes_fd_zero_on_failure)
{
#if !defined(SENTRY_PLATFORM_LINUX) || defined(SENTRY_PLATFORM_ANDROID)
Expand Down
1 change: 1 addition & 0 deletions tests/unit/tests.inc
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ XX(dsn_without_url_scheme_is_invalid)
XX(effective_org_id_resolution)
XX(elf_find_note)
XX(elf_header_entry_sizes)
XX(elf_metadata_section)
XX(elf_rejects_non_regular_files)
XX(embedded_info_basic)
XX(embedded_info_build_id)
Expand Down
Loading