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 namespace { |
| 922 |
| 923 bool DetermineDevShmExecutable() { |
| 924 bool result = false; |
| 925 FilePath path; |
| 926 int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path); |
| 927 if (fd >= 0) { |
| 928 ScopedFD shm_fd_closer(&fd); |
| 929 Delete(path, false); |
| 930 size_t pagesize = sysconf(_SC_PAGESIZE); |
| 931 void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); |
| 932 if (mapping != MAP_FAILED) { |
| 933 if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0) |
| 934 result = true; |
| 935 munmap(mapping, pagesize); |
| 936 } |
| 937 } |
| 938 return result; |
| 939 } |
| 940 |
| 941 }; // namespace |
| 942 #endif // defined(OS_LINUX) |
| 943 |
| 944 bool GetShmemTempDir(FilePath* path, bool executable) { |
| 945 #if defined(OS_LINUX) |
| 946 bool use_dev_shm = true; |
| 947 if (executable) { |
| 948 static const bool s_dev_shm_executable = DetermineDevShmExecutable(); |
| 949 use_dev_shm = s_dev_shm_executable; |
| 950 } |
| 951 if (use_dev_shm) { |
| 952 *path = FilePath("/dev/shm"); |
| 953 return true; |
| 954 } |
| 955 #endif |
918 return GetTempDir(path); | 956 return GetTempDir(path); |
919 #endif | |
920 } | 957 } |
921 #endif | 958 #endif // !defined(OS_ANDROID) |
922 | 959 |
923 FilePath GetHomeDir() { | 960 FilePath GetHomeDir() { |
924 const char* home_dir = getenv("HOME"); | 961 const char* home_dir = getenv("HOME"); |
925 if (home_dir && home_dir[0]) | 962 if (home_dir && home_dir[0]) |
926 return FilePath(home_dir); | 963 return FilePath(home_dir); |
927 | 964 |
928 #if defined(OS_ANDROID) | 965 #if defined(OS_ANDROID) |
929 DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; | 966 DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; |
930 #else | 967 #else |
931 // g_get_home_dir calls getpwent, which can fall through to LDAP calls. | 968 // 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 | 1093 |
1057 allowed_group_ids.insert(group_record->gr_gid); | 1094 allowed_group_ids.insert(group_record->gr_gid); |
1058 } | 1095 } |
1059 | 1096 |
1060 return VerifyPathControlledByUser( | 1097 return VerifyPathControlledByUser( |
1061 kFileSystemRoot, path, kRootUid, allowed_group_ids); | 1098 kFileSystemRoot, path, kRootUid, allowed_group_ids); |
1062 } | 1099 } |
1063 #endif // defined(OS_MACOSX) | 1100 #endif // defined(OS_MACOSX) |
1064 | 1101 |
1065 } // namespace file_util | 1102 } // namespace file_util |
OLD | NEW |