Headline
CVE-2020-27790: Detect bogus DT_SYMENT. · upx/upx@eb90eab
A floating point exception issue was discovered in UPX in PackLinuxElf64::invert_pt_dynamic() function of p_lx_elf.cpp file. An attacker with a crafted input file could trigger this issue that could cause a crash leading to a denial of service. The highest impact is to Availability.
@@ -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);