php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #79220 Allow setting FFI_LIB search path at runtime
Submitted: 2020-02-04 11:47 UTC Modified: 2021-11-10 18:42 UTC
From: ojrask at gmail dot com Assigned:
Status: Open Package: FFI (PECL)
PHP Version: 7.4.2 OS: -
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ojrask at gmail dot com
New email:
PHP Version: OS:

 

 [2020-02-04 11:47 UTC] ojrask at gmail dot com
Description:
------------
Currently, when using the new FFI core extension, and loading dynamic libraries using the `FFI_LIB` header definition, the path is passed as is to `dlopen(3)`.

What this means is:

1. Absolute paths work as expected
2. Relative paths work from the current working directory (not changeable with PHP's `chdir`)
3. `LD_LIBRARY_PATH` works, but only if the PHP interpreter itself if invoked after adjusting the env var
4. `/lib` and `/usr/lib` work as expected.

The problem this poses is as follows:

Assume I want to create a new distributable PHP package, using Composer for instance. I want to bundle an FFI compatible dynamic library into the package itself.

Now, when someone installs the package, the files will be installed under the `vendor` directory of the project root they are working in. Hence the library path becomes something similar to `/home/user/projects/a/vendor/myvendor/mypkg/libs/lib.so`.

Now, when I want to use `FFI::load`, I am required to use the `FFI_LIB` define in my header file.

If the `lib.h` lives inside the package's `lib` directory, next to the `lib.so` library binary, I must take the following into consideration:

1. Cannot use `./lib.so`, as quite literally no one will run PHP from that directory
2. Cannot use absolute path, as there is no way of knowing it in advance
3. Cannot use `LD_LIBRARY_PATH` as that would require everyone to write their own wrappers for the PHP interpreter that sets the variable
4. Cannot use `/lib`, as I do not wish to pollute systems globally when installing a PHP package (Python has this problem by default, requiring juggling venvs 99% of the time)

So the only "builtin" option is to use `FFI::cdef`.

Is there any way to instruct the FFI extension to use additional search paths at runtime when loading libraries using the `FFI_LIB` definition?

My current hack to fix this goes as follows:

1. Load the raw text contents of the `lib.h` file
2. Replace the `FFI_LIB` path with an absolutized path using preg_replace or similar
3. Put the altered contents into a temporary `templib.h` file somewhere accessible (e.g. `/tmp`)
4. Use that file instead of the real `lib.h` file when doing `FFI::load(...)`.

This works and allows setting an absolute path to a library file at runtime. But this is a little hacky and I would like to see an official and supported method to do this.

Maybe something like

```
\FFI::setLibraryPaths(['/path/to/libs']); // maybe some `::resetLibraryPaths` could exist as well

// now dlopen should receive an absolute path to an `/path/to/libs/lib.so` file that was found, otherwise error out if not found, or maybe defer to regular `dlopen` logic

$ffi = \FFI::load(__DIR__ . '/lib/lib.h'); // lib.h has `FFI_LIB "lib.so" defined
```

Things I don't know about:

- Is my suggestion safe, as in do people understand what happens and what holes they might be opening up? Then again who knows how often malware and such can inject files into `/lib` in the first place.
- Would it make a dent in loading performance, if we need to glob `*.so` files in X number of user supplied directories?
- Or is this just an edge case and most of the time people will not be installing FFI Composer packages and hack together loading shims just like I did now?


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-10 18:42 UTC] cmb@php.net
-Package: Dynamic loading +Package: FFI
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 04:01:28 2024 UTC