RFC: Auditor access to program headers
Jonathon Anderson
janderson@rice.edu
Thu Mar 17 20:16:11 GMT 2022
On 3/17/22 09:59, Florian Weimer wrote:
>> We propose two changes to support this use case:
>> - Addition of a new dlinfo request that fills a dl_phdr_info (or
>> similar) structure identically to how dl_iterate_phdr would. This
>> would enable access to a load module's program headers without use of
>> dl_iterate_phdr.
> The existing dlinfo requests are problematic (origin and search path
> information access suffers from buffer overflows), and these
> type-polymorphic dispatchers are never great. At least for program
> header lookup, it's possible to detect the unsupported request even
> though the current implementation does not report any errors in that
> case (the dlinfo caller needs to write a null pointer and check if it
> has been overwritten). So it looks a feasible short-term solution.
The current implementation does error on unsupported requests, and
AFAICT has since the initial implementation in 2003:
switch (args->request)
{
case RTLD_DI_CONFIGADDR:
default:
_dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo
request"));
break;
Adding a new dlinfo request should work well enough for our purposes,
we'll keep a runtime fallback in case the request isn't supported.
For my own curiosity, what would you consider for a longer-term solution?
>> - A fix for the bug that causes dl* functions to crash in early
>> auditor notifications (one of our Tier 2 issues). This is required to
>> allow use of dlinfo within an auditor. Fixing this involves adjusting
>> rtld_active to return true during auditor notifications in dl_main.
> Almost all rtld_active calls can go away in glibc 2.34 because
> GLRO (dl_dlfcn_hook) is now in read-only memory. That change isn't
> quite backportable because throughly breaks static dlopen. But
> rtld_active could simply check some other _rtld_global_ro field
> in earlier glibc version.
Great! We'll be happy to test when it's available.
>> For additional clarity, it would also be helpful to have either:
>> - documentation that a link_map* is in fact a dlopen handle and thus
>> can be passed to any dl* function in current and future versions of
>> Glibc, or
> I think we can promise that every link map pointer provided by glibc can
> be used as a dlopen handle (during its life-time).
I believe this direction is the only one missing,
dlinfo(RTLD_DI_LINKMAP) exists for the other direction.
> The other direction
> (every handle returned by dlopen is a link map) might be more
> complicated. But perhaps we can at least commit to providing the public
> link map fields (as seen in the installed <link.h>).
>
>> - the prototype of la_objopen altered to take a void* dlopen handle
>> instead of a link_map* (which AFAIK currently has no or minimal ABI
>> impact).
> It's a source-incompatible change, though, because we declare la_objopen
> in <link.h>. So perhaps we can avoid it.
It's source-incompatible, though IMHO it's an easy configure test and a
very minor source change. If Glibc can't commit to keeping link_map*
usable as a dlopen handle (eg. for possible future security concerns),
this prevents the possibility that auditors could get "locked out" of
the dl* functions.
Thanks,
-Jonathon
More information about the Libc-alpha
mailing list