| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "components/nacl/browser/nacl_process_host.h" | 5 #include "components/nacl/browser/nacl_process_host.h" |
| 6 | 6 |
| 7 #include <string.h> |
| 8 |
| 7 #include <algorithm> | 9 #include <algorithm> |
| 8 #include <string> | 10 #include <string> |
| 9 #include <vector> | 11 #include <vector> |
| 10 | 12 |
| 11 #include "base/base_switches.h" | 13 #include "base/base_switches.h" |
| 12 #include "base/bind.h" | 14 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 14 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
| 15 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/macros.h" |
| 16 #include "base/metrics/histogram_macros.h" | 19 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 18 #include "base/process/launch.h" | 21 #include "base/process/launch.h" |
| 19 #include "base/process/process_iterator.h" | 22 #include "base/process/process_iterator.h" |
| 20 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
| 21 #include "base/single_thread_task_runner.h" | 24 #include "base/single_thread_task_runner.h" |
| 22 #include "base/strings/string_number_conversions.h" | 25 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/strings/string_split.h" | 26 #include "base/strings/string_split.h" |
| 24 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
| 25 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 // Allocates |size| bytes of address space in the given process at a | 129 // Allocates |size| bytes of address space in the given process at a |
| 127 // randomised address. | 130 // randomised address. |
| 128 void* AllocateAddressSpaceASLR(base::ProcessHandle process, size_t size) { | 131 void* AllocateAddressSpaceASLR(base::ProcessHandle process, size_t size) { |
| 129 char* addr; | 132 char* addr; |
| 130 size_t avail_size; | 133 size_t avail_size; |
| 131 FindAddressSpace(process, &addr, &avail_size); | 134 FindAddressSpace(process, &addr, &avail_size); |
| 132 if (avail_size < size) | 135 if (avail_size < size) |
| 133 return NULL; | 136 return NULL; |
| 134 size_t offset = base::RandGenerator(avail_size - size); | 137 size_t offset = base::RandGenerator(avail_size - size); |
| 135 const int kPageSize = 0x10000; | 138 const int kPageSize = 0x10000; |
| 136 void* request_addr = | 139 void* request_addr = reinterpret_cast<void*>( |
| 137 reinterpret_cast<void*>(reinterpret_cast<uint64>(addr + offset) | 140 reinterpret_cast<uint64_t>(addr + offset) & ~(kPageSize - 1)); |
| 138 & ~(kPageSize - 1)); | |
| 139 return VirtualAllocEx(process, request_addr, size, | 141 return VirtualAllocEx(process, request_addr, size, |
| 140 MEM_RESERVE, PAGE_NOACCESS); | 142 MEM_RESERVE, PAGE_NOACCESS); |
| 141 } | 143 } |
| 142 | 144 |
| 143 namespace { | 145 namespace { |
| 144 | 146 |
| 145 bool RunningOnWOW64() { | 147 bool RunningOnWOW64() { |
| 146 return (base::win::OSInfo::GetInstance()->wow64_status() == | 148 return (base::win::OSInfo::GetInstance()->wow64_status() == |
| 147 base::win::OSInfo::WOW64_ENABLED); | 149 base::win::OSInfo::WOW64_ENABLED); |
| 148 } | 150 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 IPC::ChannelHandle handle_; | 276 IPC::ChannelHandle handle_; |
| 275 }; | 277 }; |
| 276 | 278 |
| 277 NaClProcessHost::NaClProcessHost( | 279 NaClProcessHost::NaClProcessHost( |
| 278 const GURL& manifest_url, | 280 const GURL& manifest_url, |
| 279 base::File nexe_file, | 281 base::File nexe_file, |
| 280 const NaClFileToken& nexe_token, | 282 const NaClFileToken& nexe_token, |
| 281 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, | 283 const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, |
| 282 ppapi::PpapiPermissions permissions, | 284 ppapi::PpapiPermissions permissions, |
| 283 int render_view_id, | 285 int render_view_id, |
| 284 uint32 permission_bits, | 286 uint32_t permission_bits, |
| 285 bool uses_nonsfi_mode, | 287 bool uses_nonsfi_mode, |
| 286 bool off_the_record, | 288 bool off_the_record, |
| 287 NaClAppProcessType process_type, | 289 NaClAppProcessType process_type, |
| 288 const base::FilePath& profile_directory) | 290 const base::FilePath& profile_directory) |
| 289 : manifest_url_(manifest_url), | 291 : manifest_url_(manifest_url), |
| 290 nexe_file_(nexe_file.Pass()), | 292 nexe_file_(nexe_file.Pass()), |
| 291 nexe_token_(nexe_token), | 293 nexe_token_(nexe_token), |
| 292 prefetched_resource_files_(prefetched_resource_files), | 294 prefetched_resource_files_(prefetched_resource_files), |
| 293 permissions_(permissions), | 295 permissions_(permissions), |
| 294 #if defined(OS_WIN) | 296 #if defined(OS_WIN) |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 // Create a shared memory region that the renderer and plugin share for | 521 // Create a shared memory region that the renderer and plugin share for |
| 520 // reporting crash information. | 522 // reporting crash information. |
| 521 crash_info_shmem_.CreateAnonymous(kNaClCrashInfoShmemSize); | 523 crash_info_shmem_.CreateAnonymous(kNaClCrashInfoShmemSize); |
| 522 | 524 |
| 523 // Launch the process | 525 // Launch the process |
| 524 if (!LaunchSelLdr()) { | 526 if (!LaunchSelLdr()) { |
| 525 delete this; | 527 delete this; |
| 526 } | 528 } |
| 527 } | 529 } |
| 528 | 530 |
| 529 void NaClProcessHost::OnChannelConnected(int32 peer_pid) { | 531 void NaClProcessHost::OnChannelConnected(int32_t peer_pid) { |
| 530 if (!base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( | 532 if (!base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( |
| 531 switches::kNaClGdb).empty()) { | 533 switches::kNaClGdb).empty()) { |
| 532 LaunchNaClGdb(); | 534 LaunchNaClGdb(); |
| 533 } | 535 } |
| 534 } | 536 } |
| 535 | 537 |
| 536 #if defined(OS_WIN) | 538 #if defined(OS_WIN) |
| 537 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { | 539 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { |
| 538 process_launched_by_broker_ = true; | 540 process_launched_by_broker_ = true; |
| 539 process_->SetHandle(handle); | 541 process_->SetHandle(handle); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 | 821 |
| 820 #if defined(OS_POSIX) | 822 #if defined(OS_POSIX) |
| 821 // TCP port we chose for NaCl debug stub. It can be any other number. | 823 // TCP port we chose for NaCl debug stub. It can be any other number. |
| 822 static const uint16_t kInitialDebugStubPort = 4014; | 824 static const uint16_t kInitialDebugStubPort = 4014; |
| 823 | 825 |
| 824 net::SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() { | 826 net::SocketDescriptor NaClProcessHost::GetDebugStubSocketHandle() { |
| 825 // We always try to allocate the default port first. If this fails, we then | 827 // We always try to allocate the default port first. If this fails, we then |
| 826 // allocate any available port. | 828 // allocate any available port. |
| 827 // On success, if the test system has register a handler | 829 // On success, if the test system has register a handler |
| 828 // (GdbDebugStubPortListener), we fire a notification. | 830 // (GdbDebugStubPortListener), we fire a notification. |
| 829 uint16 port = kInitialDebugStubPort; | 831 uint16_t port = kInitialDebugStubPort; |
| 830 net::SocketDescriptor s = | 832 net::SocketDescriptor s = |
| 831 net::CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | 833 net::CreatePlatformSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
| 832 if (s != net::kInvalidSocket) { | 834 if (s != net::kInvalidSocket) { |
| 833 // Allow rapid reuse. | 835 // Allow rapid reuse. |
| 834 static const int kOn = 1; | 836 static const int kOn = 1; |
| 835 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); | 837 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); |
| 836 | 838 |
| 837 sockaddr_in addr; | 839 sockaddr_in addr; |
| 838 memset(&addr, 0, sizeof(addr)); | 840 memset(&addr, 0, sizeof(addr)); |
| 839 addr.sin_family = AF_INET; | 841 addr.sin_family = AF_INET; |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 1230 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 1229 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); | 1231 *result = nacl_browser->QueryKnownToValidate(signature, off_the_record_); |
| 1230 } | 1232 } |
| 1231 | 1233 |
| 1232 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { | 1234 void NaClProcessHost::OnSetKnownToValidate(const std::string& signature) { |
| 1233 CHECK(!uses_nonsfi_mode_); | 1235 CHECK(!uses_nonsfi_mode_); |
| 1234 NaClBrowser::GetInstance()->SetKnownToValidate( | 1236 NaClBrowser::GetInstance()->SetKnownToValidate( |
| 1235 signature, off_the_record_); | 1237 signature, off_the_record_); |
| 1236 } | 1238 } |
| 1237 | 1239 |
| 1238 void NaClProcessHost::OnResolveFileToken(uint64 file_token_lo, | 1240 void NaClProcessHost::OnResolveFileToken(uint64_t file_token_lo, |
| 1239 uint64 file_token_hi) { | 1241 uint64_t file_token_hi) { |
| 1240 // Was the file registered? | 1242 // Was the file registered? |
| 1241 // | 1243 // |
| 1242 // Note that the file path cache is of bounded size, and old entries can get | 1244 // Note that the file path cache is of bounded size, and old entries can get |
| 1243 // evicted. If a large number of NaCl modules are being launched at once, | 1245 // evicted. If a large number of NaCl modules are being launched at once, |
| 1244 // resolving the file_token may fail because the path cache was thrashed | 1246 // resolving the file_token may fail because the path cache was thrashed |
| 1245 // while the file_token was in flight. In this case the query fails, and we | 1247 // while the file_token was in flight. In this case the query fails, and we |
| 1246 // need to fall back to the slower path. | 1248 // need to fall back to the slower path. |
| 1247 // | 1249 // |
| 1248 // However: each NaCl process will consume 2-3 entries as it starts up, this | 1250 // However: each NaCl process will consume 2-3 entries as it starts up, this |
| 1249 // means that eviction will not happen unless you start up 33+ NaCl processes | 1251 // means that eviction will not happen unless you start up 33+ NaCl processes |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1376 NaClStartDebugExceptionHandlerThread( | 1378 NaClStartDebugExceptionHandlerThread( |
| 1377 process.Pass(), info, base::ThreadTaskRunnerHandle::Get(), | 1379 process.Pass(), info, base::ThreadTaskRunnerHandle::Get(), |
| 1378 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1380 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1379 weak_factory_.GetWeakPtr())); | 1381 weak_factory_.GetWeakPtr())); |
| 1380 return true; | 1382 return true; |
| 1381 } | 1383 } |
| 1382 } | 1384 } |
| 1383 #endif | 1385 #endif |
| 1384 | 1386 |
| 1385 } // namespace nacl | 1387 } // namespace nacl |
| OLD | NEW |