-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle new DT_RUNPATH in object::load_needed() #1039
Comments
Actually the reason for the original failure is different but related. It turns out we are properly handling symlinks by using the canonicalize() function which is uses realpath() and is called by program::load_object(). @nyh I bet if you ran unmodified java from your Fedora it would have worked just fine. Here is what I saw after adding printf() to _pathname in load_needed():
when calling with command line referencing /usr/bin/java that was a symlink. Now the real issue shows up on Ubuntu when we see DT_RUNPATH in java:
And we actually do not handle it at all. Per this - "Finding shared libraries at run time" DT_RUNPATH is a newer version of DT_RPATH. The only difference is that it should be resolved after LD_LIBRARY_PATH which I am not sure it matters to us. |
@wkozaczuk interesting. I think you're right. I missed that |
Issue discovered and analyzed by @wkozaczuk when he was trying to run an unmodified Java taken as a PIE from a Linux distribution.
works fine, but
fails, because it cannot find libjli.so (to see that, add -V to the command line). Why does this happen?
If we look at
readelf -a java
, we seeThe thing is, the requirement
libjli.so
is not found in the system's main library directories. Rather the RPATH says where it is, and $ORIGIN is replaced by the executable's path. And we actually handle correctly incore/elf.cc
. Or almost correctly - when the executable is a symbolic link, we need to resolve what it links to, and use that as $ORIGIN, not the link's path.This means checking with
readlink(_pathname)
if this is a link and if so using the result. But it's not enough to do it once: we may have a link to a link, and so on, so we need to do this repeatedly as long as we still have a link - but use a limit, to avoid infinite iteration in case of link loops.Interestingly, as others noted before (e.g., https://enchildfone.wordpress.com/2010/03/23/a-description-of-rpath-origin-ld_library_path-and-portable-linux-binaries/), Linux's "ldd" has this same bug. For example, on my host,
Note that
/usr/bin/java
is a symbolic link, andlibjli.so
is not found by ldd!Here too, /usr/bin/java is actually a link to a link (!) to
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.fc29.x86_64/jre/bin/java
and if I doldd /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-0.fc29.x86_64/jre/bin/java
, it does work fine:The text was updated successfully, but these errors were encountered: