patchelf icon indicating copy to clipboard operation
patchelf copied to clipboard

Add option to replace an imported symbol

Open raphaelr opened this issue 2 years ago • 12 comments

Is your feature request related to a problem? Please describe. Using the rpath arguments (e.g. --add-rpath), patchelf can override the location of libraries. However, libraries have other ways of depending on file system paths. A common example is drivers containing a hard-coded path to firmware binaries, which the library fopen()s.

Example: Broadcom fingerprint driver, the .so contains a hardcoded path to /var/lib/fprint/fw.

Currently it is difficult to replace such paths.

Describe the solution you'd like Add a new argument to patchelf, --replace-symbol NAME_ORIG NAME_NEW. If specified, patchelf will iterate over the symbol table (.dynsym section), and replace the symbol with the name NAME_ORIG with NAME_NEW, adding it to the .dynstr section if neccessary.

This allows one to replace the fopen call from the library with a wrapper function, which can inspect the path it receives and change it if neccessary.

Example invocation:

$ # assume that fopen_wrapper.c defines a `fopen_wrapper()` function with the same signature as `fopen()`
$ cc -fPIC -shared fopen_wrapper.c -o libfopen_wrapper.so
$ patchelf \
    --replace-symbol fopen fopen_wrapper \
    --add-needed libfopen_wrapper.so \
    libdriver.so

Describe alternatives you've considered

  • Use buildFHSUserEnv from nixpkgs to give the process the filesystem layout it needs.
  • Use LD_PRELOAD to inject the wrapper into the process.

These methods have the disadvantage that they affect an entire process tree, not just the single library that needs patching.

Additional context I have a prototype quality implementation of this feature. If this feature request is accepted, I'll clean it up and add tests/documentation for it.

Upstreaming of this feature has been requested by the iscan-snap project, which attempts to package scanner drivers using snap.

raphaelr avatar Oct 13 '22 17:10 raphaelr

Sorry for the late response. I just now catched up with the latest issues and PRs in the project again. This sounds like a useful feature to me, so I would accept it. Please also add a test and the documentation for it. Thanks.

Mic92 avatar Oct 26 '22 06:10 Mic92

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/writing-derivation-for-binary-driver-that-accesses-hard-coded-paths-in-the-fhs/22969/6

nixos-discourse avatar Nov 09 '22 11:11 nixos-discourse

This might be helpful: https://github.com/NixOS/patchelf/pull/459

brenoguim avatar Feb 19 '23 20:02 brenoguim

I think this can be closed after #459 was merged

brenoguim avatar Mar 02 '23 09:03 brenoguim

#459 is failing for me in https://github.com/RyanGibb/nixos/commit/62a7d093e617b37909f3713bd37b068b3e65e18a with: patchelf: error: Span access out of range.

RyanGibb avatar Mar 03 '23 14:03 RyanGibb

Thanks for reporting this! I'll investigate.

brenoguim avatar Mar 03 '23 14:03 brenoguim

Thank you @brenoguim!

You can build it (on x86_64-linux) with nix build github:ryangibb/nixos/cctk-patchelf-rename-dynamic-symbols#cctk (and nix build github:ryangibb/nixos#cctk with raphaelr's fork).

RyanGibb avatar Mar 03 '23 14:03 RyanGibb

Opened a PR with a fix: https://github.com/NixOS/patchelf/pull/473 I will add the test first and then make it ready to merge.

brenoguim avatar Mar 04 '23 16:03 brenoguim

It works!

RyanGibb avatar Mar 04 '23 16:03 RyanGibb

Oops, I force pushed. That might affect your patch (I don't know if the hash is still valid).

brenoguim avatar Mar 04 '23 17:03 brenoguim

Thanks for the heads up! I don't think github garbage collects repositories that often, but I'll update date it if it becomes an issue (and when it's merged anyway).

RyanGibb avatar Mar 04 '23 17:03 RyanGibb

I am getting the span access out of range with rename-dynamic-symbols.sh and I am building for s390x,

Error below,

[ 17s] renaming dynamic symbol f1450 to f1450_special_suffix [ 17s] patchelf: error: Span access out of range. [ 17s] FAIL rename-dynamic-symbols.sh (exit status: 1)

Created #503 for the same.

Duraisankarp avatar Jun 19 '23 13:06 Duraisankarp