From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 16835 invoked from network); 13 Jan 2022 03:46:52 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 13 Jan 2022 03:46:52 -0000 Received: (qmail 7206 invoked by uid 550); 13 Jan 2022 03:46:50 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 7170 invoked from network); 13 Jan 2022 03:46:49 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucsc.edu; s=ucsc-google-2018; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=ESLzzUaDGdxkB9wo9SIHzKjcAAzBbauJMx8o282I8iU=; b=n1Vc4WNjRYBa0rahptLpHm17vy+Ih6tEhUd03tUQtWpLBaJsSUy+5ujsQnCaYf9ZZk zaMHPIR+3sNkLB/jo/q5Un0n5KRs9gMWyNaScSIO8PBUkBplsLf39WWAqg1Df301TnCq lperHlXKGbBgHg+UOfloh3nVOPgY6ySwWl5ftZU9YIbmqpe5UXaDJcaoIf7fGk6BA6LR rE8EJtNpf93Yo/nlqQ96sBfQiM/gBDm/eSINcLda2CFdXOMKiW/88buHgLFNocaAnCVj Rhfq5Q8sjEBDo7qsJaXs7dLaWm5El4jjKAOYw1cJXYCdAn9pB6CpsXl42Hg5vW7oQf/Z lF9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=ESLzzUaDGdxkB9wo9SIHzKjcAAzBbauJMx8o282I8iU=; b=2VKpy46z8u7eTV+9nkDPtLrAnZuFQC5IuJPnXNF4K3Ws+F4k9z5+nMEEAO7M2aflMA rITgP7GiLOBDG09ESFzN+hZfkGM/eLj9Y7ASbZZhtvMjbPy8xh/ZC67D/kIroLLuwjCx c5+aZYnVF41gkrveQSqvqWtc4v1PmAHELn7bR8d05oL86AP6K2pFk1qGvjbE4xm8hREg buIZPTYasobtz+KwyKgpeFlaFv1zO9b0Ed283M8QWtBbcGMCsxd481PC9Y0/1C+U9fsi fkERKW5suxE9oDs3vUiNccw43tRK+LinayU30GgUKRURilsv+NWJSS6yninKnN981oBC oK+g== X-Gm-Message-State: AOAM531L6I16gOaUjXMWaGyE1J1wZTcosmPg6BFKFwK4732nfKof8NH0 NbW9IxXNikN/XfA6QBGwBEu+e3pvwP92AjZ5/PKDXA== X-Google-Smtp-Source: ABdhPJxJVVpbvb5UV6Yyuj8m0s4bjKsFvAU0Q8v1aQCFx2HvHNNV0/GKSyP17jsC6jBmC72Jpb9xoLhl2gkJl76ksZI= X-Received: by 2002:a25:8e89:: with SMTP id q9mr4125944ybl.520.1642045597644; Wed, 12 Jan 2022 19:46:37 -0800 (PST) MIME-Version: 1.0 References: <20220113032953.GX7074@brightrain.aerifal.cx> In-Reply-To: <20220113032953.GX7074@brightrain.aerifal.cx> From: Farid Zakaria Date: Wed, 12 Jan 2022 19:46:26 -0800 Message-ID: To: Rich Felker Cc: musl@lists.openwall.com, "Scogland, Tom" , me@harmenstoppels.nl, Carlos Maltzahn Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [musl] is RUNPATH being incorrectly inherited inherited? Hi Rich, Thank you for taking the time to read my email and responding. I was worried it was a bit too pedantic in explanation and I had had some trivial error in the setup. (I am only beginning to gain deeper knowledge on linking) On Wed, Jan 12, 2022 at 7:29 PM Rich Felker wrote: > > On Wed, Jan 12, 2022 at 05:29:57PM -0800, Farid Zakaria wrote: > > Hello, > > > > I'm observing a strange behavior and it seems to contradict what > > ld.so[1] says should be the case for RUNPATH, namely I am observing > > that musl's dynamic linker seems to use the DT_RUNPATH of the > > executable when searching for entries of its children. > > I thought this was documented somewhere but maybe it's not. musl does > not have separate RPATH/RUNPATH behaviors. The clearly wrong part of > the legacy RPATH behavior (order relative to LD_LIBRARY_PATH) is not > followed, and the rationale stated at the time this was implemented in > musl was that the only justification for the old behavior there was > compatibility with existing binaries, which was not an issue for musl. > > On the other hand, the glibc RUNPATH behavior of ignoring the > dependent DSO's (or main app's) RUNPATH when loading indirect > dependencies completely breaks the ability to set a RUNPATH in the > application to use a *set* of unmodified library binaries in a > particular application-specific path. I'm surprised you found an > instance where that's what you want, since as far as I could tell at > the time it was an unwanted change. > > > > Using the directories specified in the DT_RUNPATH dynamic section > > > attribute of the binary if present. Such directories are searched > > > only to find those objects required by DT_NEEDED (direct > > > dependencies) entries and do not apply to those objects' children, > > > which must themselves have their own DT_RUNPATH entries. This is > > > unlike DT_RPATH, which is applied to searches for all children in > > > the dependency tree. > > > > I've uploaded a Makefile[2] that you can use to follow along. > > > > First let's build the binary. It's designed to depend on two shared > > libraries _libx.so_ and _liby.so_; _liby.so_ also depends on _libx.so_ > > > > Note: that I make the top-level _libx.so_ an absolute path using patche= lf. > > > > ``` > > # build it > > $ make CC=3Dmusl-gcc > > > > # let's inspect it to see what it looks like > > # here we can see the needed, including the one absolute > > $ patchelf --print-needed exe > > liby.so > > /home/fzakaria/code//c/libx.so > > libc.so > > > > # here is the RUNPATH > > $ patchelf --print-rpath exe > > $ORIGIN/b:$ORIGIN/c > > > > # an alternate query > > $ objdump -x ./exe | grep RUNPATH > > RUNPATH $ORIGIN/b:$ORIGIN/ > > > > # here is a dependent library > > $ patchelf --print-needed b/liby.so > > libx.so > > libc.so > > > > # liby.so has no RUNPATH > > objdump -x b/liby.so| grep RUNPATH > > ``` > > > > I would expect this *to not work* since there is no way for liby.so to > > discover libx.so, especially given the previous correspondence on the > > mailing lists on how musl does not utilize soname for the cache. > > > > However you can see that the linker is trying to resolve _libx.so_ > > using the RUNPATH when it is loading _liby.so_ > > > > ``` > > $ strace -e openat,stat,open ./exe > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/b= /liby.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/c= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/b= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D -1 ENOENT (No such file or > > directory) > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/c= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > 24 > > +++ exited with 0 +++ > > ``` > > > > Harmen's libtree[3] already fails to find the library. > > ``` > > $ libtree exe > > exe > > =E2=94=9C=E2=94=80=E2=94=80 libx.so [direct] > > =E2=94=94=E2=94=80=E2=94=80 .//b/liby.so [runpath] > > =E2=94=94=E2=94=80=E2=94=80 libx.so not found > > =E2=94=8A Paths considered > > ``` > > > > To me this means that the ld.so here is not respecting the description > > of not propagating the search paths to the children. > > Yes, that's intentional. Is this something you want not to happen? This specific case, I only brought up after having read the manpage for linux-ld/ld.so on my quest to better understand dynamic linkers. It does seem that other tools are making similar assumptions however (libtree) when trying to replicate the search pattern employed by a linker. The rationale you mention about the ability to set a single top-level RUNPATH is desirable however I do find the delta between what's documented for ld.so to have been confus= ing. I am as part of some research evaluating other alternatives to how to specify link-paths and part of that research direction involves more explicitly specifying whether a path should/should not be inherited; in addition to a few other ideas. It's clear you are aware of this discrepancy and it was done so knowingly. At least I know I was not mis-understanding the results of my setup :) > > FWIW, as per the other correspondence, if I remove part of the > > RUNPATH, then the binary fails to load even though _libx.so_ was > > already present. > > This is expected given the current lack of SONAME processing because, > while it's present, it's not tracked as being "what you should get by > resolving the name libx.so". If we do adopt SONAME processing here it > would be found, and would necessarily preclude any path search from > happening since it would already be present. Presumably that's what > you would want to happen, right? Yes! This is more of an interesting quirk I find different between glibc whose functionality I think would make a positive addition. Happy to continue discussing this issue on the other mailing list emails :) > > > > ``` > > $ patchelf --print-rpath exe > > $ORIGIN/b > > > > $ /exe > > Error loading shared library libx.so: No such file or directory > > (needed by /home/fzakaria/code/playground/cpp/musl-experiment/experimen= t-2/b/liby.so) > > ``` > > > > Thank you. > > > > [1] https://man7.org/linux/man-pages/man8/ld.so.8.html > > [2] https://gist.github.com/fzakaria/375f2c27f2db000369ec49a684ef8095 > > [3] https://github.com/haampie/libtree > > Thanks for the example and for finding something that needs better > documentation (even if just, for now, on the wiki under > https://wiki.musl-libc.org/functional-differences-from-glibc.html) > > Rich On Wed, Jan 12, 2022 at 7:29 PM Rich Felker wrote: > > On Wed, Jan 12, 2022 at 05:29:57PM -0800, Farid Zakaria wrote: > > Hello, > > > > I'm observing a strange behavior and it seems to contradict what > > ld.so[1] says should be the case for RUNPATH, namely I am observing > > that musl's dynamic linker seems to use the DT_RUNPATH of the > > executable when searching for entries of its children. > > I thought this was documented somewhere but maybe it's not. musl does > not have separate RPATH/RUNPATH behaviors. The clearly wrong part of > the legacy RPATH behavior (order relative to LD_LIBRARY_PATH) is not > followed, and the rationale stated at the time this was implemented in > musl was that the only justification for the old behavior there was > compatibility with existing binaries, which was not an issue for musl. > > On the other hand, the glibc RUNPATH behavior of ignoring the > dependent DSO's (or main app's) RUNPATH when loading indirect > dependencies completely breaks the ability to set a RUNPATH in the > application to use a *set* of unmodified library binaries in a > particular application-specific path. I'm surprised you found an > instance where that's what you want, since as far as I could tell at > the time it was an unwanted change. > > > > Using the directories specified in the DT_RUNPATH dynamic section > > > attribute of the binary if present. Such directories are searched > > > only to find those objects required by DT_NEEDED (direct > > > dependencies) entries and do not apply to those objects' children, > > > which must themselves have their own DT_RUNPATH entries. This is > > > unlike DT_RPATH, which is applied to searches for all children in > > > the dependency tree. > > > > I've uploaded a Makefile[2] that you can use to follow along. > > > > First let's build the binary. It's designed to depend on two shared > > libraries _libx.so_ and _liby.so_; _liby.so_ also depends on _libx.so_ > > > > Note: that I make the top-level _libx.so_ an absolute path using patche= lf. > > > > ``` > > # build it > > $ make CC=3Dmusl-gcc > > > > # let's inspect it to see what it looks like > > # here we can see the needed, including the one absolute > > $ patchelf --print-needed exe > > liby.so > > /home/fzakaria/code//c/libx.so > > libc.so > > > > # here is the RUNPATH > > $ patchelf --print-rpath exe > > $ORIGIN/b:$ORIGIN/c > > > > # an alternate query > > $ objdump -x ./exe | grep RUNPATH > > RUNPATH $ORIGIN/b:$ORIGIN/ > > > > # here is a dependent library > > $ patchelf --print-needed b/liby.so > > libx.so > > libc.so > > > > # liby.so has no RUNPATH > > objdump -x b/liby.so| grep RUNPATH > > ``` > > > > I would expect this *to not work* since there is no way for liby.so to > > discover libx.so, especially given the previous correspondence on the > > mailing lists on how musl does not utilize soname for the cache. > > > > However you can see that the linker is trying to resolve _libx.so_ > > using the RUNPATH when it is loading _liby.so_ > > > > ``` > > $ strace -e openat,stat,open ./exe > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/b= /liby.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/c= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/b= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D -1 ENOENT (No such file or > > directory) > > open("/home/fzakaria/code/playground/cpp/musl-experiment/experiment-2/c= /libx.so", > > O_RDONLY|O_LARGEFILE|O_CLOEXEC) =3D 3 > > 24 > > +++ exited with 0 +++ > > ``` > > > > Harmen's libtree[3] already fails to find the library. > > ``` > > $ libtree exe > > exe > > =E2=94=9C=E2=94=80=E2=94=80 libx.so [direct] > > =E2=94=94=E2=94=80=E2=94=80 .//b/liby.so [runpath] > > =E2=94=94=E2=94=80=E2=94=80 libx.so not found > > =E2=94=8A Paths considered > > ``` > > > > To me this means that the ld.so here is not respecting the description > > of not propagating the search paths to the children. > > Yes, that's intentional. Is this something you want not to happen? > > > FWIW, as per the other correspondence, if I remove part of the > > RUNPATH, then the binary fails to load even though _libx.so_ was > > already present. > > This is expected given the current lack of SONAME processing because, > while it's present, it's not tracked as being "what you should get by > resolving the name libx.so". If we do adopt SONAME processing here it > would be found, and would necessarily preclude any path search from > happening since it would already be present. Presumably that's what > you would want to happen, right? > > > > > ``` > > $ patchelf --print-rpath exe > > $ORIGIN/b > > > > $ /exe > > Error loading shared library libx.so: No such file or directory > > (needed by /home/fzakaria/code/playground/cpp/musl-experiment/experimen= t-2/b/liby.so) > > ``` > > > > Thank you. > > > > [1] https://man7.org/linux/man-pages/man8/ld.so.8.html > > [2] https://gist.github.com/fzakaria/375f2c27f2db000369ec49a684ef8095 > > [3] https://github.com/haampie/libtree > > Thanks for the example and for finding something that needs better > documentation (even if just, for now, on the wiki under > https://wiki.musl-libc.org/functional-differences-from-glibc.html) > > Rich