зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1036286 - Ensure faulty.lib diverts libc's sigaction instead of a LD_PRELOADed one. r=nfroyd
and force-send calls to sigaction from faulty.lib-loaded libraries to the libc.
This commit is contained in:
Родитель
15851645b4
Коммит
1cf20f37fd
|
@ -6,6 +6,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include <vector>
|
||||
#include <dlfcn.h>
|
||||
#include <signal.h>
|
||||
#include "CustomElf.h"
|
||||
#include "Mappable.h"
|
||||
#include "Logging.h"
|
||||
|
@ -353,6 +354,11 @@ CustomElf::GetSymbolPtrInDeps(const char *symbol) const
|
|||
if (strcmp(symbol + 2, "gnu_Unwind_Find_exidx") == 0)
|
||||
return FunctionPtr(__wrap___gnu_Unwind_Find_exidx);
|
||||
#endif
|
||||
} else if (symbol[0] == 's' && symbol[1] == 'i') {
|
||||
if (strcmp(symbol + 2, "gnal") == 0)
|
||||
return FunctionPtr(signal);
|
||||
if (strcmp(symbol + 2, "gaction") == 0)
|
||||
return FunctionPtr(sigaction);
|
||||
}
|
||||
|
||||
#define MISSING_FLASH_SYMNAME_START "_ZN7android10VectorImpl19reservedVectorImpl"
|
||||
|
|
|
@ -1019,7 +1019,49 @@ SEGVHandler::FinishInitialization()
|
|||
if (signalHandlingBroken || signalHandlingSlow)
|
||||
return;
|
||||
|
||||
if (!Divert(sigaction, __wrap_sigaction))
|
||||
typedef int (*sigaction_func)(int, const struct sigaction *,
|
||||
struct sigaction *);
|
||||
|
||||
sigaction_func libc_sigaction;
|
||||
|
||||
#if defined(ANDROID)
|
||||
/* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
|
||||
* (libsigchain) for ART. That wrapper kind of does the same trick as we
|
||||
* do, so we need extra care in handling it.
|
||||
* - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
|
||||
* it under the hood (which is more or less true according to the source
|
||||
* of that library, since it's doing a lookup in RTLD_NEXT)
|
||||
* - With the LD_PRELOADed library in place, all calls to sigaction from
|
||||
* from system libraries will go to the LD_PRELOADed library.
|
||||
* - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
|
||||
* - The calls to sigaction from libraries faulty.lib loads are sent to
|
||||
* the LD_PRELOADed library.
|
||||
* In practice, for signal handling, this means:
|
||||
* - The signal handler registered to the kernel is ours.
|
||||
* - Our handler redispatches to the LD_PRELOADed library's if there's a
|
||||
* segfault we don't handle.
|
||||
* - The LD_PRELOADed library redispatches according to whatever system
|
||||
* library or faulty.lib-loaded library set with sigaction.
|
||||
*
|
||||
* When there is no sigaction wrapper in place:
|
||||
* - Divert the libc's sigaction.
|
||||
* - Calls to sigaction from system library and faulty.lib-loaded libraries
|
||||
* all go to the libc's sigaction, which end up in our __wrap_sigaction.
|
||||
* - The signal handler registered to the kernel is ours.
|
||||
* - Our handler redispatches according to whatever system library or
|
||||
* faulty.lib-loaded library set with sigaction.
|
||||
*/
|
||||
void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (libc) {
|
||||
libc_sigaction =
|
||||
reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
libc_sigaction = sigaction;
|
||||
}
|
||||
|
||||
if (!Divert(libc_sigaction, __wrap_sigaction))
|
||||
return;
|
||||
|
||||
/* Setup an alternative stack if the already existing one is not big
|
||||
|
|
Загрузка…
Ссылка в новой задаче