mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 09:30:24 +00:00
4b091a7cc2
Consider the situation where two shared libraries libA and libB, both depending (as in having a NEEDED dtag) on libC. libA is first dlopen()-ed, which produces libC to be mapped and linked. When libB is dlopen()-ed the DynamicLinker would re-map and re-link libC though, causing any previous references to its old location to be invalid. And if libA's PLT has been patched to point to libC's symbols, then any further invocations to libA will cause the code to jump to a virtual address that isn't mapped anymore, therefore causing a crash. This situation was reported in #10014, although the setup was more convolved in the ticket. This commit fixes the issue by distinguishing between a main program loading being performed by Loader.so, and a dlopen() call. The main difference between these two cases is that in the former the s_globals_objects maps is always empty, while in the latter it might already contain dependencies for the library being dlopen()-ed. Hence, when collecting dependencies to map and link, dlopen() should skip those that are present in the global map to avoid the issue described above. With this patch the original issue seen in #10014 is gone, with all python3 modules (so far) loading correctly. A unit test reproducing a simplified issue is also included in this commit. The unit test includes the building of two dynamic libraries A and B with both depending on libline.so (and B also depending on A); the test then dlopen()s libA, invokes one its function, then does the same with libB.
15 lines
232 B
C++
15 lines
232 B
C++
/*
|
|
* Copyright (c) 2021, Rodrigo Tobar <rtobarc@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibLine/Span.h>
|
|
|
|
extern "C" {
|
|
int FUNCTION();
|
|
int FUNCTION()
|
|
{
|
|
return (int)Line::Span(0, 0).beginning();
|
|
}
|
|
}
|