LD_AUDIT is broken on amd64
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
eglibc (Ubuntu) |
Fix Released
|
Undecided
|
Adam Conrad | ||
Precise |
Won't Fix
|
Undecided
|
Unassigned | ||
Quantal |
Won't Fix
|
Undecided
|
Unassigned |
Bug Description
[Impact]
LD_AUDIT is an "auditing interface" for the dynamic linker (ld.so), which allows an audit library specified in that environment variable to register hooks for loading and unloading objects, resolving relocations, and calling functions across dynamic libraries. It is particularly useful as a debugging tool; the command "latrace" is based on this functionality. It is also useful for making certain runtime changes to how libraries or symbols are resolved, similar to LD_PRELOAD but more powerful. See rtld-audit(7) for details.
In glibc before 2.17 (i.e., Precise and Quantal), on amd64, almost any use of LD_AUDIT on amd64 crashes with the following backtrace:
[1538449.702152] python[13400]: segfault at 60 ip 00007fdeaa97e8a3 sp 00007ffffd50bb00 error 4 in ld-2.15.
(gdb) bt
#0 _dl_profile_fixup (l=0x7fdeaab679d8, reloc_arg=3, retaddr=
#1 0x00007fdeaa9856e8 in _dl_runtime_profile () at ../sysdeps/
...
In particular, l->l_reloc_result is NULL, and ld.so proceeds to dereference it.
That code has since been patched upstream with the following comment:
if (l->l_reloc_result == NULL)
{
/* BZ #14843: ELF_DYNAMIC_
is allocated. We will get here if ELF_DYNAMIC_
resolver function to resolve an IRELATIVE relocation and that
resolver calls a function that is not yet resolved (lazy). For
example, the resolver in x86-64 libm.so calls __get_cpu_features
defined in libc.so. Skip audit and resolve the external function
in this case. */
The referenced upstream bug (which unfortunately doesn't mention that it's fixed) is
http://
The full upstream commit is
http://
and only adds that one if statement and a test case.
[Test Case]
Install the latrace package, and try to trace anything that links libm.so (as described above) or anything else using the same functionality. `python -c 1` is a good test. Note that it segfaults:
salmon-
python finished - killed by signal 11
The expected result is tracing output. Taken from an schroot with the fix applied:
(precise-
30242 _dl_get_
30242 getrlimit [/lib/x86_
30242 __libc_dl_error_tsd [/lib/x86_
30242 __libc_pthread_init [/lib/x86_
...
You can also test this with a simple LD_AUDIT module:
salmon-
unsigned int la_version(unsigned int version)
{
return version;
}
salmon-
salmon-
Segmentation fault (core dumped)
[Regression Potential]
It seems highly unlikely to me that this patch introduces the possibility of regression: it checks for a NULL in a case where ld.so was previously not checking and instead dereferencing the NULL pointer, so we were already going to crash if we hit the code added by this patch.
Changed in eglibc (Ubuntu): | |
assignee: | nobody → Adam Conrad (adconrad) |
status: | New → Fix Released |
Here's a debdiff that backports that one commit from upstream. I've tested that it fixes the bug inside a Precise chroot. I'm also currently rebuilding on Quantal, which is what I use on my desktop at the moment, and run with that for a bit.