Date: Sat, 01 Sep 2018 00:32:07 +0200 From: Andreas Longwitz <longwitz@incore.de> To: freebsd-stable@freebsd.org Subject: Constraints in libmap(32).conf do not work as expected, possible bug in rtld-elf Message-ID: <5B89C1E7.4090002@incore.de>
next in thread | raw e-mail | index | archive | help
On a FreeBSD 10.4-STABLE r337823 (amd64) server I have to run some old
php52 scripts from an FreeBSD 8.4-STABLE r284383 (i386) server. I have
copied the old php software to /usr/local/php52, installed the ports
misc/compat8x and misc/compat9x and have copied all missing 32-bit
libraries from the old machine to /usr/local/lib32. With the following
libmap32.conf everything works fine:
## php52
/usr/local/lib          /usr/local/lib32
/usr/local/lib/mysql    /usr/local/lib32/mysql
Two examples:
-> ldd /usr/local/php52/bin/php
/usr/local/php52/bin/php:
        libcrypt.so.5 => /usr/lib32/libcrypt.so.5 (0x28273000)
        librt.so.1 => /usr/lib32/librt.so.1 (0x28292000)
        libm.so.5 => /usr/lib32/libm.so.5 (0x28298000)
        libxml2.so.5 => /usr/local/lib32/libxml2.so.5 (0x282c2000)
        libz.so.5 => /usr/local/lib32/compat/libz.so.5 (0x283ec000)
        libiconv.so.3 => /usr/local/lib32/libiconv.so.3 (0x283fe000)
        libc.so.7 => /usr/lib32/libc.so.7 (0x284f2000)
        libthr.so.3 => /usr/lib32/libthr.so.3 (0x2866c000)
-> ldd /usr/local/php52/lib/php/20060613/mysql.so
/usr/local/php52/lib/php/20060613/mysql.so:
        libmysqlclient.so.16 =>
/usr/local/lib32/mysql/libmysqlclient.so.16 (0x28206000)
        libc.so.7 => /usr/lib32/libc.so.7 (0x28070000)
        libcrypt.so.5 => /usr/lib32/libcrypt.so.5 (0x2835e000)
        libm.so.5 => /usr/lib32/libm.so.5 (0x2837d000)
        libz.so.5 => /usr/local/lib32/compat/libz.so.5 (0x283a7000)
        librt.so.1 => /usr/lib32/librt.so.1 (0x283b9000)
        libthr.so.3 => /usr/lib32/libthr.so.3 (0x283bf000)
Because I like to use constraints in libmap32.conf I chenged the file to
## php52
[/usr/local/php52/]
/usr/local/lib          /usr/local/lib32
[/usr/local/php52/lib/php/20060613/mysql.so]
/usr/local/lib/mysql    /usr/local/lib32/mysql
The same examples as above shows that libmap does not work anymore:
-> ldd /usr/local/php52/bin/php
/usr/local/php52/bin/php:
        libcrypt.so.5 => /usr/lib32/libcrypt.so.5 (0x28273000)
        librt.so.1 => /usr/lib32/librt.so.1 (0x28292000)
        libm.so.5 => /usr/lib32/libm.so.5 (0x28298000)
        libxml2.so.5 => not found (0)
        libz.so.5 => /usr/local/lib32/compat/libz.so.5 (0x282c2000)
        libiconv.so.3 => not found (0)
        libc.so.7 => /usr/lib32/libc.so.7 (0x282d4000)
        libthr.so.3 => /usr/lib32/libthr.so.3 (0x2844e000)
-> ldd /usr/local/php52/lib/php/20060613/mysql.so
/usr/local/php52/lib/php/20060613/mysql.so:
       libmysqlclient.so.16 => not found (0)
       libc.so.7 => /usr/lib32/libc.so.7 (0x28070000)
The constraints in libmap.conf are handled in rtld-elf with the help of
contexts, and especially a "$DEFAULT$" context is used for all entries
in libmap.conf before the first constraint statement. Now when rtld-elf
loads a program the mapping rules from libmap.conf are applied. In a
first step rtld-elf does a direct mapping using the correct context. But
in a second step called "Searching for ..." rtld-elf uses always the
"$DEFAULT$" context, which in the last example is empty. Therfore
rtld-elf does never find a library in his searching step and cannot load
programs where searching for libraries is necessary.
I cannot see any reason why rtld-elf should change the context between
step1 and step2, The following patch provokes that rtld-elf uses the
context from step1 in step2 too:
--- rtld.c.orig 2018-03-20 16:56:48.000000000 +0100
+++ rtld.c      2018-08-31 23:17:18.051206000 +0200
@@ -186,6 +186,7 @@
 static Obj_Entry obj_rtld;     /* The dynamic linker shared object */
 static unsigned int obj_count; /* Number of objects in obj_list */
 static unsigned int obj_loads; /* Number of loads of objects (gen count) */
+static char *save_refobj_path;
 static Objlist list_global =   /* Objects dlopened with RTLD_GLOBAL */
   STAILQ_HEAD_INITIALIZER(list_global);
@@ -1499,6 +1500,7 @@
     if (libmap_disable || !objgiven ||
        (name = lm_find(refobj->path, xname)) == NULL)
        name = (char *)xname;
+    save_refobj_path = refobj->path;
     dbg(" Searching for \"%s\"", name);
@@ -2831,7 +2833,7 @@
        char  *res;
        len = strcspn(path, ":;");
-       trans = lm_findn(NULL, path, len);
+       trans = lm_findn(save_refobj_path, path, len);
        if (trans)
            res = callback(trans, strlen(trans), arg);
        else
This patch solves the described problem for me.
Andreas Longwitz
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5B89C1E7.4090002>
