Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so The SysV ABI specifies that the symbol has...



details:   https://anonhg.NetBSD.org/src/rev/83654902ec4b
branches:  trunk
changeset: 374320:83654902ec4b
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Apr 18 16:48:45 2023 +0000

description:
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.

diffstat:

 libexec/ld.elf_so/rtld.h   |   6 +++---
 libexec/ld.elf_so/symbol.c |  30 ++++++++++++------------------
 2 files changed, 15 insertions(+), 21 deletions(-)

diffs (90 lines):

diff -r eeec5192c7f8 -r 83654902ec4b libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h  Tue Apr 18 15:02:22 2023 +0000
+++ b/libexec/ld.elf_so/rtld.h  Tue Apr 18 16:48:45 2023 +0000
@@ -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 *,
diff -r eeec5192c7f8 -r 83654902ec4b libexec/ld.elf_so/symbol.c
--- a/libexec/ld.elf_so/symbol.c        Tue Apr 18 15:02:22 2023 +0000
+++ b/libexec/ld.elf_so/symbol.c        Tue Apr 18 16:48:45 2023 +0000
@@ -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 @@ static bool
 }
 
 /*
- * 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;
+       Elf32_Word h = 0;
 
-       for (; __predict_true((c = *p) != '\0'); p++) {
-               h <<= 4;
-               h += c;
-               if ((g = h & 0xf0000000) != 0) {
-                       h ^= g;
-                       h ^= g >> 24;
-               }
+       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 @@ unsigned long
 
        for (c = *p; c != '\0'; c = *++p)
                h = h * 33 + c;
-       return (unsigned long)h;
+       return (h & 0xffffffff);
 }
 
 const Elf_Sym *



Home | Main Index | Thread Index | Old Index