Red Hat Bugzilla – Bug 70407
RFE: use _r_debug.r_brk to call _dl_debug_state (with patch)
Last modified: 2007-04-18 12:45:03 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529
Description of problem:
By using _r_debug.r_brk to call _dl_debug_state(), the dynamic linker can
cooperate better with a same-process debugger when giving notice about modules
added and removed.
On some architectures and with some compiler optimization levels, such as gcc
-O3 on x86, _dl_debug_state() can occupy less space than is required for
overwriting it with a transfer of control to an arbitrary address, making it
hard for a same-process debugger to get notice of changed modules. A
controlling-process debugger, such as gdb, has little trouble overwriting with a
breakpoint instruction and intercepting SIGTRAP. But when a same-process program
analysis tool uses this technique, then gdb cannot be used at the same time.
It's also more convenient to get a direct call.
The attached ChangeLog entry and patch against glibc-2.2.90-17.src.rpm enhance
struct r_debug by changing r_brk from just an address to a full function
pointer, by being slightly more careful of existing values when setting them,
and by using .r_brk to call _dl_debug_state.
The absolute layout of the bits in struct r_debug could be binary compatible
with previous versions on those machines for which the size of a function
pointer is the same as the size of an address. But implementations such as
PowerPC and ia64 carry two addresses in a function pointer, which makes the new
struct larger, and changes some offsets. The type change for .r_brk also argues
for a new .r_version number.
[Substantially the same info has been entered as libc/4223 in the GNU gnats
, and the patch attached here in bugzilla already contains the correction for
dl-close.c which was emailed to GNU.]
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1.Run same-process debugger (co-resident in the address space with the program
being analyzed) when ld-linux.so.2 has been compiled with gcc 3.1 at -O3, and
_dl_debug_state() occupies only 1 byte ("ret") on i386, and next function begins
immediately at 1+(char *)&_dl_debug_state .
Actual Results: Must use 'int3' at _dl_debug_state(), and SIGTRAP handler, to
get notice from ld-linux.so.2 about changed modules. Using SIGTRAP hander means
that gdb cannot be run at the same time, and also interferes with those programs
that want to use SIGTRAP.
Expected Results: Easy interception of call to _dl_debug_state() by setting
_r_debug.r_brk after mapping ld-linux.so.2 but before invoking ld-linux.so.2 .
Created attachment 68130 [details]
patch to implement enhancement (ChangeLog entry, diff -u)
We never will add any kind of change which allows exploiting internals. It is
none of your business to poke in there. If you still do, it is 100% your
problem and responsibilit. We'll not pay any attention to this when making
changes. It might just break at the next update.