diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index 3a7a5dd30e1..47c2d5a2e1c 100644 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -124,6 +124,7 @@ typedef std::wstring xpstring; #define CRASH_REPORTER_FILENAME "crashreporter.exe" #define PATH_SEPARATOR "\\" #define XP_PATH_SEPARATOR L"\\" +#define XP_PATH_SEPARATOR_CHAR L'\\' #define XP_PATH_MAX (MAX_PATH + 1) // "" "" #define CMDLINE_SIZE ((XP_PATH_MAX * 2) + 6) @@ -141,6 +142,7 @@ typedef std::string xpstring; #define CRASH_REPORTER_FILENAME "crashreporter" #define PATH_SEPARATOR "/" #define XP_PATH_SEPARATOR "/" +#define XP_PATH_SEPARATOR_CHAR '/' #define XP_PATH_MAX PATH_MAX #ifdef XP_LINUX #define XP_STRLEN(x) my_strlen(x) @@ -267,9 +269,9 @@ 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; +#if (defined(XP_MACOSX) || defined(XP_WIN)) +// This field is valid in both chrome and content processes. +static xpstring* childProcessTmpDir = nullptr; #endif # if defined(XP_WIN) || defined(XP_MACOSX) @@ -1116,11 +1118,11 @@ bool MinidumpCallback( #if defined(XP_MACOSX) || defined(__ANDROID__) static size_t -EnsureTrailingSlash(char* aBuf, size_t aBufLen) +EnsureTrailingSlash(XP_CHAR* aBuf, size_t aBufLen) { size_t len = XP_STRLEN(aBuf); - if ((len + 2) < aBufLen && aBuf[len - 1] != '/') { - aBuf[len] = '/'; + if ((len + 2) < aBufLen && aBuf[len - 1] != XP_PATH_SEPARATOR_CHAR) { + aBuf[len] = XP_PATH_SEPARATOR_CHAR; ++len; aBuf[len] = 0; } @@ -1225,28 +1227,41 @@ PrepareChildExceptionTimeAnnotations() static XP_CHAR tempPath[XP_PATH_MAX] = {0}; // Get the temp path + int charsAvailable = XP_PATH_MAX; + XP_CHAR* p = tempPath; +#if (defined(XP_MACOSX) || defined(XP_WIN)) + if (!childProcessTmpDir || childProcessTmpDir->empty()) { + return; + } + p = Concat(p, childProcessTmpDir->c_str(), &charsAvailable); + // Ensure that this path ends with a path separator + if (p > tempPath && *(p - 1) != XP_PATH_SEPARATOR_CHAR) { + p = Concat(p, XP_PATH_SEPARATOR, &charsAvailable); + } +#else size_t tempPathLen = BuildTempPath(tempPath); if (!tempPathLen) { return; } + p += tempPathLen; + charsAvailable -= tempPathLen; +#endif // Generate and append the file name - int size = XP_PATH_MAX - tempPathLen; - XP_CHAR* p = tempPath + tempPathLen; - p = Concat(p, childCrashAnnotationBaseName, &size); + p = Concat(p, childCrashAnnotationBaseName, &charsAvailable); 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); + p = Concat(p, pidBuffer, &charsAvailable); // Now open the file... PlatformWriter apiData; OpenAPIData(apiData, tempPath); - // ...and write out any annotations. These should be escaped if necessary + // ...and write out any annotations. These must be escaped if necessary // (but don't call EscapeAnnotation here, because it touches the heap). char oomAllocationSizeBuffer[32] = ""; if (gOOMAllocationSize) { @@ -2901,7 +2916,7 @@ AppendExtraData(nsIFile* extraFile, const AnnotationTable& data) } static bool -GetExtraFileForChildPid(nsIFile* aMinidump, uint32_t aPid, nsIFile** aExtraFile) +GetExtraFileForChildPid(uint32_t aPid, nsIFile** aExtraFile) { MOZ_ASSERT(XRE_IsParentProcess()); @@ -2909,20 +2924,13 @@ GetExtraFileForChildPid(nsIFile* aMinidump, uint32_t aPid, nsIFile** aExtraFile) nsresult rv; #if defined(XP_WIN) || defined(XP_MACOSX) -# if defined(MOZ_CONTENT_SANDBOX) - if (!contentProcessTmpDir) { + if (!childProcessTmpDir) { return false; } - CreateFileFromPath(*contentProcessTmpDir, getter_AddRefs(extraFile)); + CreateFileFromPath(*childProcessTmpDir, 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)); @@ -2942,26 +2950,10 @@ GetExtraFileForChildPid(nsIFile* aMinidump, uint32_t aPid, nsIFile** aExtraFile) 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; @@ -3043,8 +3035,7 @@ WriteExtraForMinidump(nsIFile* minidump, nsCOMPtr exceptionTimeExtra; FILE* fd; - if (pid && GetExtraFileForChildPid(minidump, pid, - getter_AddRefs(exceptionTimeExtra)) && + if (pid && GetExtraFileForChildPid(pid, getter_AddRefs(exceptionTimeExtra)) && NS_SUCCEEDED(exceptionTimeExtra->OpenANSIFileDesc("r", &fd))) { AnnotationTable exceptionTimeAnnotations; ReadAndValidateExceptionTimeAnnotations(fd, exceptionTimeAnnotations); @@ -3181,13 +3172,25 @@ 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) +#if (defined(XP_WIN) || defined(XP_MACOSX)) nsCOMPtr tmpDir; - nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir)); - if (NS_SUCCEEDED(rv)) { - contentProcessTmpDir = CreatePathFromFile(tmpDir); +# if defined(MOZ_CONTENT_SANDBOX) + nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR, + getter_AddRefs(tmpDir)); + if (NS_FAILED(rv) && PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR")) { + // Temporary hack for xpcshell, will be fixed in bug 1257098 + rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir)); } -#endif + if (NS_SUCCEEDED(rv)) { + childProcessTmpDir = CreatePathFromFile(tmpDir); + } +# else + if (NS_SUCCEEDED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, + getter_AddRefs(tmpDir)))) { + childProcessTmpDir = CreatePathFromFile(tmpDir); + } +# endif // defined(MOZ_CONTENT_SANDBOX) +#endif // (defined(XP_WIN) || defined(XP_MACOSX)) #if defined(XP_WIN) childCrashNotifyPipe = @@ -3422,6 +3425,21 @@ GetLastRunCrashID(nsAString& id) return true; } +#if defined(XP_WIN) || defined(XP_MACOSX) +void +InitChildProcessTmpDir() +{ + MOZ_ASSERT(!XRE_IsParentProcess()); + // When retrieved by the child process, this will always resolve to the + // correct directory regardless of sandbox level. + nsCOMPtr tmpDir; + nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir)); + if (NS_SUCCEEDED(rv)) { + childProcessTmpDir = CreatePathFromFile(tmpDir); + } +} +#endif // defined(XP_WIN) || defined(XP_MACOSX) + #if defined(XP_WIN) // Child-side API bool diff --git a/toolkit/crashreporter/nsExceptionHandler.h b/toolkit/crashreporter/nsExceptionHandler.h index 066505a23a5..3e167fd9b76 100644 --- a/toolkit/crashreporter/nsExceptionHandler.h +++ b/toolkit/crashreporter/nsExceptionHandler.h @@ -237,6 +237,7 @@ void UnregisterInjectorCallback(DWORD processID); // Child-side API bool SetRemoteExceptionHandler(const nsACString& crashPipe); +void InitChildProcessTmpDir(); # elif defined(XP_LINUX) // Parent-side API for children diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index 57ec8477a91..d87a3a66bba 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -612,6 +612,10 @@ XRE_InitChildProcess(int aArgc, return NS_ERROR_FAILURE; } +#if defined(XP_WIN) || defined(XP_MACOSX) + CrashReporter::InitChildProcessTmpDir(); +#endif + #if defined(XP_WIN) // Set child processes up such that they will get killed after the // chrome process is killed in cases where the user shuts the system diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 3155352c836..1d89d6bbfb1 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -42,6 +42,7 @@ #ifdef XP_WIN #include #include +#include "mozilla/WindowsVersion.h" #endif #ifdef XP_MACOSX #include "nsILocalFileMac.h" @@ -643,6 +644,20 @@ GetContentProcessTempBaseDirKey() nsresult nsXREDirProvider::LoadContentProcessTempDir() { +#if defined(XP_WIN) + const bool isSandboxDisabled = !mozilla::IsVistaOrLater() || + (Preferences::GetInt("security.sandbox.content.level") < 1); +#elif defined(XP_MACOSX) + const bool isSandboxDisabled = + Preferences::GetInt("security.sandbox.content.level") < 1; +#endif + + if (isSandboxDisabled) { + // Just use the normal temp directory if sandboxing is turned off + return NS_GetSpecialDirectory(NS_OS_TEMP_DIR, + getter_AddRefs(mContentTempDir)); + } + nsCOMPtr localFile; nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),