JonathonReinhart / staticx

Create static executable from dynamic executable
https://staticx.readthedocs.io/
Other
345 stars 37 forks source link

NODEFLIB insufficient for preventing use of target system libs, specifically when any library uses RUNPATH #169

Open JonathonReinhart opened 3 years ago

JonathonReinhart commented 3 years ago

138 sets NODEFLIB on the user app (the root of the dynamic object tree) in an attempt to prevent libraries from the target system from ever being loaded. This, coupled with RPATH, was supposed to give the (runtime patched) app complete control over the set of libraries loaded.

The problem is that if any object down the tree has RUNPATH set, not only is the root RPATH ignored, but somehow NODEFLIB seems to be ignored too! I don't actually see this in the source code yet, but it's a bit hard to follow.

See https://github.com/JonathonReinhart/staticx/issues/159#issuecomment-711414273 where I originally figured all of this out.


One might think that the solution would be for Staticx to use RUNPATH instead, but alas, that only applies to the object on which it is applied, and not the tree.

From this comment:

The trouble with RUNPATH and the reason we won’t use it is that it’s search semantics are fundamentally broken. It isn’t just a difference in precedence. Whereas an RPATH’d binary will search its RPATH, it’s loading object’s RPATH, all the way up to the executable if need be, RUNPATH gives up after searching the RUNPATH of the object itself. This means that the executable can’t enforce consistent link semantics...

In other words:


This is extremely discouraging. I'm running out of tricks for defeating GLIBC.

Damn you, @drepper! :smiling_imp: (Reference: https://github.com/bminor/glibc/commit/fcf70d4114db9ff7923f5dfeb3fea6e2d623e5c2)

My original comment had some half-baked ideas for fixing/working-around/acknowledging this.

JonathonReinhart commented 3 years ago

RPATH is also a problem: https://github.com/JonathonReinhart/staticx/pull/173#pullrequestreview-769556242