gentoo-overlay/www-client/chromium/files/chromium-dev-shm-r0.patch

193 lines
6.7 KiB
Diff

Backport http://codereview.chromium.org/8800025 to fix issues with noexec /dev/shm
diff --git a/base/file_util.h b/base/file_util.h
index 90ec1ae..78827e9 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -259,7 +259,7 @@ BASE_EXPORT bool IsDirectoryEmpty(const FilePath& dir_path);
BASE_EXPORT bool GetTempDir(FilePath* path);
// Get a temporary directory for shared memory files.
// Only useful on POSIX; redirects to GetTempDir() on Windows.
-BASE_EXPORT bool GetShmemTempDir(FilePath* path);
+BASE_EXPORT bool GetShmemTempDir(FilePath* path, bool executable);
// Get the home directory. This is more complicated than just getenv("HOME")
// as it knows to fall back on getpwent() etc.
@@ -279,7 +279,10 @@ BASE_EXPORT bool CreateTemporaryFileInDir(const FilePath& dir,
// Returns a handle to the opened file or NULL if an error occured.
BASE_EXPORT FILE* CreateAndOpenTemporaryFile(FilePath* path);
// Like above but for shmem files. Only useful for POSIX.
-BASE_EXPORT FILE* CreateAndOpenTemporaryShmemFile(FilePath* path);
+// The executable flag says the file needs to support using
+// mprotect with PROT_EXEC after mapping.
+BASE_EXPORT FILE* CreateAndOpenTemporaryShmemFile(FilePath* path,
+ bool executable);
// Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|.
BASE_EXPORT FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir,
FilePath* path);
diff --git a/base/file_util_android.cc b/base/file_util_android.cc
index eff3a46..6807d8d 100644
--- a/base/file_util_android.cc
+++ b/base/file_util_android.cc
@@ -8,7 +8,7 @@
namespace file_util {
-bool GetShmemTempDir(FilePath* path) {
+bool GetShmemTempDir(FilePath* path, bool executable) {
*path = FilePath("/data/local/tmp");
return true;
}
diff --git a/base/file_util_mac.mm b/base/file_util_mac.mm
index 95d4f25..bb4975d 100644
--- a/base/file_util_mac.mm
+++ b/base/file_util_mac.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,7 +22,7 @@ bool GetTempDir(FilePath* path) {
return true;
}
-bool GetShmemTempDir(FilePath* path) {
+bool GetShmemTempDir(FilePath* path, bool executable) {
return GetTempDir(path);
}
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 582f70e..5c14abd 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -481,9 +481,9 @@ bool CreateTemporaryFile(FilePath* path) {
return true;
}
-FILE* CreateAndOpenTemporaryShmemFile(FilePath* path) {
+FILE* CreateAndOpenTemporaryShmemFile(FilePath* path, bool executable) {
FilePath directory;
- if (!GetShmemTempDir(&directory))
+ if (!GetShmemTempDir(&directory, executable))
return NULL;
return CreateAndOpenTemporaryFileInDir(directory, path);
@@ -910,15 +910,52 @@ bool GetTempDir(FilePath* path) {
}
#if !defined(OS_ANDROID)
-bool GetShmemTempDir(FilePath* path) {
+
#if defined(OS_LINUX)
- *path = FilePath("/dev/shm");
- return true;
-#else
- return GetTempDir(path);
-#endif
+// Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC.
+// This depends on the mount options used for /dev/shm, which vary among
+// different Linux distributions and possibly local configuration. It also
+// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm
+// but its kernel allows mprotect with PROT_EXEC anyway.
+
+namespace {
+
+bool DetermineDevShmExecutable() {
+ bool result = false;
+ FilePath path;
+ int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path);
+ if (fd >= 0) {
+ ScopedFD shm_fd_closer(&fd);
+ Delete(path, false);
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+ void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
+ if (mapping != MAP_FAILED) {
+ if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
+ result = true;
+ munmap(mapping, pagesize);
+ }
+ }
+ return result;
}
+
+}; // namespace
+#endif // defined(OS_LINUX)
+
+bool GetShmemTempDir(FilePath* path, bool executable) {
+#if defined(OS_LINUX)
+ bool use_dev_shm = true;
+ if (executable) {
+ static const bool s_dev_shm_executable = DetermineDevShmExecutable();
+ use_dev_shm = s_dev_shm_executable;
+ }
+ if (use_dev_shm) {
+ *path = FilePath("/dev/shm");
+ return true;
+ }
#endif
+ return GetTempDir(path);
+}
+#endif // !defined(OS_ANDROID)
FilePath GetHomeDir() {
const char* home_dir = getenv("HOME");
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index 00cacd6..a9f9377 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -1545,7 +1545,7 @@ TEST_F(FileUtilTest, CreateNewTemporaryDirInDirTest) {
TEST_F(FileUtilTest, GetShmemTempDirTest) {
FilePath dir;
- EXPECT_TRUE(file_util::GetShmemTempDir(&dir));
+ EXPECT_TRUE(file_util::GetShmemTempDir(&dir, false));
EXPECT_TRUE(file_util::DirectoryExists(dir));
}
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 8d9fbde..a6720a5 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -556,7 +556,7 @@ bool GetTempDir(FilePath* path) {
return true;
}
-bool GetShmemTempDir(FilePath* path) {
+bool GetShmemTempDir(FilePath* path, bool executable) {
return GetTempDir(path);
}
@@ -576,7 +576,7 @@ bool CreateTemporaryFile(FilePath* path) {
return false;
}
-FILE* CreateAndOpenTemporaryShmemFile(FilePath* path) {
+FILE* CreateAndOpenTemporaryShmemFile(FilePath* path, bool executable) {
base::ThreadRestrictions::AssertIOAllowed();
return CreateAndOpenTemporaryFile(path);
}
diff --git a/base/shared_memory_posix.cc b/base/shared_memory_posix.cc
index 030061a..a66c859 100644
--- a/base/shared_memory_posix.cc
+++ b/base/shared_memory_posix.cc
@@ -123,7 +123,7 @@ bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
DCHECK(!options.open_existing);
// Q: Why not use the shm_open() etc. APIs?
// A: Because they're limited to 4mb on OS X. FFFFFFFUUUUUUUUUUU
- fp = file_util::CreateAndOpenTemporaryShmemFile(&path);
+ fp = file_util::CreateAndOpenTemporaryShmemFile(&path, options.executable);
// Deleting the file prevents anyone else from mapping it in
// (making it private), and prevents the need for cleanup (once
@@ -317,7 +317,7 @@ bool SharedMemory::FilePathForMemoryName(const std::string& mem_name,
DCHECK_EQ(std::string::npos, mem_name.find('\0'));
FilePath temp_dir;
- if (!file_util::GetShmemTempDir(&temp_dir))
+ if (!file_util::GetShmemTempDir(&temp_dir, false))
return false;
#if !defined(OS_MACOSX)
--
1.7.6.1