From 962c35aa08ef3dcee13d3f7ef6e2d845da912f25 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sat, 23 May 2020 10:04:38 -0700 Subject: [PATCH] More checking of DT_GNU_HASH and DT_HASH tables https://github.com/upx/upx/issues/381 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 997a7cde..7b7ba690 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -5362,7 +5362,8 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const unsigned const *const buckets = &hashtab[2]; unsigned const *const chains = &buckets[nbucket]; unsigned const m = elf_hash(name) % nbucket; - if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) + if (!nbucket + || (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) <= sizeof(unsigned)*nbucket ) { char msg[80]; snprintf(msg, sizeof(msg), "bad nbucket %#x\n", nbucket); @@ -5384,7 +5385,14 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const unsigned const *const bitmask = &gashtab[4]; unsigned const *const buckets = &bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; - if ((unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) + if (!n_bucket + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } + if (!n_bitmask + || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) <= sizeof(unsigned)*n_bitmask ) { char msg[80]; snprintf(msg, sizeof(msg), "bad n_bitmask %#x\n", n_bitmask); @@ -5431,7 +5439,8 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const unsigned const *const buckets = &hashtab[2]; unsigned const *const chains = &buckets[nbucket]; unsigned const m = elf_hash(name) % nbucket; - if ((unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) + if (!nbucket + || (unsigned)(file_size - ((char const *)buckets - (char const *)(void const *)file_image)) <= sizeof(unsigned)*nbucket ) { char msg[80]; snprintf(msg, sizeof(msg), "bad nbucket %#x\n", nbucket); @@ -5453,7 +5462,14 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const upx_uint64_t const *const bitmask = (upx_uint64_t const *)(void const *)&gashtab[4]; unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; - if ((unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) + if (!n_bucket + || (void const *)&file_image[file_size] <= (void const *)hasharr) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad n_bucket %#x\n", n_bucket); + throwCantPack(msg); + } + if (!n_bitmask + || (unsigned)(file_size - ((char const *)bitmask - (char const *)(void const *)file_image)) <= sizeof(unsigned)*n_bitmask ) { char msg[80]; snprintf(msg, sizeof(msg), "bad n_bitmask %#x\n", n_bitmask);