Bug 1256541: Fix incorrect generation of path for child process .extra files when content sandboxing is disabled; r=bsmedberg, a=lizzard

MozReview-Commit-ID: JQgqlntQ6cu
This commit is contained in:
Aaron Klotz 2016-03-16 12:35:50 -06:00
parent 6a3b9aff95
commit 920cf5f82c
4 changed files with 82 additions and 44 deletions

View File

@ -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)
// "<reporter path>" "<minidump path>"
#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<nsIFile> 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<nsIFile> 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<nsIFile> 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

View File

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

View File

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

View File

@ -42,6 +42,7 @@
#ifdef XP_WIN
#include <windows.h>
#include <shlobj.h>
#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<nsIFile> localFile;
nsresult rv = NS_GetSpecialDirectory(GetContentProcessTempBaseDirKey(),