From 3dca1175e5899b54ac97e2ffab38dc5191cc4be4 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 10 Jan 2024 09:41:12 -0800 Subject: [PATCH] invert_pt_dynamic() needs better checking for malformed input https://github.com/upx/upx/issues/759 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65510 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index e0929222..4544b3e9 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -2128,7 +2128,7 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway) unsigned const *const chains = &buckets[nbucket]; (void)chains; unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val); - if ((unsigned)file_size <= nbucket/sizeof(*buckets) // FIXME: weak + if ((hashend - buckets) < nbucket || !v_sym || (unsigned)file_size <= v_sym || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket)) ) { @@ -2170,6 +2170,7 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway) unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; (void)hasharr; if (!n_bucket || (1u<<31) <= n_bucket /* fie on fuzzers */ + || (gashend - buckets) < 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); @@ -8014,7 +8015,7 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway) unsigned const *const chains = &buckets[nbucket]; (void)chains; unsigned const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val); // UPX_RSIZE_MAX_MEM - if ((unsigned)file_size <= nbucket/sizeof(*buckets) // FIXME: weak + if ((hashend - buckets) < nbucket || !v_sym || (unsigned)file_size <= v_sym || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket)) ) { @@ -8056,6 +8057,7 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway) unsigned const *const buckets = (unsigned const *)&bitmask[n_bitmask]; unsigned const *const hasharr = &buckets[n_bucket]; (void)hasharr; if (!n_bucket || (1u<<31) <= n_bucket /* fie on fuzzers */ + || (gashend - buckets) < 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);