Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Sep 2018 15:06:03 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Andreas Longwitz <longwitz@incore.de>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: Constraints in libmap(32).conf do not work as expected, possible bug in rtld-elf
Message-ID:  <20180902120603.GI2340@kib.kiev.ua>
In-Reply-To: <5B89C1E7.4090002@incore.de>
References:  <5B89C1E7.4090002@incore.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Sep 01, 2018 at 12:32:07AM +0200, Andreas Longwitz wrote:
> 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:
I am having problem understanding what do you mean by step1/step2. The
refobj reference that you cache in the patch, comes into load_object()
as the pointer to the object which initiate the load_object() call. It
is NULL for preloaded objects, otherwise it is not.
So, could you, please, explain where does it get passed as NULL in your
case ?

Also, your patch makes the ref_object stuck for all future invocations
of the load_object(), so it cannot be correct for this reason alone.

Another note is that libmap.conf use that you put it for, is quite the
strengthen of the original purpose.  You should just add the pathes
with your libraries to LD_32_LIBRARY_PATH or configure them into
/var/run/ld-elf32.so.hints using 'ldconfig -32'.

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180902120603.GI2340>