From 30f37d2cc60a39e59f220b17c05fd8f9c1384c8c Mon Sep 17 00:00:00 2001 From: John Reiser Date: Fri, 17 Apr 2020 16:49:54 -0700 Subject: [PATCH] DT_GNU_HASH check the buckets https://github.com/upx/upx/issues/365 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 725f68f4..73e2c68b 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1686,6 +1686,12 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp) unsigned bmax = 0; for (unsigned j= 0; j < n_bucket; ++j) { if (buckets[j]) { + if (buckets[j] < symbias) { + char msg[50]; snprintf(msg, sizeof(msg), + "bad DT_GNU_HASH bucket[%d] < symbias{%#x}\n", + buckets[j], symbias); + throwCantPack(msg); + } if (bmax < buckets[j]) { bmax = buckets[j]; } @@ -5231,6 +5237,12 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp) unsigned bmax = 0; for (unsigned j= 0; j < n_bucket; ++j) { if (buckets[j]) { + if (buckets[j] < symbias) { + char msg[50]; snprintf(msg, sizeof(msg), + "bad DT_GNU_HASH bucket[%d] < symbias{%#x}\n", + buckets[j], symbias); + throwCantPack(msg); + } if (bmax < buckets[j]) { bmax = buckets[j]; } @@ -5357,6 +5369,12 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const if (1& (w>>hbit1) & (w>>hbit2)) { unsigned bucket = get_te32(&buckets[h % n_bucket]); + if (n_bucket <= bucket) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n", + n_bucket, h % n_bucket, bucket); + throwCantPack(msg); + } if (0!=bucket) { Elf32_Sym const *dsp = &dynsym[bucket]; unsigned const *hp = &hasharr[bucket - symbias]; @@ -5406,6 +5424,12 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const if (1& (w>>hbit1) & (w>>hbit2)) { unsigned bucket = get_te32(&buckets[h % n_bucket]); + if (n_bucket <= bucket) { + char msg[80]; snprintf(msg, sizeof(msg), + "bad DT_GNU_HASH n_bucket{%#x} <= buckets[%d]{%#x}\n", + n_bucket, h % n_bucket, bucket); + throwCantPack(msg); + } if (0!=bucket) { Elf64_Sym const *dsp = &dynsym[bucket]; unsigned const *hp = &hasharr[bucket - symbias];