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:
Mike Hommey 2014-08-07 02:51:20 +09:00
Родитель 15851645b4
Коммит 1cf20f37fd
2 изменённых файлов: 49 добавлений и 1 удалений

Просмотреть файл

@ -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