[Libguestfs] alternatives for hooking dlopen() without LD_LIBRARY_PATH or LD_AUDIT?

Eric Blake eblake at redhat.com
Mon Feb 17 15:03:48 UTC 2020


On 2/14/20 3:29 PM, Eric Blake wrote:
> On 2/14/20 1:02 PM, Eric Blake wrote:
> 
>> Writing my own dlopen() wrapper directly in nbdkit seems like a 
>> non-starter (my override has to come from a shared library before it 
>> can replace the shared version that would be imported from -ldl, at 
>> least for all subsequent shared library loads that want to bind to the 
>> override).
> 
> Maybe I spoke too soon. I've tried another approach that looks like it 
> will do what I want: put my shim dlopen() in a shared library, but link 
> nbdkit against that shared library PRIOR to -ldl (so that name lookup 
> for dlopen resolves there first).  The shim library in turn depends on 
> -ldl so that dlsym(RTLD_NEXT, "dlopen") still lets me get to the real 
> dlopen.  And by linking it directly into nbdkit, rather than into the 
> nbdkit-vddk-plugin.so that gets loaded later, the first bound dlopen() 
> in use for all subsequent loads is from my shim.  It's still a bit less 
> clean than I'd like (it requires tighter coupling between nbdkit and 
> nbdkit-vddk-plugin.so than what used to exist), but the fact that it 
> works without dlmopen() or LD_LIBRARY_PATH is in its favor.  I'm now 
> polishing up the experiment, and will post the patch when it's ready.

Progress report: I've posted a v4 series that relies on a shared library 
in the main executable; but I'm still trying to see if I can further 
reduce things (maybe with -rdynamic) so that the main binary itself 
provides the dlopen() override without needing an auxiliary shared library.
https://www.redhat.com/archives/libguestfs/2020-February/msg00162.html

> But after spending more than an hour playing with la_objsearch() and reading 'man rtld-audit', it looks like an audit library cannot be triggered in glibc except by listing it in LD_AUDIT in the environment during exec - which is back to the same problem we have with needing LD_LIBRARY_PATH in the environment.  Furthermore, although I know that glibc's audit interface is slightly different from the Solaris version it copied from, the Solaris documentation states that an audit library has some rather tough restrictions (including that using 'malloc' is unsafe, https://docs.oracle.com/cd/E36784_01/html/E36857/chapter6-3.html#scrolltoc "Some system interfaces assume that the interfaces are the only instance of their implementation within a process. Examples of such implementations are signals and malloc(3C). Audit libraries should avoid using such interfaces, as doing so can inadvertently alter the behavior of the application.").  But Solaris also stated that a library could serve as an audit entry point without LD_AUDIT if it is registered locally, via -Wl,-paudit.so.1 when creating the shared library (https://docs.oracle.com/cd/E36784_01/html/E36857/chapter6-18.html#scrolltoc); it doesn't seem that this functionality exists with glibc (/usr/lib64/libaudit.so on Linux has nothing to do with rtld-audit). 

I'm just now noticing that 'man ld' reports that you may pass '--audit 
LIB' during linking to add a DT_DEPAUDIT dependency on a library 
implementing the audit interface, which sounds like it might be an 
alternative to LD_AUDIT for getting a library with la_objsearch() to 
actually do something (but doesn't obviate the need for la_obsearch() to 
be in a separate library, rather than part of the main executable, 
unless a library can be reused as its own audit library...).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




More information about the Libguestfs mailing list