Richard W.M. Jones
2020-Feb-21 14:51 UTC
Re: [Libguestfs] alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
On Fri, Feb 21, 2020 at 01:19:34PM +0100, Florian Weimer wrote:> I think what confuses me is that keep talking about a single binary, but > clearly there is this separate vddk DSO, and there is talk of plugins. > So it seems to me that multiple files are involved already?nbdkit is a standalone binary that happens to be able to load plugins from a well-known path, eg nbdkit-vddk-plugin.so. nbdkit knows the path for plugins, and there's a wrapper allowing it to get local plugins even when it's still in the build directory. Adding another file would mean another path (or overloading the meaning of the plugin path) and just makes the whole thing more fragile and complex. Having said all that, what would also solve this is either an API for updating LD_LIBRARY_PATH after the program has started; or making setenv ("LD_LIBRARY_PATH",...) DTRT*; or some kind of dlopen() variant which takes a library path as an extra parameter. Rich. * “Why does setenv ("LD_LIBRARY_PATH") not work?” has several stackoverflow answers. Apparently even the JDK has to work around this by re-execing. https://www.google.com/search?q=setenv+%22LD_LIBRARY_PATH%22+site:stackoverflow.com -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html
Florian Weimer
2020-Feb-21 15:00 UTC
Re: [Libguestfs] alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
* Richard W. M. Jones:> On Fri, Feb 21, 2020 at 01:19:34PM +0100, Florian Weimer wrote: >> I think what confuses me is that keep talking about a single binary, but >> clearly there is this separate vddk DSO, and there is talk of plugins. >> So it seems to me that multiple files are involved already? > > nbdkit is a standalone binary that happens to be able to load plugins > from a well-known path, eg nbdkit-vddk-plugin.so. nbdkit knows the > path for plugins, and there's a wrapper allowing it to get local > plugins even when it's still in the build directory. Adding another > file would mean another path (or overloading the meaning of the plugin > path) and just makes the whole thing more fragile and complex. > > Having said all that, what would also solve this is either an API for > updating LD_LIBRARY_PATH after the program has started; or making > setenv ("LD_LIBRARY_PATH",...) DTRT*; or some kind of dlopen() variant > which takes a library path as an extra parameter.Have you tried adding DT_RUNPATH or DT_RPATH to nbdkit-vddk-plugin.so? Or does the path have to be chosen dynamically? If you merely want to prevent loading of libstdc++.so or libcrypto.so by vddk, it may be possible to explicitly dlopen DSOs of that name before loading vddk. But there is an existing bug where we do not duplicate properly on soname alone, so we may have to fix that first. Thanks, Florian
Richard W.M. Jones
2020-Feb-21 15:39 UTC
Re: [Libguestfs] alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
On Fri, Feb 21, 2020 at 04:00:30PM +0100, Florian Weimer wrote:> * Richard W. M. Jones: > > > On Fri, Feb 21, 2020 at 01:19:34PM +0100, Florian Weimer wrote: > >> I think what confuses me is that keep talking about a single binary, but > >> clearly there is this separate vddk DSO, and there is talk of plugins. > >> So it seems to me that multiple files are involved already? > > > > nbdkit is a standalone binary that happens to be able to load plugins > > from a well-known path, eg nbdkit-vddk-plugin.so. nbdkit knows the > > path for plugins, and there's a wrapper allowing it to get local > > plugins even when it's still in the build directory. Adding another > > file would mean another path (or overloading the meaning of the plugin > > path) and just makes the whole thing more fragile and complex. > > > > Having said all that, what would also solve this is either an API for > > updating LD_LIBRARY_PATH after the program has started; or making > > setenv ("LD_LIBRARY_PATH",...) DTRT*; or some kind of dlopen() variant > > which takes a library path as an extra parameter. > > Have you tried adding DT_RUNPATH or DT_RPATH to nbdkit-vddk-plugin.so? > Or does the path have to be chosen dynamically?To be clear, the situation is: nbdkit (free) -> dlopens nbdkit-vddk-plugin.so (free) -> dlopens libvixDiskLib.so (proprietary) -> dlopens other proprietary plugins -> both libvixDiskLib.so and its plugins have DT_NEEDED "libstdc++.so.X" and other objects that have odd/old compiled versions in its own directory It's the proprietary library libvixDiskLib.so (colloquially known as "VDDK") which has trouble opening its own plugins. I guess you mean adding DT_* to the proprietary library? We don't distribute the proprietary library, end users have to choose to accept the terms of the (very poisonous) license on that library and so they download and install it themselves and just give us a path where they installed it. With all this low quality proprietary software involved I don't expect there's going to be a clean way to solve this, was really only wondering if there's a better way than re-execing the whole program. But we do at least have the re-exec working now.> If you merely want to prevent loading of libstdc++.so or libcrypto.so by > vddk, it may be possible to explicitly dlopen DSOs of that name before > loading vddk. But there is an existing bug where we do not duplicate > properly on soname alone, so we may have to fix that first.Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Eric Blake
2020-Feb-21 20:21 UTC
Re: [Libguestfs] alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
On 2/21/20 9:00 AM, Florian Weimer wrote:> * Richard W. M. Jones: > >> On Fri, Feb 21, 2020 at 01:19:34PM +0100, Florian Weimer wrote: >>> I think what confuses me is that keep talking about a single binary, but >>> clearly there is this separate vddk DSO, and there is talk of plugins. >>> So it seems to me that multiple files are involved already? >> >> nbdkit is a standalone binary that happens to be able to load plugins >> from a well-known path, eg nbdkit-vddk-plugin.so. nbdkit knows the >> path for plugins, and there's a wrapper allowing it to get local >> plugins even when it's still in the build directory. Adding another >> file would mean another path (or overloading the meaning of the plugin >> path) and just makes the whole thing more fragile and complex. >> >> Having said all that, what would also solve this is either an API for >> updating LD_LIBRARY_PATH after the program has started; or making >> setenv ("LD_LIBRARY_PATH",...) DTRT*; or some kind of dlopen() variant >> which takes a library path as an extra parameter. > > Have you tried adding DT_RUNPATH or DT_RPATH to nbdkit-vddk-plugin.so?Post-processing an existing closed-source .so shipped from an external vendor might have negative consequences - while it may be possible to modify the ELF image to add a DT_RUNPATH entry or modify the DT_NEEDED entries to use anchored names based on $ORIGIN rather than bare names, there's no telling if such modification would be in violation of agreements or even cause failure to load if the proprietary code is using shenanigans like validating a checksum of shipped binaries to detect tampering.> Or does the path have to be chosen dynamically?So, since we cannot fix the existing product, and have no idea if/when the vendor will release an updated version that has saner libraries, a dynamic search path is the only option to getting their product to load (but whether that is done by LD_LIBRARY_PATH, LD_AUDIT, pre-loading libraries, or something else, is where we have a bit more control).> > If you merely want to prevent loading of libstdc++.so or libcrypto.so by > vddk, it may be possible to explicitly dlopen DSOs of that name before > loading vddk. But there is an existing bug where we do not duplicate > properly on soname alone, so we may have to fix that first.The problem then becomes "given an arbitrary libvixDiskLib.so, how do we determine the dependency of bare libraries it would want to load so that we can pre-emptively load those libraries by direct path name first". My re-exec solution was nice - it works for all versions of VDDK. Whereas with scraping the binary to see what DT_NEEDED entries it has is a bit more image-specific: for example, VDDK 5.5.5 loads "libcrypto.so.1.0.0", VDDK-6.5 loads "libcrypto.so.1.0.2". I don't want to hard-code any of those library names into nbdkit-vddk-plugin.so, because that would needlessly tie the open source program into a specific VDDK release, instead of working with all of them. However, if it is easy enough to compute our own topological sort of DT_NEEDED for a given VDDK .so, and then pre-load in leaf-first order, so that by the time we finally get around to dlopen()ing libvixDiskLib.so and calling its init function, then all of the subsequent dlopen()s performed by VDDK code will succeed right off the bat because the library has already been loaded in memory. Or at least, that's what I'm hoping your suggesting. And if we do that, it would avoid the need to re-exec with LD_LIBRARY_PATH set. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Reasonably Related Threads
- Re: alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
- Re: alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
- Re: alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
- Re: alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?
- alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?