]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
If dlopen() is called for the dso that has been already loaded as a
authorkib <kib@FreeBSD.org>
Wed, 3 Nov 2010 09:23:08 +0000 (09:23 +0000)
committerkib <kib@FreeBSD.org>
Wed, 3 Nov 2010 09:23:08 +0000 (09:23 +0000)
commit6ddde2168bc79a10ab0937ba69afe0a74559eea0
tree32512f3bc1869db4dad1920d6d6d20fa63b1d63e
parentd83519c991663fe77cf7bd81dbd86ef38d115065
If dlopen() is called for the dso that has been already loaded as a
dependency, then the dso never has its DAG initialized. Empty DAG
makes ref_dag() call in dlopen() a nop, and the dso refcount is off
by one.

Initialize the DAG on the first dlopen() call, using a boolean flag
to prevent double initialization.

From the PR (edited):
Assume we have a library liba.so, containing a function a(), and a
library libb.so, containing function b(). liba.so needs functionality
from libb.so, so liba.so links in libb.so.

An application doesn't know about the relation between these libraries,
but needs to call a() and b(). It dlopen()s liba.so and obtains a
pointer to a(), then it dlopen()s libb.so and obtains a pointer to b().

As soon as the application doesn't need a() anymore, it dlclose()s liba.so.

Expected result: the pointer to b() is still valid and can be called
Actual result: the pointer to b() has become invalid, even though the
application did not dlclose() the handle to libb.so. On calling b(), the
application crashes with a segmentation fault.

PR: misc/151861
Based on patch by: jh
Reviewed by: kan
Tested by: Arjan van Leeuwen <freebsd-maintainer opera com>
MFC after: 1 week
libexec/rtld-elf/rtld.c
libexec/rtld-elf/rtld.h