From cf394b78919e2048d6b9e5d964eb85d111394719 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 4 Sep 2026 09:31:06 +0200 Subject: [PATCH 1/2] fix(linux): Guard module address arithmetic Validate mapping-relative offsets and lengths with subtraction so malformed ELF metadata cannot wrap a range check. Close: NATIVE-219 --- src/modulefinder/sentry_modulefinder_linux.c | 20 ++++++++++++-------- tests/unit/test_modulefinder.c | 7 +++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/modulefinder/sentry_modulefinder_linux.c b/src/modulefinder/sentry_modulefinder_linux.c index 595885b10c..fabe0a86c3 100644 --- a/src/modulefinder/sentry_modulefinder_linux.c +++ b/src/modulefinder/sentry_modulefinder_linux.c @@ -101,17 +101,21 @@ sentry__module_get_addr( { for (size_t i = 0; i < module->num_mappings; i++) { const sentry_mapped_region_t *mapping = &module->mappings[i]; + if (mapping->offset < module->offset_in_inode) { + continue; + } uint64_t mapping_offset = mapping->offset - module->offset_in_inode; - // start_offset is inside this mapping - if (start_offset >= mapping_offset - && start_offset < mapping_offset + mapping->size) { - uint64_t addr = start_offset - mapping_offset + mapping->addr; - // the requested size is fully inside the mapping - if (addr + size <= mapping->addr + mapping->size) { - return (void *)(uintptr_t)(addr); - } + if (start_offset < mapping_offset) { + continue; + } + uint64_t offset = start_offset - mapping_offset; + + // start_offset and the requested size are fully inside this mapping + if (offset >= mapping->size || size > mapping->size - offset) { + continue; } + return (void *)(uintptr_t)(mapping->addr + offset); } return NULL; } diff --git a/tests/unit/test_modulefinder.c b/tests/unit/test_modulefinder.c index 3173c3ba1d..6d8147c8b2 100644 --- a/tests/unit/test_modulefinder.c +++ b/tests/unit/test_modulefinder.c @@ -74,6 +74,13 @@ SENTRY_TEST(module_addr) ptr = sentry__module_get_addr(&module, 7, 9); TEST_CHECK(ptr == NULL); // too big + + ptr = sentry__module_get_addr(&module, 1, UINT64_MAX); + TEST_CHECK(ptr == NULL); // size overflows + + module.offset_in_inode = 10; + ptr = sentry__module_get_addr(&module, UINT64_MAX - 8, 1); + TEST_CHECK(ptr == NULL); // mapping offset underflows #endif } From 43cb29c9613f383196a7883dbcea8c5ce8443f6e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 4 Sep 2026 12:23:11 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0237927f9..056e9fa7a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ **Fixes**: - Native/Linux: parse minidump-writer ELF build-id notes with `sentry__elf_find_note`. ([#2055](https://github.com/getsentry/sentry-native/pull/2055)) +- Native/Linux: prevent malformed ELF metadata from bypassing module address bounds checks through integer overflow or underflow. ([#2064](https://github.com/getsentry/sentry-native/pull/2064)) - 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)) - Native: clean up stale envelopes after crashes with `SENTRY_TRANSPORT=none`. ([#2049](https://github.com/getsentry/sentry-native/pull/2049))