From b48f8707015345ae41e5d0e44acbea202b2a7318 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Thu, 25 Jan 2024 15:05:53 -0800 Subject: [PATCH] Detect circular DT_HASH and DT_GNUHASH lookup https://github.com/upx/upx/issues/775 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65811&q=label%3AProj-upx https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65840&q=label%3AProj-upx --- src/p_lx_elf.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 80f61a33..16378b88 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -8179,12 +8179,16 @@ Elf32_Sym const *PackLinuxElf32::elf_lookup(char const *name) const } if (nbucket) { unsigned const m = elf_hash(name) % nbucket; + unsigned nvisit = 0; unsigned si; for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) { char const *const p= get_dynsym_name(si, (unsigned)-1); if (0==strcmp(name, p)) { return &dynsym[si]; } + if (nbucket <= ++nvisit) { + throwCantPack("circular DT_HASH chain %d\n", si); + } } } } @@ -8261,12 +8265,16 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const } if (nbucket) { // -rust-musl can have "empty" hashtab unsigned const m = elf_hash(name) % nbucket; + unsigned nvisit = 0; unsigned si; for (si= get_te32(&buckets[m]); 0!=si; si= get_te32(&chains[si])) { char const *const p= get_dynsym_name(si, (unsigned)-1); if (0==strcmp(name, p)) { return &dynsym[si]; } + if (nbucket <= ++nvisit) { + throwCantPack("circular DT_HASH chain %d\n", si); + } } } }