This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Detecting multiple libcs


On 06/03/2016 02:10 PM, Florian Weimer wrote:
> On 06/03/2016 06:50 PM, Carlos O'Donell wrote:
>> On 06/03/2016 10:50 AM, Florian Weimer wrote:
>>> ptmalloc_init has this code:
>>>
>>> #ifdef SHARED
>>>   /* In case this libc copy is in a non-default namespace, never use brk.
>>>      Likewise if dlopened from statically linked program.  */
>>>   Dl_info di;
>>>   struct link_map *l;
>>>
>>>   if (_dl_open_hook != NULL
>>>       || (_dl_addr (ptmalloc_init, &di, &l, NULL) != 0
>>>           && l->l_ns != LM_ID_BASE))
>>>     __morecore = __failing_morecore;
>>> #endif
>>>
>>> But it does not seem t work because after a static dlopen, _dl_open_hook is NULL.
>>
>> Just to be clear, you have verified that the value of _dl_open_hook is NULL
>> for the copy of that variable in the newly loaded library?
> 
> I thought I had. I'm no longer sure. The test case passes now. I
> probably had botched something along the way.
> 
> __libc_multiple_libcs is 0, though (although gdb prints 1 because it
> uses the variable in the outer namespace).

That's unfortunate. I would have expected gdb to know the shared library
it is loaded in and use that link map to find the inner value. Did you
inspect the value of __libc_multiple_libcs while executing code inside
the the inner-most libc?

> We have a larger problem, though:
> 
> (gdb) info symb &_dl_open_hook
> _dl_open_hook in section .bss of /lib64/libc.so.6
> (This is from a regular dynamically linked executable.)
> This pointer variable should really be in the .relro section.

Agreed.

> The existing patching mechanism for static dlopen uses a dlsym lookup
> in the new namespace, and just patches in the intended value (with
> _dl_open_hook and _dlfcn_hook). It would be nice to have these
> pointers in .relro instead, but that needs significant changes. With
> the current approach, it seems that the patching happens really late,
> after ELF constructors from the new DSOs have already run.

Yes, the calls to __libc_register_* happen last in __dlopen.

I can't think of any strong reason it happens last, other than it was
simple enough to add the calls to __dlopen after you had the link map
(and after you knew dlopen succeeded).

To put it in RELRO you would need to push the calls to 
__libc_register_dl_open_hook, and __libc_register_dlfcn_hook into the
callee past the point at which you have a linkmap setup and ready to
use, modify the variables, and then let RELRO finish marking it
read-only.

> Does the above seem more reasonable?  (I'm apparently quite confused today.)

Yes.

> As a stop-gap measure, we could mangle the hook pointers. The pointer
> guard value is derived from AT_RANDOM on both sides of the linking
> barrier, so the mangling will be identical.

Agreed.

-- 
Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]