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