Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3845)

Unified Diff: base/file_util_posix.cc

Issue 8800025: Adaptively use temp dir instead of /dev/shm for executable shmem file on Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/file_util_mac.mm ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/file_util_posix.cc
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 582f70ed7c6450c7e3e3b228368abaebcc2f4cb3..d40b6ab2d93cadd44b795b321719d6569189e721 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,66 @@ 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.
+//
+// Do this once the first time we need to know. The global variable
+// storing the state is not locked, so there is the possibility of a race
+// here. But it should be a harmless one, since the answer should come back
+// the same on multiple attempts.
+
+namespace {
+
+enum DevShmExecutable {
+ DevShmExecutableUnknown,
+ DevShmExecutableYes,
+ DevShmExecutableNo
+} g_dev_shm_executable;
+
+DevShmExecutable DetermineDevShmExecutable() {
+ if (g_dev_shm_executable == DevShmExecutableUnknown) {
+ FilePath path;
+ int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path);
Mark Mentovai 2011/12/05 23:44:47 A ScopedFDClose would be a good idea here.
+ if (fd < 0) {
+ g_dev_shm_executable = DevShmExecutableNo;
+ } else {
+ Delete(path, false);
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+ void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0);
+ if (mapping == MAP_FAILED) {
+ g_dev_shm_executable = DevShmExecutableNo;
+ } else {
+ if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0)
+ g_dev_shm_executable = DevShmExecutableYes;
+ else
+ g_dev_shm_executable = DevShmExecutableNo;
+ munmap(mapping, pagesize);
+ }
+ close(fd);
+ }
+ }
+ return g_dev_shm_executable;
}
+
+}; // namespace
+#endif // defined(OS_LINUX)
+
+bool GetShmemTempDir(FilePath* path, bool executable) {
+#if defined(OS_LINUX)
+ if (!executable ||
Mark Mentovai 2011/12/05 23:44:47 It might be better to do: DevShmExecutable dev_
+ DetermineDevShmExecutable() == DevShmExecutableYes) {
+ *path = FilePath("/dev/shm");
+ return true;
+ }
#endif
+ return GetTempDir(path);
+}
+#endif // !defined(OS_ANDROID)
FilePath GetHomeDir() {
const char* home_dir = getenv("HOME");
« no previous file with comments | « base/file_util_mac.mm ('k') | base/file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698