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 |