summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2023-04-13 19:57:31 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2023-04-13 19:57:31 +0000
commit8b7f6c5fb8744b75275395ec621eb880471094b5 (patch)
tree6d5fdb99aee7ecd7cb2d8d0ec152fa9f99457ca1 /libexec
parent17fb9aca220688d1279ac419dea9c6a63ce7b55c (diff)
Avoid an overflow in the ELF SYSV ABI hash function.
The hash function is supposed to return a value less than or equal to 0x0fffffff. Due to a bug in the sample code supplied with the ELF SYSV ABI documentation, the hash function can overflow on 64-bit systems. Apply the same fix used by GNU libc, MUSL libc and FreeBSD. Prompted by https://maskray.me/blog/2023-04-12-elf-hash-function OK tb@ miod@
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/resolve.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index 709402d19cc..70e8dd0dec2 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.98 2023/04/09 23:41:47 gnezdo Exp $ */
+/* $OpenBSD: resolve.c,v 1.99 2023/04/13 19:57:30 millert Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -650,13 +650,11 @@ _dl_find_symbol(const char *name, int flags, const Elf_Sym *ref_sym,
/* Calculate both hashes in one pass */
for (p = (const unsigned char *)name; (c = *p) != '\0'; p++) {
- unsigned long g;
sl.sl_elf_hash = (sl.sl_elf_hash << 4) + c;
- if ((g = sl.sl_elf_hash & 0xf0000000))
- sl.sl_elf_hash ^= g >> 24;
- sl.sl_elf_hash &= ~g;
+ sl.sl_elf_hash ^= (sl.sl_elf_hash >> 24) & 0xf0;
sl.sl_gnu_hash = sl.sl_gnu_hash * 33 + c;
}
+ sl.sl_elf_hash &= 0x0fffffff;
if (req_obj->dyn.symbolic)
if (_dl_find_symbol_obj(req_obj, &sl))