Skip to content
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

Guidance for unsupported DT_RPATH / DT_RUNPATH #188

Open
JonathonReinhart opened this issue Oct 3, 2021 · 7 comments
Open

Guidance for unsupported DT_RPATH / DT_RUNPATH #188

JonathonReinhart opened this issue Oct 3, 2021 · 7 comments

Comments

@JonathonReinhart
Copy link
Owner

JonathonReinhart commented Oct 3, 2021

(Moved to https://staticx.readthedocs.io/en/latest/rpath.html)


This issue exists as a permalink to provide guidance for errors related to an unsupported use of DT_RPATH or DT_RUNPATH.

You might be here because you encountered the following error:

staticx: /path/to/libfoo.so uses unsupported DT_RUNPATH ('/usr/local/lib').
See https://github.com/JonathonReinhart/staticx/issues/188

The underlying issue is described in detail in #169. The auditing check which emits this error was added in #173.

You're receiving this error because one of the libraries that would be included in your staticx archive (either directly, or perhaps via your PyInstaller application bundle) uses a feature of the GNU dynamic linker/loader called RPATH or RUNPATH. This dynamic section entry allows a dynamic executable/library to augment/override the preconfigured library path list of the dynamic loader (ld.so). The problem is that RPATH and RUNPATH can circumvent staticx's ability to control the library path and can allow target-system libraries to be unexpectedly loaded, causing symbol errors or runtime crashes.

RPATH

RPATH is allowed as long as the path is relative to $ORIGIN (the directory where the dynamic executable lives).

If staticx is complaining about your RPATH, it's probably because your library is referencing an absolute path like /usr/local/lib. If staticx were to allow this, then the application, when run on a foreign system, would try to load some dependent libraries from the target path, and not the staticx bundle.

RUNPATH

RUNPATH is always forbidden. This is because RUNPATH causes ld.so to completely disregard not only the RPATH set by staticx at program launch, for loading child dependencies of that library.

What to do

staticx tries as hard as it can to handle this, by removing RPATH and RUNPATH that it is bundling. staticx cannot, however, modify libraries the archive of an application bundled with PyInstaller. You can try to use a different build of Python or the problematic library, one which does not use RPATH or RUNPATH.

Feel free to open an issue detailing your problems, but please understand that this is not something that staticx can readily fix.

@JonathonReinhart JonathonReinhart changed the title Guidance for unsupported DT_RUNPATH Guidance for unsupported DT_RPATH / DT_RUNPATH Oct 4, 2021
@JonathonReinhart
Copy link
Owner Author

JonathonReinhart commented Oct 4, 2021

Please up-vote this comment if you are seeing this new error message and you are using GitHub Actions, specifically actions/setup-python.

Repository owner deleted a comment from jay0lee Oct 7, 2021
Repository owner deleted a comment from jay0lee Oct 7, 2021
Repository owner deleted a comment from jay0lee Oct 7, 2021
Repository owner deleted a comment from jay0lee Oct 7, 2021
@astrofrog
Copy link

astrofrog commented Oct 21, 2021

Does staticx stop at the first problematic RUNPATH it encounters? I am only getting one error but I suspect there will be more, and I would ideally like to understand the scale of the problem to see which dependencies need fixing or which libraries will need to be removed.

If staticx stops at the first error, would it be possible to add a mode where it will continue and show all the errors and then abort once all the auditing is done?


Edit by @JonathonReinhart: Addressed in #207.

@BerndDasByte
Copy link

BerndDasByte commented Nov 9, 2021

since staticx version v0.13.0 I get the following error message if I try to make a PyInstaller binary static:


One or more libraries included in the PyInstaller archive uses unsupported RPATH/RUNPATH tags:

  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/egldeviceintegrations/libqeglfs-emu-integration.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/egldeviceintegrations/libqeglfs-kms-egldevice-integration.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/egldeviceintegrations/libqeglfs-x11-integration.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/iconengines/libqsvgicon.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqgif.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqicns.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqico.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqjpeg.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqsvg.so: DT_RUNPATH='$ORIGIN/../../lib'
  /tmp/staticx-pyi-gg2sp8i5/PyQt5/Qt/plugins/imageformats/libqtga.so: DT_RUNPATH='$ORIGIN/../../lib'
  ...

With staticx versions below v0.13.0 I have no problems building from the same, PyInstaller binary ... What is the problem here?

@JonathonReinhart
Copy link
Owner Author

@BerndDasByte

With staticx versions below v0.13.0 I have no problems building from the same, PyInstaller binary ... What is the problem here?

The problem, as I believe has been thoroughly explained above, is that your PyInstalled binary includes libraries (In this case Qt5) which are linked with RUNPATH. Previously, staticx would have allowed this and produced executable, which when run, would potentially try to load libraries from the target system, which defeats the purpose (and guarantees) of StaticX. As described above, Staticx now tries to fix this problem by removing RPATH/RUNPATH where it can. However, if the problematic libraries are inside of a PyInstaller archive, then StaticX cannot easily modify (and thus does not modify) those.

The solution is not simple. You need to avoid libraries which link with RUNPATH. That may mean setting up a virtualenv and compiling them yourself. Unfortunately, I simply don't have the resources (i.e. time) right now to help much beyond that.

@Andrwe
Copy link

Andrwe commented Jan 31, 2022

Please up-vote this comment if you are seeing this new error message and you are using GitHub Actions, specifically actions/setup-python.

Died for me in Github action run https://github.com/Andrwe/accointing-convert/runs/5000354491.

Andrwe added a commit to Andrwe/accointing-convert that referenced this issue Jan 31, 2022
Switching to python3.8 to prevent
JonathonReinhart/staticx#188.

Signed-off-by: Andrwe Lord Weber <github@andrwe.org>
alekssamos added a commit to alekssamos/svrusoundbot that referenced this issue Oct 4, 2022
* skeep staticx, known problem

* spaces
JonathonReinhart/staticx#188
vbaltrusaitis-reef added a commit to vbaltrusaitis-reef/terraform-provider-b2 that referenced this issue Feb 16, 2023
setup-python GitHub action on Ubuntu is incompatible with staticx. See:
* actions/setup-python#325
* JonathonReinhart/staticx#188
* https://staticx.readthedocs.io/en/latest/rpath.html

However, deadsnakes action installs Ubuntu package from PPA and it
doesn't cause this problem. Hence, we use this action for Python setup
on Ubuntu.
@joaompinto
Copy link

joaompinto commented Jun 28, 2023

Short update, hopefully github will be able to work on the related issue actions/setup-python#325 .
Meanwhile I will try to get some time to provide a GH action specially designed for the use if staticx,

@th3w1zard1
Copy link

th3w1zard1 commented Mar 9, 2024

RPATH
RPATH is allowed as long as the path is relative to $ORIGIN (the directory where the dynamic executable lives).

If staticx is complaining about your RPATH, it's probably because your library is referencing an absolute path like /usr/local/lib. If staticx were to allow this, then the application, when run on a foreign system, would try to load some dependent libraries from the target path, and not the staticx bundle.

I just don't understand... if the whole point is to statically link why not either A: copy the lib in question into the executable's directory or B: preferably, pack the lib into the executable binary. Why does staticX ERROR when the path isn't relative. Can't staticx just copy the lib somewhere relative?

RUNPATH
RUNPATH is always forbidden. This is because RUNPATH causes ld.so to completely disregard not only the RPATH set by staticx at program launch, for loading child dependencies of that library.

Same. Why is packing into the executable or moving into the executable's directory not an option?

I'm using pyinstaller to compile some scripts for cross-platform distribution. Half of those site-packages on linux use rpath/runpath, and after spending an hour trying to tweak the python installation, compiling from source, running patchelf, I'm not finding any solutions.

Workflow can be found here: https://github.com/NickHugi/PyKotor/blob/master/.github/workflows/publish_and_test_pykotor.yml

Runs that show the errors:
https://github.com/NickHugi/PyKotor/actions/runs/8211459842
https://github.com/NickHugi/PyKotor/actions/runs/8210899351/job/22459096677

The motivation behind using StaticX in my case was simply because I needed glibc to be static. Is there any way to make StaticX at least skip the libs that it can't statically link due to these runpath/rpath problems? Currently it just fast fails on the first one, and there's zero configuration on my end I can do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants