Skip site navigation (1)Skip section navigation (2)
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>