From eb90eab6325d009004ffb155e3e33f22d4d3ca26 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 13 Jan 2020 17:10:02 -0800 Subject: [PATCH] Detect bogus DT_SYMENT. https://github.com/upx/upx/issues/331 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index c17c672d..ef58eee8 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1614,9 +1614,17 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp) unsigned const z_sym = dt_table[Elf32_Dyn::DT_SYMENT]; unsigned const sz_sym = !z_sym ? sizeof(Elf32_Sym) : get_te32(&dynp0[-1+ z_sym].d_val); + if (sz_sym < sizeof(Elf32_Sym)) { + char msg[50]; snprintf(msg, sizeof(msg), + "bad DT_SYMENT %x", sz_sym); + throwCantPack(msg); + } if (v_sym < v_str) { symnum_end = (v_str - v_sym) / sz_sym; } + if (symnum_end < 1) { + throwCantPack("bad DT_SYMTAB"); + } } // DT_HASH often ends at DT_SYMTAB unsigned const v_hsh = elf_unsigned_dynamic(Elf32_Dyn::DT_HASH); @@ -5104,9 +5112,17 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp) unsigned const z_sym = dt_table[Elf64_Dyn::DT_SYMENT]; unsigned const sz_sym = !z_sym ? sizeof(Elf64_Sym) : get_te64(&dynp0[-1+ z_sym].d_val); + if (sz_sym < sizeof(Elf64_Sym)) { + char msg[50]; snprintf(msg, sizeof(msg), + "bad DT_SYMENT %x", sz_sym); + throwCantPack(msg); + } if (v_sym < v_str) { symnum_end = (v_str - v_sym) / sz_sym; } + if (symnum_end < 1) { + throwCantPack("bad DT_SYMTAB"); + } } // DT_HASH often ends at DT_SYMTAB unsigned const v_hsh = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH);