Bug 1386404 - Intercept access to /tmp and rewrite to content process tempdir. r?jld
MozReview-Commit-ID: 2h9hw6opYof
--- 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);
}
--- 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<const Policy> 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<nsIFile> 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.
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -138,16 +138,18 @@ class SandboxBroker final
SandboxBroker(UniquePtr<const Policy> 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:
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -228,18 +228,16 @@ SandboxBrokerPolicyFactory::SandboxBroke
policy->AddDir(rdonly, "/usr/lib32");
policy->AddDir(rdonly, "/usr/lib64");
policy->AddDir(rdonly, "/etc");
#ifdef MOZ_PULSEAUDIO
policy->AddPath(rdonly, "/var/lib/dbus/machine-id");
#endif
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);