From 29e851dc765af6f34ddd31335c613e040495c441 Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 05:59:30 +0300 Subject: [PATCH 1/6] Fix: prevent OOB read and UB in sleb128_decode Fix an Out-of-Bounds (OOB) read bug in sleb128_decode(). - Added early return on buffer overrun. - Added shift overflow check to prevent UB. --- src/elf_util.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/elf_util.c b/src/elf_util.c index 57a89fe..7013726 100644 --- a/src/elf_util.c +++ b/src/elf_util.c @@ -80,12 +80,18 @@ static int64_t sleb128_decode(struct sleb128_decoder *decoder) { const size_t size = sizeof(int64_t) * CHAR_BIT; do { - if (decoder->current >= decoder->end) - LOGF("Failed to decode SLEB128: buffer overrun"); + if (decoder->current >= decoder->end) { + LOGF("Failed to decode SLEB128: buffer overrun"); + return 0; + } byte = *decoder->current++; value |= ((int64_t)(byte & 0x7F)) << shift; shift += 7; + if (shift > size) { + LOGF("SLEB128 shift overflow"); + return 0; + } } while (byte & 0x80); if (shift < size && (byte & 0x40)) { From 5cdb867bb5ced6af441a08587a67aabdaa372de6 Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 06:57:32 +0300 Subject: [PATCH 2/6] Bug: add heap overflow guard in elfutil_unpack_android_relocs Added boundary check to prevent out of bounds heap write in elfutil_unpack_android_relocs() This ensures that parsed relocations do not exceed the pre-allocated buffer size. Also added free() --- src/elf_util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/elf_util.c b/src/elf_util.c index 7013726..03fa2fa 100644 --- a/src/elf_util.c +++ b/src/elf_util.c @@ -403,6 +403,12 @@ static bool elfutil_unpack_android_relocs(const struct elf_image *elf, struct an if (elf->rel_android_is_rela_ && group_flags_reloc == RELOCATION_GROUP_HAS_ADDEND_FLAG) r_addend += sleb128_decode(&decoder); + if (out_index >= num_relocs) { + LOGE("Android reloc: out_index exceeded num_relocs"); + free(entries); + return false; + } + if (elf->rel_android_is_rela_) { ElfW(Rela) *rela = (ElfW(Rela) *)entries; rela[out_index].r_offset = current_offset; From 2827dac8327a7b22709dca3ffc3d3642db91c817 Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 07:13:46 +0300 Subject: [PATCH 3/6] Bug: prevent integer mismatch in num_relocs decoding --- src/elf_util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/elf_util.c b/src/elf_util.c index 03fa2fa..5cebb89 100644 --- a/src/elf_util.c +++ b/src/elf_util.c @@ -333,8 +333,9 @@ static bool elfutil_unpack_android_relocs(const struct elf_image *elf, struct an struct sleb128_decoder decoder; sleb128_decoder_init(&decoder, (const uint8_t *)elf->rel_android_, elf->rel_android_size_); - uint64_t num_relocs = sleb128_decode(&decoder); - if (num_relocs <= 0) return false; + int64_t num_relocs_signed = sleb128_decode(&decoder); + if (num_relocs_signed <= 0) return false; + uint64_t num_relocs = (uint64_t)num_relocs_signed; size_t out_index = 0; void *entries = calloc(num_relocs, elf->rel_android_is_rela_ ? sizeof(ElfW(Rela)) : sizeof(ElfW(Rel))); From e5af71ec6c2c7c0031ea5653bb7f8af7c60c396a Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 07:29:32 +0300 Subject: [PATCH 4/6] Fix: prevent memory corruption using MAP_FIXED_NOREPLACE - Replace MAP_FIXED with MAP_FIXED_NOREPLACE in plti_internal_set_got_entry(). - This prevents unintentional overwriting of existing memory mappings if the hint address is already occupied. - Added a fallback mechanism to allocate memory safely without a hint --- src/plti.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plti.c b/src/plti.c index 47676ef..929fcd8 100644 --- a/src/plti.c +++ b/src/plti.c @@ -259,7 +259,9 @@ static bool plti_internal_set_got_entry(struct elf_info *info, uintptr_t got_add if (!stash) { /* INFO: Don't call LOGE -- or else it will try to access GOT while it's being modified */ void *hint = find_high_backup_hint(vma_len); - void *backup_addr = mmap(hint, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + void *backup_addr = MAP_FAILED; + if (hint) + backup_addr = mmap(hint, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0); if (backup_addr == MAP_FAILED) { backup_addr = mmap(NULL, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (backup_addr == MAP_FAILED) { From 6561dda84c69eabd293a3a3c265d5d497bf23c7e Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 16:57:31 +0300 Subject: [PATCH 5/6] Style: spaces and remove Android reloc --- src/elf_util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/elf_util.c b/src/elf_util.c index 5cebb89..204c2bc 100644 --- a/src/elf_util.c +++ b/src/elf_util.c @@ -405,8 +405,10 @@ static bool elfutil_unpack_android_relocs(const struct elf_image *elf, struct an r_addend += sleb128_decode(&decoder); if (out_index >= num_relocs) { - LOGE("Android reloc: out_index exceeded num_relocs"); + LOGE("out_index exceeded num_relocs"); + free(entries); + return false; } From f7b5570086c1aa50f175b44aef56a1a34febb5ab Mon Sep 17 00:00:00 2001 From: Joe Date: Tue, 26 May 2026 17:16:24 +0300 Subject: [PATCH 6/6] Improve: compatibility of the code to run below kernel 4.17 --- src/plti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plti.c b/src/plti.c index 929fcd8..ab69b6b 100644 --- a/src/plti.c +++ b/src/plti.c @@ -261,7 +261,7 @@ static bool plti_internal_set_got_entry(struct elf_info *info, uintptr_t got_add void *hint = find_high_backup_hint(vma_len); void *backup_addr = MAP_FAILED; if (hint) - backup_addr = mmap(hint, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0); + backup_addr = mmap(hint, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (backup_addr == MAP_FAILED) { backup_addr = mmap(NULL, vma_len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (backup_addr == MAP_FAILED) {