From 527139978abdb15a664a5a88e40d44ee576c7089 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 8 Jun 2020 12:37:53 -0700 Subject: [PATCH] DT_HASH chains might be trimmed (64-bit, too) https://github.com/upx/upx/issues/383 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 65f9e695..cd9e4ec9 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -5241,14 +5241,23 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp) unsigned const *const chains = &buckets[nbucket]; (void)chains; unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val); - if (!nbucket || !v_sym - || (nbucket>>31) || (file_size/sizeof(unsigned)) <= (2*nbucket) // FIXME: weak - || ((v_hsh < v_sym) && (v_sym - v_hsh) < (sizeof(unsigned)*2 // headers - + sizeof(*buckets)*nbucket // buckets - + sizeof(*chains) *nbucket // chains - )) + if (!nbucket || (nbucket>>31) || !v_sym || file_size <= v_sym + || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket)) ) { - char msg[90]; snprintf(msg, sizeof(msg), + char msg[80]; snprintf(msg, sizeof(msg), + "bad DT_HASH nbucket=%#x len=%#x", + nbucket, (v_sym - v_hsh)); + throwCantPack(msg); + } + unsigned chmax = 0; + for (unsigned j= 0; j < nbucket; ++j) { + if (chmax < buckets[j]) { + chmax = buckets[j]; + } + } + if ((v_hsh < v_sym) && (v_sym - v_hsh) < + (sizeof(*buckets)*(2+ nbucket) + sizeof(*chains)*(1+ chmax))) { + char msg[80]; snprintf(msg, sizeof(msg), "bad DT_HASH nbucket=%#x len=%#x", nbucket, (v_sym - v_hsh)); throwCantPack(msg);