Module Name:    src
Committed By:   christos
Date:           Tue Apr 18 16:48:45 UTC 2023

Modified Files:
        src/libexec/ld.elf_so: rtld.h symbol.c

Log Message:
The SysV ABI specifies that the symbol hash function should return only 32
bits of hash. Unfortunately due to an implementation bu and the fact that
the return type is unsigned long which is 64 bits in LP64, this can fail
in some cases: "\xff\x0f\x0f\x0f\x0f\x0f\x12". See:
    https://maskray.me/blog/2023-04-12-elf-hash-function
>From Ed Maste @ FreeBSD:
    https://cgit.freebsd.org/src/commit/\
        ?id=29e3a06510823edbb91667d21f530d3ec778116d
Need to write Unit Tests for this.


To generate a diff of this commit:
cvs rdiff -u -r1.144 -r1.145 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.73 -r1.74 src/libexec/ld.elf_so/symbol.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.144 src/libexec/ld.elf_so/rtld.h:1.145
--- src/libexec/ld.elf_so/rtld.h:1.144	Tue Jun 21 02:52:17 2022
+++ src/libexec/ld.elf_so/rtld.h	Tue Apr 18 12:48:45 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.144 2022/06/21 06:52:17 skrll Exp $	 */
+/*	$NetBSD: rtld.h,v 1.145 2023/04/18 16:48:45 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -440,8 +440,8 @@ void _rtld_call_ifunc(Obj_Entry *, sigse
 Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
 
 /* symbol.c */
-unsigned long _rtld_sysv_hash(const char *);
-unsigned long _rtld_gnu_hash(const char *);
+Elf32_Word _rtld_sysv_hash(const char *);
+Elf32_Word _rtld_gnu_hash(const char *);
 const Elf_Sym *_rtld_symlook_obj(const char *, Elf_Hash *,
     const Obj_Entry *, u_int, const Ver_Entry *);
 const Elf_Sym *_rtld_find_symdef(unsigned long, const Obj_Entry *,

Index: src/libexec/ld.elf_so/symbol.c
diff -u src/libexec/ld.elf_so/symbol.c:1.73 src/libexec/ld.elf_so/symbol.c:1.74
--- src/libexec/ld.elf_so/symbol.c:1.73	Sat Feb 29 13:45:20 2020
+++ src/libexec/ld.elf_so/symbol.c	Tue Apr 18 12:48:45 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: symbol.c,v 1.73 2020/02/29 18:45:20 kamil Exp $	 */
+/*	$NetBSD: symbol.c,v 1.74 2023/04/18 16:48:45 christos Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: symbol.c,v 1.73 2020/02/29 18:45:20 kamil Exp $");
+__RCSID("$NetBSD: symbol.c,v 1.74 2023/04/18 16:48:45 christos Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -81,33 +81,27 @@ _rtld_donelist_check(DoneList *dlp, cons
 }
 
 /*
- * Hash function for symbol table lookup.  Don't even think about changing
- * this.  It is specified by the System V ABI.
+ * SysV hash function for symbol table lookup.  It is a slightly optimized
+ * version of the hash specified by the System V ABI.
  */
-unsigned long
+Elf32_Word
 _rtld_sysv_hash(const char *name)
 {
 	const unsigned char *p = (const unsigned char *) name;
-	unsigned long   h = 0;
-	unsigned long   g;
-	unsigned long   c;
-
-	for (; __predict_true((c = *p) != '\0'); p++) {
-		h <<= 4;
-		h += c;
-		if ((g = h & 0xf0000000) != 0) {
-			h ^= g;
-			h ^= g >> 24;
-		}
+	Elf32_Word h = 0;
+
+	while (__predict_true(*p != '\0')) {
+		h = (h << 4) + *p++;
+		h ^= (h >> 24) & 0xf0;
 	}
-	return (h);
+	return (h & 0xffffffff);
 }
 
 /*
  * Hash function for symbol table lookup.  Don't even think about changing
  * this.  It is specified by the GNU toolchain ABI.
  */
-unsigned long
+Elf32_Word
 _rtld_gnu_hash(const char *name)
 {
 	const unsigned char *p = (const unsigned char *) name;
@@ -116,7 +110,7 @@ _rtld_gnu_hash(const char *name)
 
 	for (c = *p; c != '\0'; c = *++p)
 		h = h * 33 + c;
-	return (unsigned long)h;
+	return (h & 0xffffffff);
 }
 
 const Elf_Sym *

Reply via email to