# HG changeset patch # User Gian-Carlo Pascutto # Date 1509033049 -7200 # Node ID 773543190318862160daf7e5f23a66b514318c64 # Parent 029e9c37b174c5560be2301d74d9f37a9529c71f Bug 1386404 - Intercept access to /tmp and rewrite to content process tempdir. r=jld MozReview-Commit-ID: 2h9hw6opYof diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -515,20 +515,16 @@ GeckoChildProcessHost::PerformAsyncLaunc } #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX) if (!mTmpDirName.IsEmpty()) { // Point a bunch of things that might want to write from content to our // shiny new content-process specific tmpdir mLaunchOptions->env_map[ENVIRONMENT_LITERAL("TMPDIR")] = ENVIRONMENT_STRING(mTmpDirName); - mLaunchOptions->env_map[ENVIRONMENT_LITERAL("XDG_CACHE_HOME")] = - ENVIRONMENT_STRING(mTmpDirName); - mLaunchOptions->env_map[ENVIRONMENT_LITERAL("XDG_CACHE_DIR")] = - ENVIRONMENT_STRING(mTmpDirName); // Partial fix for bug 1380051 (not persistent - should be) mLaunchOptions->env_map[ENVIRONMENT_LITERAL("MESA_GLSL_CACHE_DIR")] = ENVIRONMENT_STRING(mTmpDirName); } #endif return PerformAsyncLaunchInternal(aExtraOpts); } diff --git a/security/sandbox/linux/broker/SandboxBroker.cpp b/security/sandbox/linux/broker/SandboxBroker.cpp --- a/security/sandbox/linux/broker/SandboxBroker.cpp +++ b/security/sandbox/linux/broker/SandboxBroker.cpp @@ -23,16 +23,19 @@ #include "base/string_util.h" #include "mozilla/Assertions.h" #include "mozilla/DebugOnly.h" #include "mozilla/Move.h" #include "mozilla/NullPtr.h" #include "mozilla/Sprintf.h" #include "mozilla/ipc/FileDescriptor.h" +#include "nsDirectoryServiceDefs.h" +#include "nsAppDirectoryServiceDefs.h" +#include "SpecialSystemDirectory.h" #include "sandbox/linux/system_headers/linux_syscalls.h" namespace mozilla { // This constructor signals failure by setting mFileDesc and aClientFd to -1. SandboxBroker::SandboxBroker(UniquePtr aPolicy, int aChildPid, int& aClientFd) : mChildPid(aChildPid), mPolicy(Move(aPolicy)) @@ -510,16 +513,44 @@ SandboxBroker::ConvertToRealPath(char* a // Size changed, but guaranteed to be 0 terminated aPathLen = strlen(aPath); } // ValidatePath will handle failure to translate } return aPathLen; } +size_t +SandboxBroker::RemapTempDirs(char* aPath, size_t aBufSize, size_t aPathLen) +{ + nsAutoCString path(aPath); + static const nsLiteralCString tempPrefix(NS_LITERAL_CSTRING("/tmp")); + + if (StringBeginsWith(path, tempPrefix)) { + size_t prefixLen = tempPrefix.Length(); + const nsDependentCSubstring cutPath = + Substring(path, prefixLen, path.Length() - prefixLen); + // Only now try to get the content process temp dir + nsCOMPtr tmpDir; + nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR, + getter_AddRefs(tmpDir)); + if (NS_SUCCEEDED(rv)) { + nsAutoCString tmpPath; + rv = tmpDir->GetNativePath(tmpPath); + if (NS_SUCCEEDED(rv)) { + tmpPath.Append(cutPath); + base::strlcpy(aPath, tmpPath.get(), aBufSize); + return strlen(aPath); + } + } + } + + return aPathLen; +} + nsCString SandboxBroker::ReverseSymlinks(const nsACString& aPath) { // Revert any symlinks we previously resolved. int32_t cutLength = aPath.Length(); nsCString cutPath(Substring(aPath, 0, cutLength)); for (;;) { @@ -670,16 +701,17 @@ SandboxBroker::ThreadMain(void) // enforced below. strncpy(pathBuf2, recvBuf + first_len + 1, kMaxPathLen + 1); // First string is guaranteed to be 0-terminated. pathLen = first_len; // Look up the first pathname but first translate relative paths. pathLen = ConvertToRealPath(pathBuf, sizeof(pathBuf), pathLen); + pathLen = RemapTempDirs(pathBuf, sizeof(pathBuf), pathLen); perms = mPolicy->Lookup(nsDependentCString(pathBuf, pathLen)); // We don't have read permissions on the requested dir. // Did we arrive from a symlink in a path that is not writable? // Then try to figure out the original path and see if that is readable. if (!(perms & MAY_READ)) { // Work on the original path, // this reverses ConvertToRealPath above. diff --git a/security/sandbox/linux/broker/SandboxBroker.h b/security/sandbox/linux/broker/SandboxBroker.h --- a/security/sandbox/linux/broker/SandboxBroker.h +++ b/security/sandbox/linux/broker/SandboxBroker.h @@ -138,16 +138,18 @@ class SandboxBroker final SandboxBroker(UniquePtr aPolicy, int aChildPid, int& aClientFd); void ThreadMain(void) override; void AuditPermissive(int aOp, int aFlags, int aPerms, const char* aPath); void AuditDenial(int aOp, int aFlags, int aPerms, const char* aPath); // Remap relative paths to absolute paths. size_t ConvertToRealPath(char* aPath, size_t aBufSize, size_t aPathLen); + // Remap references to /tmp and friends to the content process tempdir + size_t RemapTempDirs(char* aPath, size_t aBufSize, size_t aPathLen); nsCString ReverseSymlinks(const nsACString& aPath); // Retrieves permissions for the path the original symlink sits in. int SymlinkPermissions(const char* aPath, const size_t aPathLen); // In SandboxBrokerRealPath.cpp char* SymlinkPath(const Policy* aPolicy, const char* __restrict aPath, char* __restrict aResolved, int* aPermission); // Holding a UniquePtr should disallow copying, but to make that explicit: diff --git a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp --- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp +++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp @@ -205,18 +205,16 @@ SandboxBrokerPolicyFactory::SandboxBroke policy->AddDir(rdonly, "/lib"); policy->AddDir(rdonly, "/lib64"); policy->AddDir(rdonly, "/usr/lib"); policy->AddDir(rdonly, "/usr/lib32"); policy->AddDir(rdonly, "/usr/lib64"); policy->AddDir(rdonly, "/etc"); policy->AddDir(rdonly, "/usr/share"); policy->AddDir(rdonly, "/usr/local/share"); - policy->AddDir(rdonly, "/usr/tmp"); - policy->AddDir(rdonly, "/var/tmp"); // Various places where fonts reside policy->AddDir(rdonly, "/usr/X11R6/lib/X11/fonts"); policy->AddDir(rdonly, "/nix/store"); policy->AddDir(rdonly, "/run/host/fonts"); policy->AddDir(rdonly, "/run/host/user-fonts"); AddMesaSysfsPaths(policy); AddLdconfigPaths(policy);