Bug 1036286 - Make sure libraries loaded by faulty.lib use its own sigaction. r=nfroyd

Android L added a libsigchain library it LD_PRELOADs. That library exposes
a different sigaction than libc's. It's used for ART.

faulty.lib gets its sigaction from libsigchain, but after bug 874708, the
libraries it loads simply use libc's sigaction, assuming it would be the
hooked one. In turn, this means libraries loaded by faulty.lib may
override faulty.lib's handler, which is definitely not the intent.

This essentially restores some of the code that bug 874708 removed.

An alternative fix would be to add support for LD_PRELOAD, but that has more
implications and feels more risky. This could be done, if necessary, as a
followup.
This commit is contained in:
Mike Hommey 2014-07-24 13:43:56 +09:00
parent 532c1e8eff
commit 95e40852cb
3 changed files with 36 additions and 3 deletions

View File

@ -353,6 +353,11 @@ CustomElf::GetSymbolPtrInDeps(const char *symbol) const
if (strcmp(symbol + 2, "gnu_Unwind_Find_exidx") == 0) if (strcmp(symbol + 2, "gnu_Unwind_Find_exidx") == 0)
return FunctionPtr(__wrap___gnu_Unwind_Find_exidx); return FunctionPtr(__wrap___gnu_Unwind_Find_exidx);
#endif #endif
} else if (symbol[0] == 's' && symbol[1] == 'i') {
if (strcmp(symbol + 2, "gnal") == 0)
return FunctionPtr(SEGVHandler::__wrap_signal);
if (strcmp(symbol + 2, "gaction") == 0)
return FunctionPtr(SEGVHandler::__wrap_sigaction);
} }
#define MISSING_FLASH_SYMNAME_START "_ZN7android10VectorImpl19reservedVectorImpl" #define MISSING_FLASH_SYMNAME_START "_ZN7android10VectorImpl19reservedVectorImpl"

View File

@ -1123,4 +1123,30 @@ SEGVHandler::__wrap_sigaction(int signum, const struct sigaction *act,
return 0; return 0;
} }
sighandler_t
SEGVHandler::__wrap_signal(int signum, sighandler_t handler)
{
/* Use system signal() function for all but SIGSEGV signals. */
if (signum != SIGSEGV)
return signal(signum, handler);
SEGVHandler &that = ElfLoader::Singleton;
union {
sighandler_t signal;
void (*sigaction)(int, siginfo_t *, void *);
} oldHandler;
/* Keep the previous handler to return its value */
if (that.action.sa_flags & SA_SIGINFO) {
oldHandler.sigaction = that.action.sa_sigaction;
} else {
oldHandler.signal = that.action.sa_handler;
}
/* Set the new handler */
that.action.sa_handler = handler;
that.action.sa_flags = 0;
return oldHandler.signal;
}
Logging Logging::Singleton; Logging Logging::Singleton;

View File

@ -319,14 +319,16 @@ public:
return signalHandlingBroken; return signalHandlingBroken;
} }
static int __wrap_sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
static sighandler_t __wrap_signal(int signum, sighandler_t handler);
protected: protected:
SEGVHandler(); SEGVHandler();
~SEGVHandler(); ~SEGVHandler();
private: private:
static int __wrap_sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
/** /**
* SIGSEGV handler registered with __wrap_signal or __wrap_sigaction. * SIGSEGV handler registered with __wrap_signal or __wrap_sigaction.
*/ */