Bug 1386404 - Use the full tmpdir finding logic. r?jld
MozReview-Commit-ID: BDBslEZsctJ
--- a/security/sandbox/linux/broker/SandboxBroker.cpp
+++ b/security/sandbox/linux/broker/SandboxBroker.cpp
@@ -30,16 +30,19 @@
#include "mozilla/ipc/FileDescriptor.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "SpecialSystemDirectory.h"
#include "sandbox/linux/system_headers/linux_syscalls.h"
namespace mozilla {
+// Default/fallback temporary directory
+static const nsLiteralCString tempDirPrefix(NS_LITERAL_CSTRING("/tmp"));
+
// 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))
{
int fds[2];
if (0 != socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds)) {
SANDBOX_LOG_ERROR("SandboxBroker: socketpair failed: %s", strerror(errno));
@@ -517,22 +520,28 @@ SandboxBroker::ConvertToRealPath(char* a
}
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();
+ size_t prefixLen = 0;
+ if (!mTempPath.IsEmpty() && StringBeginsWith(path, mTempPath)) {
+ prefixLen = mTempPath.Length();
+ } else if (StringBeginsWith(path, tempDirPrefix)) {
+ prefixLen = tempDirPrefix.Length();
+ }
+
+ if (prefixLen) {
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)) {
@@ -611,16 +620,42 @@ SandboxBroker::ThreadMain(void)
SprintfLiteral(threadName, "FS Broker %d", mChildPid);
PlatformThread::SetName(threadName);
// Permissive mode can only be enabled through an environment variable,
// therefore it is sufficient to fetch the value once
// before the main thread loop starts
bool permissive = SandboxInfo::Get().Test(SandboxInfo::kPermissive);
+ // Find the current temporary directory
+ nsCOMPtr<nsIFile> tmpDir;
+ nsresult rv = GetSpecialSystemDirectory(OS_TemporaryDirectory,
+ getter_AddRefs(tmpDir));
+ if (NS_SUCCEEDED(rv)) {
+ rv = tmpDir->GetNativePath(mTempPath);
+ if (NS_SUCCEEDED(rv)) {
+ // Make sure there's no terminating /
+ if (mTempPath.Last() == '/') {
+ mTempPath.Truncate(mTempPath.Length() - 1);
+ }
+ }
+ }
+ // If we can't find it, we aren't bothered much: we will
+ // always try /tmp anyway in the substitution code
+ if (NS_FAILED(rv) || mTempPath.IsEmpty()) {
+ SANDBOX_LOG_ERROR("Tempdir: /tmp");
+ } else {
+ SANDBOX_LOG_ERROR("Tempdir: %s", mTempPath.get());
+ // If it's /tmp, clear it here so we don't compare against
+ // it twice. Just let the fallback code do the work.
+ if (mTempPath.Equals(tempDirPrefix)) {
+ mTempPath.Truncate();
+ }
+ }
+
while (true) {
struct iovec ios[2];
// We will receive the path strings in 1 buffer and split them back up.
char recvBuf[2 * (kMaxPathLen + 1)];
char pathBuf[kMaxPathLen + 1];
char pathBuf2[kMaxPathLen + 1];
size_t pathLen = 0;
size_t pathLen2 = 0;
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -127,16 +127,17 @@ class SandboxBroker final
ipc::FileDescriptor& aClientFdOut);
virtual ~SandboxBroker();
private:
PlatformThreadHandle mThread;
int mFileDesc;
const int mChildPid;
const UniquePtr<const Policy> mPolicy;
+ nsCString mTempPath;
typedef nsDataHashtable<nsCStringHashKey, nsCString> PathMap;
PathMap mSymlinkMap;
SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
int& aClientFd);
void ThreadMain(void) override;
void AuditPermissive(int aOp, int aFlags, int aPerms, const char* aPath);