Bug 990230 - Fix heap use-after-free in memory reporter. r=n.nethercote

This commit is contained in:
Dave Hylands
2014-04-17 16:57:30 -07:00
parent 40ec2911c2
commit 258fc06a82
2 changed files with 53 additions and 35 deletions

View File

@@ -11,7 +11,7 @@
#include <errno.h>
#include "mozilla/Services.h"
#include "nsIObserverService.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ClearOnShutdown.h"
#if defined(XP_LINUX) || defined(__FreeBSD__) // {
#include "mozilla/Preferences.h"
@@ -20,6 +20,8 @@
#include <sys/types.h>
#include <sys/stat.h>
using namespace mozilla;
/*
* The following code supports triggering a registered callback upon
* receiving a specific signal.
@@ -118,25 +120,26 @@ SignalPipeWatcher::GetSingleton()
return sSingleton;
}
/* static */ void
SignalPipeWatcher::RegisterCallback(const uint8_t aSignal,
void
SignalPipeWatcher::RegisterCallback(uint8_t aSignal,
PipeCallback aCallback)
{
for (SignalInfoArray::index_type i = 0;
i < SignalPipeWatcher::mSignalInfo.Length(); i++)
MutexAutoLock lock(mSignalInfoLock);
for (SignalInfoArray::index_type i = 0; i < mSignalInfo.Length(); i++)
{
if (SignalPipeWatcher::mSignalInfo[i].mSignal == aSignal) {
if (mSignalInfo[i].mSignal == aSignal) {
LOG("Register Signal(%d) callback failed! (DUPLICATE)", aSignal);
return;
}
}
SignalInfo aSignalInfo = { aSignal, aCallback };
SignalPipeWatcher::mSignalInfo.AppendElement(aSignalInfo);
SignalPipeWatcher::RegisterSignalHandler(aSignalInfo.mSignal);
SignalInfo signalInfo = { aSignal, aCallback };
mSignalInfo.AppendElement(signalInfo);
RegisterSignalHandler(signalInfo.mSignal);
}
/* static */ void
SignalPipeWatcher::RegisterSignalHandler(const uint8_t aSignal)
void
SignalPipeWatcher::RegisterSignalHandler(uint8_t aSignal)
{
struct sigaction action;
memset(&action, 0, sizeof(action));
@@ -148,10 +151,11 @@ SignalPipeWatcher::RegisterSignalHandler(const uint8_t aSignal)
LOG("SignalPipeWatcher failed to register sig %d.", aSignal);
}
} else {
for (SignalInfoArray::index_type i = 0; i < SignalPipeWatcher::mSignalInfo.Length(); i++) {
if (sigaction(SignalPipeWatcher::mSignalInfo[i].mSignal, &action, nullptr)) {
MutexAutoLock lock(mSignalInfoLock);
for (SignalInfoArray::index_type i = 0; i < mSignalInfo.Length(); i++) {
if (sigaction(mSignalInfo[i].mSignal, &action, nullptr)) {
LOG("SignalPipeWatcher failed to register signal(%d) "
"dump signal handler.",SignalPipeWatcher::mSignalInfo[i].mSignal);
"dump signal handler.", mSignalInfo[i].mSignal);
}
}
}
@@ -159,8 +163,9 @@ SignalPipeWatcher::RegisterSignalHandler(const uint8_t aSignal)
SignalPipeWatcher::~SignalPipeWatcher()
{
if (sDumpPipeWriteFd != -1)
SignalPipeWatcher::StopWatching();
if (sDumpPipeWriteFd != -1) {
StopWatching();
}
}
int SignalPipeWatcher::OpenFd()
@@ -182,7 +187,7 @@ int SignalPipeWatcher::OpenFd()
int readFd = pipeFds[0];
sDumpPipeWriteFd = pipeFds[1];
SignalPipeWatcher::RegisterSignalHandler();
RegisterSignalHandler();
return readFd;
}
@@ -215,10 +220,13 @@ void SignalPipeWatcher::OnFileCanReadWithoutBlocking(int aFd)
return;
}
for (SignalInfoArray::index_type i = 0; i < SignalPipeWatcher::mSignalInfo.Length(); i++) {
if(signum == SignalPipeWatcher::mSignalInfo[i].mSignal) {
SignalPipeWatcher::mSignalInfo[i].mCallback(signum);
return;
{
MutexAutoLock lock(mSignalInfoLock);
for (SignalInfoArray::index_type i = 0; i < mSignalInfo.Length(); i++) {
if(signum == mSignalInfo[i].mSignal) {
mSignalInfo[i].mCallback(signum);
return;
}
}
}
LOG("SignalPipeWatcher got unexpected signum.");
@@ -257,25 +265,26 @@ FifoWatcher::MaybeCreate()
}
// The FifoWatcher is held alive by the observer service.
if (!FifoWatcher::sSingleton) {
FifoWatcher::GetSingleton();
if (!sSingleton) {
GetSingleton();
}
return true;
}
void
FifoWatcher::RegisterCallback(const nsCString& aCommand,FifoCallback aCallback)
FifoWatcher::RegisterCallback(const nsCString& aCommand, FifoCallback aCallback)
{
for (FifoInfoArray::index_type i = 0;
i < FifoWatcher::mFifoInfo.Length(); i++)
MutexAutoLock lock(mFifoInfoLock);
for (FifoInfoArray::index_type i = 0; i < mFifoInfo.Length(); i++)
{
if (FifoWatcher::mFifoInfo[i].mCommand.Equals(aCommand)) {
if (mFifoInfo[i].mCommand.Equals(aCommand)) {
LOG("Register command(%s) callback failed! (DUPLICATE)", aCommand.get());
return;
}
}
FifoInfo aFifoInfo = { aCommand, aCallback };
FifoWatcher::mFifoInfo.AppendElement(aFifoInfo);
mFifoInfo.AppendElement(aFifoInfo);
}
FifoWatcher::~FifoWatcher()
@@ -392,11 +401,15 @@ void FifoWatcher::OnFileCanReadWithoutBlocking(int aFd)
// it'll actually write "foo\n" to the fifo.
inputStr.Trim("\b\t\r\n");
for (FifoInfoArray::index_type i = 0; i < FifoWatcher::mFifoInfo.Length(); i++) {
const nsCString commandStr = FifoWatcher::mFifoInfo[i].mCommand;
if(inputStr == commandStr.get()) {
FifoWatcher::mFifoInfo[i].mCallback(inputStr);
return;
{
MutexAutoLock lock(mFifoInfoLock);
for (FifoInfoArray::index_type i = 0; i < mFifoInfo.Length(); i++) {
const nsCString commandStr = mFifoInfo[i].mCommand;
if(inputStr == commandStr.get()) {
mFifoInfo[i].mCallback(inputStr);
return;
}
}
}
LOG("Got unexpected value from fifo; ignoring it.");