mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1236108: Backout 34a219cbd67d; r=backout a=lizzard
MozReview-Commit-ID: EEYLmdZrZmN
This commit is contained in:
parent
c9c9658327
commit
6a3b9aff95
@ -12,8 +12,13 @@
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#endif
|
||||
@ -33,12 +38,21 @@ IsSandboxTempDirRequired()
|
||||
(Preferences::GetInt("security.sandbox.content.level") >= 1));
|
||||
}
|
||||
|
||||
static const char*
|
||||
SandboxTempDirParent()
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
// On Windows, the sandbox-writable temp directory resides in the
|
||||
// low integrity sandbox base directory.
|
||||
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
|
||||
// Save the TMP environment variable so that is is picked up by GetTempPath().
|
||||
// Note that we specifically write to the TMP variable, as that is the first
|
||||
// variable that is checked by GetTempPath() to determine its output.
|
||||
nsAutoString fullTmpPath;
|
||||
nsresult rv = aValue->GetPath(fullTmpPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", fullTmpPath.get()));
|
||||
// We also set TEMP in case there is naughty third-party code that is
|
||||
// referencing the environment variable directly.
|
||||
NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", fullTmpPath.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -50,10 +64,15 @@ IsSandboxTempDirRequired()
|
||||
return (Preferences::GetInt("security.sandbox.content.level") >= 1);
|
||||
}
|
||||
|
||||
static const char*
|
||||
SandboxTempDirParent()
|
||||
static void
|
||||
SetTmpEnvironmentVariable(nsIFile* aValue)
|
||||
{
|
||||
return NS_OS_TEMP_DIR;
|
||||
nsAutoCString fullTmpPath;
|
||||
nsresult rv = aValue->GetNativePath(fullTmpPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
NS_WARN_IF(setenv("TMPDIR", fullTmpPath.get(), 1) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -68,24 +87,11 @@ SetUpSandboxEnvironment()
|
||||
return;
|
||||
}
|
||||
|
||||
nsAdoptingString tempDirSuffix =
|
||||
Preferences::GetString("security.sandbox.content.tempDirSuffix");
|
||||
if (tempDirSuffix.IsEmpty()) {
|
||||
NS_WARNING("Sandbox-writable temp directory suffix pref not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the parent of our sandbox writable temp directory.
|
||||
nsCOMPtr<nsIFile> lowIntegrityTemp;
|
||||
nsresult rv = nsDirectoryService::gService->Get(SandboxTempDirParent(),
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(lowIntegrityTemp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Append our profile specific temp name.
|
||||
rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
|
||||
nsCOMPtr<nsIFile> sandboxedContentTemp;
|
||||
nsresult rv =
|
||||
nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(sandboxedContentTemp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
@ -93,10 +99,12 @@ SetUpSandboxEnvironment()
|
||||
// Change the gecko defined temp directory to our sandbox-writable one.
|
||||
// Undefine returns a failure if the property is not already set.
|
||||
Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
|
||||
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
|
||||
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, sandboxedContentTemp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetTmpEnvironmentVariable(sandboxedContentTemp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsExceptionHandler.h"
|
||||
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/dom/CrashReporterChild.h"
|
||||
@ -121,8 +124,7 @@ typedef std::wstring xpstring;
|
||||
#define CRASH_REPORTER_FILENAME "crashreporter.exe"
|
||||
#define PATH_SEPARATOR "\\"
|
||||
#define XP_PATH_SEPARATOR L"\\"
|
||||
// sort of arbitrary, but MAX_PATH is kinda small
|
||||
#define XP_PATH_MAX 4096
|
||||
#define XP_PATH_MAX (MAX_PATH + 1)
|
||||
// "<reporter path>" "<minidump path>"
|
||||
#define CMDLINE_SIZE ((XP_PATH_MAX * 2) + 6)
|
||||
#ifdef _USE_32BIT_TIME_T
|
||||
@ -157,10 +159,17 @@ typedef std::string xpstring;
|
||||
#endif
|
||||
#endif // XP_WIN32
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define MAYBE_UNUSED
|
||||
#endif // defined(__GNUC__)
|
||||
|
||||
#ifndef XP_LINUX
|
||||
static const XP_CHAR dumpFileExtension[] = XP_TEXT(".dmp");
|
||||
#endif
|
||||
|
||||
static const XP_CHAR childCrashAnnotationBaseName[] = XP_TEXT("GeckoChildCrash");
|
||||
static const XP_CHAR extraFileExtension[] = XP_TEXT(".extra");
|
||||
static const XP_CHAR memoryReportExtension[] = XP_TEXT(".memory.json.gz");
|
||||
|
||||
@ -258,6 +267,11 @@ static bool isSafeToDump = false;
|
||||
// OOP crash reporting
|
||||
static CrashGenerationServer* crashServer; // chrome process has this
|
||||
|
||||
#if (defined(XP_MACOSX) || defined(XP_WIN)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// This field is only valid in the chrome process, not content.
|
||||
static xpstring* contentProcessTmpDir = nullptr;
|
||||
#endif
|
||||
|
||||
# if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
// If crash reporting is disabled, we hand out this "null" pipe to the
|
||||
// child process and don't attempt to connect to a parent server.
|
||||
@ -489,12 +503,34 @@ CreateFileFromPath(const wchar_t* path, nsIFile** file)
|
||||
{
|
||||
CreateFileFromPath(std::wstring(path), file);
|
||||
}
|
||||
|
||||
static xpstring*
|
||||
CreatePathFromFile(nsIFile* file)
|
||||
{
|
||||
nsAutoString path;
|
||||
nsresult rv = file->GetPath(path);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
return new xpstring(path.get(), path.Length());
|
||||
}
|
||||
#else
|
||||
static void
|
||||
CreateFileFromPath(const xpstring& path, nsIFile** file)
|
||||
{
|
||||
NS_NewNativeLocalFile(nsDependentCString(path.c_str()), false, file);
|
||||
}
|
||||
|
||||
MAYBE_UNUSED static xpstring*
|
||||
CreatePathFromFile(nsIFile* file)
|
||||
{
|
||||
nsAutoCString path;
|
||||
nsresult rv = file->GetNativePath(path);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
return new xpstring(path.get(), path.Length());
|
||||
}
|
||||
#endif
|
||||
|
||||
static XP_CHAR*
|
||||
@ -583,6 +619,7 @@ bool copy_file(const char* from, const char* to)
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
class PlatformWriter
|
||||
{
|
||||
public:
|
||||
@ -701,6 +738,34 @@ WriteAnnotation(PlatformWriter& pw, const char (&name)[N],
|
||||
WriteLiteral(pw, "\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* If minidump_id is null, we assume that dump_path contains the full
|
||||
* dump file path.
|
||||
*/
|
||||
static void
|
||||
OpenAPIData(PlatformWriter& aWriter,
|
||||
const XP_CHAR* dump_path, const XP_CHAR* minidump_id = nullptr
|
||||
)
|
||||
{
|
||||
static XP_CHAR extraDataPath[XP_PATH_MAX];
|
||||
int size = XP_PATH_MAX;
|
||||
XP_CHAR* p;
|
||||
if (minidump_id) {
|
||||
p = Concat(extraDataPath, dump_path, &size);
|
||||
p = Concat(p, XP_PATH_SEPARATOR, &size);
|
||||
p = Concat(p, minidump_id, &size);
|
||||
} else {
|
||||
p = Concat(extraDataPath, dump_path, &size);
|
||||
// Skip back past the .dmp extension, if any.
|
||||
if (*(p - 4) == XP_TEXT('.')) {
|
||||
p -= 4;
|
||||
size += 4;
|
||||
}
|
||||
}
|
||||
Concat(p, extraFileExtension, &size);
|
||||
aWriter.Open(extraDataPath);
|
||||
}
|
||||
|
||||
bool MinidumpCallback(
|
||||
#ifdef XP_LINUX
|
||||
const MinidumpDescriptor& descriptor,
|
||||
@ -729,19 +794,6 @@ bool MinidumpCallback(
|
||||
Concat(minidumpPath, descriptor.path(), &size);
|
||||
#endif
|
||||
|
||||
static XP_CHAR extraDataPath[XP_PATH_MAX];
|
||||
size = XP_PATH_MAX;
|
||||
#ifndef XP_LINUX
|
||||
p = Concat(extraDataPath, dump_path, &size);
|
||||
p = Concat(p, XP_PATH_SEPARATOR, &size);
|
||||
p = Concat(p, minidump_id, &size);
|
||||
#else
|
||||
p = Concat(extraDataPath, descriptor.path(), &size);
|
||||
// Skip back past the .dmp extension.
|
||||
p -= 4;
|
||||
#endif
|
||||
Concat(p, extraFileExtension, &size);
|
||||
|
||||
static XP_CHAR memoryReportLocalPath[XP_PATH_MAX];
|
||||
size = XP_PATH_MAX;
|
||||
#ifndef XP_LINUX
|
||||
@ -866,7 +918,11 @@ bool MinidumpCallback(
|
||||
|
||||
if (!crashReporterAPIData->IsEmpty()) {
|
||||
// write out API data
|
||||
apiData.Open(extraDataPath);
|
||||
#ifdef XP_LINUX
|
||||
OpenAPIData(apiData, descriptor.path());
|
||||
#else
|
||||
OpenAPIData(apiData, dump_path, minidump_id);
|
||||
#endif
|
||||
apiData.WriteBuffer(crashReporterAPIData->get(), crashReporterAPIData->Length());
|
||||
}
|
||||
WriteAnnotation(apiData, "CrashTime", crashTimeString);
|
||||
@ -1058,6 +1114,154 @@ bool MinidumpCallback(
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX) || defined(__ANDROID__)
|
||||
static size_t
|
||||
EnsureTrailingSlash(char* aBuf, size_t aBufLen)
|
||||
{
|
||||
size_t len = XP_STRLEN(aBuf);
|
||||
if ((len + 2) < aBufLen && aBuf[len - 1] != '/') {
|
||||
aBuf[len] = '/';
|
||||
++len;
|
||||
aBuf[len] = 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
|
||||
static size_t
|
||||
BuildTempPath(wchar_t* aBuf, size_t aBufLen)
|
||||
{
|
||||
// first figure out buffer size
|
||||
DWORD pathLen = GetTempPath(0, nullptr);
|
||||
if (pathLen == 0 || pathLen >= aBufLen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetTempPath(pathLen, aBuf);
|
||||
}
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
static size_t
|
||||
BuildTempPath(char* aBuf, size_t aBufLen)
|
||||
{
|
||||
if (aBufLen < PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSRef fsRef;
|
||||
OSErr err = FSFindFolder(kUserDomain, kTemporaryFolderType,
|
||||
kCreateFolder, &fsRef);
|
||||
if (err != noErr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSStatus status = FSRefMakePath(&fsRef, (UInt8*)aBuf, PATH_MAX);
|
||||
if (status != noErr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EnsureTrailingSlash(aBuf, aBufLen);
|
||||
}
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
static size_t
|
||||
BuildTempPath(char* aBuf, size_t aBufLen)
|
||||
{
|
||||
// GeckoAppShell or Gonk's init.rc sets this in the environment
|
||||
const char *tempenv = PR_GetEnv("TMPDIR");
|
||||
if (!tempenv) {
|
||||
return false;
|
||||
}
|
||||
int size = (int)aBufLen;
|
||||
Concat(aBuf, tempenv, &size);
|
||||
return EnsureTrailingSlash(aBuf, aBufLen);
|
||||
}
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
|
||||
static size_t
|
||||
BuildTempPath(char* aBuf, size_t aBufLen)
|
||||
{
|
||||
// we assume it's always /tmp on unix systems
|
||||
NS_NAMED_LITERAL_CSTRING(tmpPath, "/tmp/");
|
||||
int size = (int)aBufLen;
|
||||
Concat(aBuf, tmpPath.get(), &size);
|
||||
return tmpPath.Length();
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Implement this for your platform"
|
||||
#endif
|
||||
|
||||
template <typename CharT, size_t N>
|
||||
static size_t
|
||||
BuildTempPath(CharT (&aBuf)[N])
|
||||
{
|
||||
static_assert(N >= XP_PATH_MAX, "char array length is too small");
|
||||
return BuildTempPath(&aBuf[0], N);
|
||||
}
|
||||
|
||||
template <typename PathStringT>
|
||||
static bool
|
||||
BuildTempPath(PathStringT& aResult)
|
||||
{
|
||||
aResult.SetLength(XP_PATH_MAX);
|
||||
size_t actualLen = BuildTempPath(aResult.BeginWriting(), XP_PATH_MAX);
|
||||
if (!actualLen) {
|
||||
return false;
|
||||
}
|
||||
aResult.SetLength(actualLen);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
PrepareChildExceptionTimeAnnotations()
|
||||
{
|
||||
MOZ_ASSERT(!XRE_IsParentProcess());
|
||||
static XP_CHAR tempPath[XP_PATH_MAX] = {0};
|
||||
|
||||
// Get the temp path
|
||||
size_t tempPathLen = BuildTempPath(tempPath);
|
||||
if (!tempPathLen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate and append the file name
|
||||
int size = XP_PATH_MAX - tempPathLen;
|
||||
XP_CHAR* p = tempPath + tempPathLen;
|
||||
p = Concat(p, childCrashAnnotationBaseName, &size);
|
||||
XP_CHAR pidBuffer[32] = XP_TEXT("");
|
||||
#if defined(XP_WIN32)
|
||||
_ui64tow(GetCurrentProcessId(), pidBuffer, 10);
|
||||
#else
|
||||
XP_STOA(getpid(), pidBuffer, 10);
|
||||
#endif
|
||||
p = Concat(p, pidBuffer, &size);
|
||||
|
||||
// Now open the file...
|
||||
PlatformWriter apiData;
|
||||
OpenAPIData(apiData, tempPath);
|
||||
|
||||
// ...and write out any annotations. These should be escaped if necessary
|
||||
// (but don't call EscapeAnnotation here, because it touches the heap).
|
||||
char oomAllocationSizeBuffer[32] = "";
|
||||
if (gOOMAllocationSize) {
|
||||
XP_STOA(gOOMAllocationSize, oomAllocationSizeBuffer, 10);
|
||||
}
|
||||
|
||||
if (oomAllocationSizeBuffer[0]) {
|
||||
WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
|
||||
}
|
||||
|
||||
if (gMozCrashReason) {
|
||||
WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
static void
|
||||
ReserveBreakpadVM()
|
||||
@ -1108,6 +1312,18 @@ static bool FPEFilter(void* context, EXCEPTION_POINTERS* exinfo,
|
||||
FreeBreakpadVM();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ChildFPEFilter(void* context, EXCEPTION_POINTERS* exinfo,
|
||||
MDRawAssertionInfo* assertion)
|
||||
{
|
||||
bool result = FPEFilter(context, exinfo, assertion);
|
||||
if (result) {
|
||||
PrepareChildExceptionTimeAnnotations();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // XP_WIN
|
||||
|
||||
static bool ShouldReport()
|
||||
@ -1127,13 +1343,22 @@ static bool ShouldReport()
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool Filter(void* context) {
|
||||
mozilla::IOInterposer::Disable();
|
||||
return true;
|
||||
}
|
||||
static bool
|
||||
Filter(void* context)
|
||||
{
|
||||
mozilla::IOInterposer::Disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ChildFilter(void* context)
|
||||
{
|
||||
bool result = Filter(context);
|
||||
if (result) {
|
||||
PrepareChildExceptionTimeAnnotations();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
bool force/*=false*/)
|
||||
@ -1228,41 +1453,12 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
// get temp path to use for minidump path
|
||||
#if defined(XP_WIN32)
|
||||
nsString tempPath;
|
||||
|
||||
// first figure out buffer size
|
||||
int pathLen = GetTempPath(0, nullptr);
|
||||
if (pathLen == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
tempPath.SetLength(pathLen);
|
||||
GetTempPath(pathLen, (LPWSTR)tempPath.BeginWriting());
|
||||
#elif defined(XP_MACOSX)
|
||||
nsCString tempPath;
|
||||
FSRef fsRef;
|
||||
OSErr err = FSFindFolder(kUserDomain, kTemporaryFolderType,
|
||||
kCreateFolder, &fsRef);
|
||||
if (err != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char path[PATH_MAX];
|
||||
OSStatus status = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
|
||||
if (status != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
tempPath = path;
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
// GeckoAppShell or Gonk's init.rc sets this in the environment
|
||||
const char *tempenv = PR_GetEnv("TMPDIR");
|
||||
if (!tempenv)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCString tempPath(tempenv);
|
||||
#elif defined(XP_UNIX)
|
||||
// we assume it's always /tmp on unix systems
|
||||
nsCString tempPath = NS_LITERAL_CSTRING("/tmp/");
|
||||
#else
|
||||
#error "Implement this for your platform"
|
||||
nsCString tempPath;
|
||||
#endif
|
||||
if (!BuildTempPath(tempPath)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Initialize spawn attributes, since this calls malloc.
|
||||
@ -2704,24 +2900,164 @@ AppendExtraData(nsIFile* extraFile, const AnnotationTable& data)
|
||||
return WriteExtraData(extraFile, data, Blacklist());
|
||||
}
|
||||
|
||||
static bool
|
||||
GetExtraFileForChildPid(nsIFile* aMinidump, uint32_t aPid, nsIFile** aExtraFile)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
nsCOMPtr<nsIFile> extraFile;
|
||||
nsresult rv;
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
# if defined(MOZ_CONTENT_SANDBOX)
|
||||
if (!contentProcessTmpDir) {
|
||||
return false;
|
||||
}
|
||||
CreateFileFromPath(*contentProcessTmpDir, getter_AddRefs(extraFile));
|
||||
if (!extraFile) {
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
rv = aMinidump->Clone(getter_AddRefs(extraFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
# endif // defined(MOZ_CONTENT_SANDBOX)
|
||||
#elif defined(XP_UNIX)
|
||||
rv = NS_NewLocalFile(NS_LITERAL_STRING("/tmp"), false,
|
||||
getter_AddRefs(extraFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#error "Implement this for your platform"
|
||||
#endif
|
||||
|
||||
nsAutoString leafName;
|
||||
#if defined(XP_WIN)
|
||||
leafName.AppendPrintf("%S%u%S", childCrashAnnotationBaseName, aPid,
|
||||
extraFileExtension);
|
||||
#else
|
||||
leafName.AppendPrintf("%s%u%s", childCrashAnnotationBaseName, aPid,
|
||||
extraFileExtension);
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
# if defined(MOZ_CONTENT_SANDBOX)
|
||||
rv = extraFile->Append(leafName);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
# else
|
||||
rv = extraFile->SetLeafName(leafName);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
# endif // defined(MOZ_CONTENT_SANDBOX)
|
||||
#elif defined(XP_UNIX)
|
||||
rv = extraFile->Append(leafName);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#error "Implement this for your platform"
|
||||
#endif
|
||||
|
||||
extraFile.forget(aExtraFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsDataEscaped(char* aData)
|
||||
{
|
||||
if (strchr(aData, '\n')) {
|
||||
// There should not be any newlines
|
||||
return false;
|
||||
}
|
||||
char* pos = aData;
|
||||
while ((pos = strchr(pos, '\\'))) {
|
||||
if (*(pos + 1) != '\\') {
|
||||
return false;
|
||||
}
|
||||
// Add 2 to account for the second pos
|
||||
pos += 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ReadAndValidateExceptionTimeAnnotations(FILE*& aFd,
|
||||
AnnotationTable& aAnnotations)
|
||||
{
|
||||
char line[0x1000];
|
||||
while (fgets(line, sizeof(line), aFd)) {
|
||||
char* data = strchr(line, '=');
|
||||
if (!data) {
|
||||
// bad data? Abort!
|
||||
break;
|
||||
}
|
||||
// Move past the '='
|
||||
*data = 0;
|
||||
++data;
|
||||
size_t dataLen = strlen(data);
|
||||
// Chop off any trailing newline
|
||||
if (dataLen > 0 && data[dataLen - 1] == '\n') {
|
||||
data[dataLen - 1] = 0;
|
||||
--dataLen;
|
||||
}
|
||||
// There should not be any newlines in the key
|
||||
if (strchr(line, '\n')) {
|
||||
break;
|
||||
}
|
||||
// Data should have been escaped by the child
|
||||
if (!IsDataEscaped(data)) {
|
||||
break;
|
||||
}
|
||||
// Looks good, save the (line,data) pair
|
||||
aAnnotations.Put(nsDependentCString(line),
|
||||
nsDependentCString(data, dataLen));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: One side effect of this function is that it deletes the
|
||||
* GeckoChildCrash<pid>.extra file if it exists, once processed.
|
||||
*/
|
||||
static bool
|
||||
WriteExtraForMinidump(nsIFile* minidump,
|
||||
uint32_t pid,
|
||||
const Blacklist& blacklist,
|
||||
nsIFile** extraFile)
|
||||
{
|
||||
nsCOMPtr<nsIFile> extra;
|
||||
if (!GetExtraFileForMinidump(minidump, getter_AddRefs(extra)))
|
||||
if (!GetExtraFileForMinidump(minidump, getter_AddRefs(extra))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteExtraData(extra, *crashReporterAPIData_Hash,
|
||||
blacklist,
|
||||
true /*write crash time*/,
|
||||
true /*truncate*/))
|
||||
true /*truncate*/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*extraFile = nullptr;
|
||||
extra.swap(*extraFile);
|
||||
nsCOMPtr<nsIFile> exceptionTimeExtra;
|
||||
FILE* fd;
|
||||
if (pid && GetExtraFileForChildPid(minidump, pid,
|
||||
getter_AddRefs(exceptionTimeExtra)) &&
|
||||
NS_SUCCEEDED(exceptionTimeExtra->OpenANSIFileDesc("r", &fd))) {
|
||||
AnnotationTable exceptionTimeAnnotations;
|
||||
ReadAndValidateExceptionTimeAnnotations(fd, exceptionTimeAnnotations);
|
||||
fclose(fd);
|
||||
if (!AppendExtraData(extra, exceptionTimeAnnotations)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (exceptionTimeExtra) {
|
||||
exceptionTimeExtra->Remove(false);
|
||||
}
|
||||
|
||||
extra.forget(extraFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2775,7 +3111,14 @@ OnChildProcessDumpRequested(void* aContext,
|
||||
#endif
|
||||
getter_AddRefs(minidump));
|
||||
|
||||
if (!WriteExtraForMinidump(minidump,
|
||||
uint32_t pid =
|
||||
#ifdef XP_MACOSX
|
||||
aClientInfo.pid();
|
||||
#else
|
||||
aClientInfo->pid();
|
||||
#endif
|
||||
|
||||
if (!WriteExtraForMinidump(minidump, pid,
|
||||
Blacklist(kSubprocessBlacklist,
|
||||
ArrayLength(kSubprocessBlacklist)),
|
||||
getter_AddRefs(extraFile)))
|
||||
@ -2785,12 +3128,6 @@ OnChildProcessDumpRequested(void* aContext,
|
||||
MoveToPending(minidump, extraFile);
|
||||
|
||||
{
|
||||
uint32_t pid =
|
||||
#ifdef XP_MACOSX
|
||||
aClientInfo.pid();
|
||||
#else
|
||||
aClientInfo->pid();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
bool runCallback;
|
||||
@ -2818,13 +3155,6 @@ OOPInitialized()
|
||||
return pidToMinidump != nullptr;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
static bool ChildFilter(void *context) {
|
||||
mozilla::IOInterposer::Disable();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
OOPInit()
|
||||
{
|
||||
@ -2851,6 +3181,14 @@ OOPInit()
|
||||
MOZ_ASSERT(gExceptionHandler != nullptr,
|
||||
"attempt to initialize OOP crash reporter before in-process crashreporter!");
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
nsCOMPtr<nsIFile> tmpDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
contentProcessTmpDir = CreatePathFromFile(tmpDir);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
childCrashNotifyPipe =
|
||||
PR_smprintf("\\\\.\\pipe\\gecko-crash-server-pipe.%i",
|
||||
@ -2889,7 +3227,7 @@ OOPInit()
|
||||
|
||||
crashServer = new CrashGenerationServer(
|
||||
childCrashNotifyPipe,
|
||||
ChildFilter,
|
||||
nullptr,
|
||||
nullptr,
|
||||
OnChildProcessDumpRequested, nullptr,
|
||||
nullptr, nullptr,
|
||||
@ -3097,16 +3435,16 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
|
||||
|
||||
gExceptionHandler = new google_breakpad::
|
||||
ExceptionHandler(L"",
|
||||
FPEFilter,
|
||||
ChildFPEFilter,
|
||||
nullptr, // no minidump callback
|
||||
nullptr, // no callback context
|
||||
google_breakpad::ExceptionHandler::HANDLER_ALL,
|
||||
MiniDumpNormal,
|
||||
NS_ConvertASCIItoUTF16(crashPipe).get(),
|
||||
nullptr);
|
||||
#ifdef XP_WIN
|
||||
gExceptionHandler->set_handle_debug_exceptions(true);
|
||||
#endif
|
||||
|
||||
mozalloc_set_oom_abort_handler(AnnotateOOMAllocationSize);
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
@ -3139,15 +3477,12 @@ SetRemoteExceptionHandler()
|
||||
{
|
||||
MOZ_ASSERT(!gExceptionHandler, "crash client already init'd");
|
||||
|
||||
#ifndef XP_LINUX
|
||||
xpstring path = "";
|
||||
#else
|
||||
// MinidumpDescriptor requires a non-empty path.
|
||||
google_breakpad::MinidumpDescriptor path(".");
|
||||
#endif
|
||||
|
||||
gExceptionHandler = new google_breakpad::
|
||||
ExceptionHandler(path,
|
||||
nullptr, // no filter callback
|
||||
ChildFilter,
|
||||
nullptr, // no minidump callback
|
||||
nullptr, // no callback context
|
||||
true, // install signal handlers
|
||||
@ -3160,6 +3495,8 @@ SetRemoteExceptionHandler()
|
||||
delete gDelayedAnnotations;
|
||||
}
|
||||
|
||||
mozalloc_set_oom_abort_handler(AnnotateOOMAllocationSize);
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
}
|
||||
@ -3178,12 +3515,14 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
|
||||
|
||||
gExceptionHandler = new google_breakpad::
|
||||
ExceptionHandler("",
|
||||
Filter,
|
||||
ChildFilter,
|
||||
nullptr, // no minidump callback
|
||||
nullptr, // no callback context
|
||||
true, // install signal handlers
|
||||
crashPipe.BeginReading());
|
||||
|
||||
mozalloc_set_oom_abort_handler(AnnotateOOMAllocationSize);
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
}
|
||||
@ -3297,7 +3636,7 @@ PairedDumpCallbackExtra(
|
||||
nsCOMPtr<nsIFile>& minidump = *static_cast< nsCOMPtr<nsIFile>* >(context);
|
||||
|
||||
nsCOMPtr<nsIFile> extra;
|
||||
return WriteExtraForMinidump(minidump, Blacklist(), getter_AddRefs(extra));
|
||||
return WriteExtraForMinidump(minidump, 0, Blacklist(), getter_AddRefs(extra));
|
||||
}
|
||||
|
||||
ThreadId
|
||||
|
@ -7,12 +7,12 @@ function run_test()
|
||||
return;
|
||||
}
|
||||
|
||||
// Try crashing with a pure virtual call
|
||||
// Try crashing with a runtime abort
|
||||
do_content_crash(function() {
|
||||
crashType = CrashTestUtils.CRASH_RUNTIMEABORT;
|
||||
crashReporter.annotateCrashReport("TestKey", "TestValue");
|
||||
crashReporter.appendAppNotesToCrashReport("!!!foo!!!");
|
||||
},
|
||||
},
|
||||
function(mdump, extra) {
|
||||
do_check_eq(extra.TestKey, "TestValue");
|
||||
do_check_true('StartupTime' in extra);
|
||||
|
@ -0,0 +1,17 @@
|
||||
load("../unit/head_crashreporter.js");
|
||||
|
||||
function run_test()
|
||||
{
|
||||
if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
|
||||
dump("INFO | test_content_annotation.js | Can't test crashreporter in a non-libxul build.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try crashing with an OOM
|
||||
do_content_crash(function() {
|
||||
crashType = CrashTestUtils.CRASH_OOM;
|
||||
},
|
||||
function(mdump, extra) {
|
||||
do_check_true('OOMAllocationSize' in extra);
|
||||
});
|
||||
}
|
@ -4,3 +4,4 @@ tail =
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
|
||||
[test_content_annotation.js]
|
||||
[test_content_exception_time_annotation.js]
|
||||
|
@ -604,37 +604,15 @@ CanShowProfileManager()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static const char*
|
||||
SandboxTempDirParent()
|
||||
{
|
||||
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static const char*
|
||||
SandboxTempDirParent()
|
||||
{
|
||||
return NS_OS_TEMP_DIR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
static already_AddRefed<nsIFile>
|
||||
GetAndCleanTempDir(const nsAString& aTempDirSuffix)
|
||||
GetAndCleanTempDir()
|
||||
{
|
||||
// Get the directory within which we'll place the
|
||||
// sandbox-writable temp directory
|
||||
nsCOMPtr<nsIFile> tempDir;
|
||||
nsresult rv = NS_GetSpecialDirectory(SandboxTempDirParent(),
|
||||
getter_AddRefs(tempDir));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Append our profile specific temp name.
|
||||
rv = tempDir->Append(NS_LITERAL_STRING("Temp-") + aTempDirSuffix);
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
getter_AddRefs(tempDir));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -715,7 +693,7 @@ SetUpSandboxEnvironment()
|
||||
}
|
||||
|
||||
// Get (and clean up if still there) the sandbox-writable temp directory.
|
||||
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir(tempDirSuffix);
|
||||
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
|
||||
if (!tempDir) {
|
||||
NS_WARNING("Failed to get or clean sandboxed temp directory.");
|
||||
return;
|
||||
@ -737,16 +715,9 @@ CleanUpSandboxEnvironment()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get temp directory suffix pref.
|
||||
nsAdoptingString tempDirSuffix =
|
||||
Preferences::GetString("security.sandbox.content.tempDirSuffix");
|
||||
if (tempDirSuffix.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get and remove the sandbox-writable temp directory.
|
||||
// This function already warns if the deletion fails.
|
||||
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir(tempDirSuffix);
|
||||
nsCOMPtr<nsIFile> tempDir = GetAndCleanTempDir();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -397,6 +397,14 @@ nsXREDirProvider::GetFile(const char* aProperty, bool* aPersistent,
|
||||
bool unused;
|
||||
rv = dirsvc->GetFile("XCurProcD", &unused, getter_AddRefs(file));
|
||||
}
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
else if (!strcmp(aProperty, NS_APP_CONTENT_PROCESS_TEMP_DIR)) {
|
||||
if (!mContentTempDir && NS_FAILED((rv = LoadContentProcessTempDir()))) {
|
||||
return rv;
|
||||
}
|
||||
rv = mContentTempDir->Clone(getter_AddRefs(file));
|
||||
}
|
||||
#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
else if (NS_SUCCEEDED(GetProfileStartupDir(getter_AddRefs(file)))) {
|
||||
// We need to allow component, xpt, and chrome registration to
|
||||
// occur prior to the profile-after-change notification.
|
||||
@ -620,6 +628,50 @@ LoadExtensionDirectories(nsINIParser &parser,
|
||||
while (true);
|
||||
}
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
static const char*
|
||||
GetContentProcessTempBaseDirKey()
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
return NS_WIN_LOW_INTEGRITY_TEMP_BASE;
|
||||
#else
|
||||
return NS_OS_TEMP_DIR;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXREDirProvider::LoadContentProcessTempDir()
|
||||
{
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
|
||||
nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),
|
||||
getter_AddRefs(localFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoString tempDirSuffix;
|
||||
rv = Preferences::GetString("security.sandbox.content.tempDirSuffix",
|
||||
&tempDirSuffix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (tempDirSuffix.IsEmpty()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
rv = localFile->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
localFile.swap(mContentTempDir);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
void
|
||||
nsXREDirProvider::LoadExtensionBundleDirectories()
|
||||
{
|
||||
@ -869,6 +921,7 @@ nsXREDirProvider::DoStartup()
|
||||
|
||||
static const char16_t kStartup[] = {'s','t','a','r','t','u','p','\0'};
|
||||
obsSvc->NotifyObservers(nullptr, "profile-do-change", kStartup);
|
||||
|
||||
// Init the Extension Manager
|
||||
nsCOMPtr<nsIObserver> em = do_GetService("@mozilla.org/addons/integration;1");
|
||||
if (em) {
|
||||
|
@ -121,6 +121,11 @@ protected:
|
||||
// delimiters.
|
||||
static inline nsresult AppendProfileString(nsIFile* aFile, const char* aPath);
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// Load the temp directory for sandboxed content processes
|
||||
nsresult LoadContentProcessTempDir();
|
||||
#endif
|
||||
|
||||
// Calculate and register extension and theme bundle directories.
|
||||
void LoadExtensionBundleDirectories();
|
||||
|
||||
@ -141,6 +146,9 @@ protected:
|
||||
nsCOMPtr<nsIFile> mProfileDir;
|
||||
nsCOMPtr<nsIFile> mProfileLocalDir;
|
||||
bool mProfileNotified;
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
nsCOMPtr<nsIFile> mContentTempDir;
|
||||
#endif
|
||||
nsCOMArray<nsIFile> mAppBundleDirectories;
|
||||
nsCOMArray<nsIFile> mExtensionDirectories;
|
||||
nsCOMArray<nsIFile> mThemeDirectories;
|
||||
|
@ -83,4 +83,9 @@
|
||||
#define NS_APP_INDEXEDDB_PARENT_DIR "indexedDBPDir"
|
||||
|
||||
#define NS_APP_PERMISSION_PARENT_DIR "permissionDBPDir"
|
||||
#endif
|
||||
|
||||
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
#define NS_APP_CONTENT_PROCESS_TEMP_DIR "ContentTmpD"
|
||||
#endif // (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
|
||||
|
||||
#endif // nsAppDirectoryServiceDefs_h___
|
||||
|
Loading…
Reference in New Issue
Block a user