Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 | 6 |
| 7 #include <dirent.h> | 7 #include <dirent.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <fnmatch.h> | 10 #include <fnmatch.h> |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 FilePath directory; | 474 FilePath directory; |
| 475 if (!GetTempDir(&directory)) | 475 if (!GetTempDir(&directory)) |
| 476 return false; | 476 return false; |
| 477 int fd = CreateAndOpenFdForTemporaryFile(directory, path); | 477 int fd = CreateAndOpenFdForTemporaryFile(directory, path); |
| 478 if (fd < 0) | 478 if (fd < 0) |
| 479 return false; | 479 return false; |
| 480 ignore_result(HANDLE_EINTR(close(fd))); | 480 ignore_result(HANDLE_EINTR(close(fd))); |
| 481 return true; | 481 return true; |
| 482 } | 482 } |
| 483 | 483 |
| 484 FILE* CreateAndOpenTemporaryShmemFile(FilePath* path) { | 484 FILE* CreateAndOpenTemporaryShmemFile(FilePath* path, bool executable) { |
| 485 FilePath directory; | 485 FilePath directory; |
| 486 if (!GetShmemTempDir(&directory)) | 486 if (!GetShmemTempDir(&directory, executable)) |
| 487 return NULL; | 487 return NULL; |
| 488 | 488 |
| 489 return CreateAndOpenTemporaryFileInDir(directory, path); | 489 return CreateAndOpenTemporaryFileInDir(directory, path); |
| 490 } | 490 } |
| 491 | 491 |
| 492 FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { | 492 FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir, FilePath* path) { |
| 493 int fd = CreateAndOpenFdForTemporaryFile(dir, path); | 493 int fd = CreateAndOpenFdForTemporaryFile(dir, path); |
| 494 if (fd < 0) | 494 if (fd < 0) |
| 495 return NULL; | 495 return NULL; |
| 496 | 496 |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 903 else | 903 else |
| 904 #if defined(OS_ANDROID) | 904 #if defined(OS_ANDROID) |
| 905 *path = FilePath("/data/local/tmp"); | 905 *path = FilePath("/data/local/tmp"); |
| 906 #else | 906 #else |
| 907 *path = FilePath("/tmp"); | 907 *path = FilePath("/tmp"); |
| 908 #endif | 908 #endif |
| 909 return true; | 909 return true; |
| 910 } | 910 } |
| 911 | 911 |
| 912 #if !defined(OS_ANDROID) | 912 #if !defined(OS_ANDROID) |
| 913 bool GetShmemTempDir(FilePath* path) { | 913 |
| 914 #if defined(OS_LINUX) | 914 #if defined(OS_LINUX) |
| 915 *path = FilePath("/dev/shm"); | 915 // Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC. |
| 916 return true; | 916 // This depends on the mount options used for /dev/shm, which vary among |
| 917 #else | 917 // different Linux distributions and possibly local configuration. It also |
| 918 // depends on details of kernel--ChromeOS uses the noexec option for /dev/shm | |
| 919 // but its kernel allows mprotect with PROT_EXEC anyway. | |
| 920 // | |
| 921 // Do this once the first time we need to know. The global variable | |
| 922 // storing the state is not locked, so there is the possibility of a race | |
| 923 // here. But it should be a harmless one, since the answer should come back | |
| 924 // the same on multiple attempts. | |
| 925 | |
| 926 namespace { | |
| 927 | |
| 928 enum DevShmExecutable { | |
| 929 DevShmExecutableUnknown, | |
| 930 DevShmExecutableYes, | |
| 931 DevShmExecutableNo | |
| 932 } g_dev_shm_executable; | |
| 933 | |
| 934 DevShmExecutable DetermineDevShmExecutable() { | |
| 935 if (g_dev_shm_executable == DevShmExecutableUnknown) { | |
| 936 FilePath path; | |
| 937 int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path); | |
|
Mark Mentovai
2011/12/05 23:44:47
A ScopedFDClose would be a good idea here.
| |
| 938 if (fd < 0) { | |
| 939 g_dev_shm_executable = DevShmExecutableNo; | |
| 940 } else { | |
| 941 Delete(path, false); | |
| 942 size_t pagesize = sysconf(_SC_PAGESIZE); | |
| 943 void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); | |
| 944 if (mapping == MAP_FAILED) { | |
| 945 g_dev_shm_executable = DevShmExecutableNo; | |
| 946 } else { | |
| 947 if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0) | |
| 948 g_dev_shm_executable = DevShmExecutableYes; | |
| 949 else | |
| 950 g_dev_shm_executable = DevShmExecutableNo; | |
| 951 munmap(mapping, pagesize); | |
| 952 } | |
| 953 close(fd); | |
| 954 } | |
| 955 } | |
| 956 return g_dev_shm_executable; | |
| 957 } | |
| 958 | |
| 959 }; // namespace | |
| 960 #endif // defined(OS_LINUX) | |
| 961 | |
| 962 bool GetShmemTempDir(FilePath* path, bool executable) { | |
| 963 #if defined(OS_LINUX) | |
| 964 if (!executable || | |
|
Mark Mentovai
2011/12/05 23:44:47
It might be better to do:
DevShmExecutable dev_
| |
| 965 DetermineDevShmExecutable() == DevShmExecutableYes) { | |
| 966 *path = FilePath("/dev/shm"); | |
| 967 return true; | |
| 968 } | |
| 969 #endif | |
| 918 return GetTempDir(path); | 970 return GetTempDir(path); |
| 919 #endif | |
| 920 } | 971 } |
| 921 #endif | 972 #endif // !defined(OS_ANDROID) |
| 922 | 973 |
| 923 FilePath GetHomeDir() { | 974 FilePath GetHomeDir() { |
| 924 const char* home_dir = getenv("HOME"); | 975 const char* home_dir = getenv("HOME"); |
| 925 if (home_dir && home_dir[0]) | 976 if (home_dir && home_dir[0]) |
| 926 return FilePath(home_dir); | 977 return FilePath(home_dir); |
| 927 | 978 |
| 928 #if defined(OS_ANDROID) | 979 #if defined(OS_ANDROID) |
| 929 DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; | 980 DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; |
| 930 #else | 981 #else |
| 931 // g_get_home_dir calls getpwent, which can fall through to LDAP calls. | 982 // g_get_home_dir calls getpwent, which can fall through to LDAP calls. |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 | 1107 |
| 1057 allowed_group_ids.insert(group_record->gr_gid); | 1108 allowed_group_ids.insert(group_record->gr_gid); |
| 1058 } | 1109 } |
| 1059 | 1110 |
| 1060 return VerifyPathControlledByUser( | 1111 return VerifyPathControlledByUser( |
| 1061 kFileSystemRoot, path, kRootUid, allowed_group_ids); | 1112 kFileSystemRoot, path, kRootUid, allowed_group_ids); |
| 1062 } | 1113 } |
| 1063 #endif // defined(OS_MACOSX) | 1114 #endif // defined(OS_MACOSX) |
| 1064 | 1115 |
| 1065 } // namespace file_util | 1116 } // namespace file_util |
| OLD | NEW |