Chromium Code Reviews| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/base_switches.h" | 11 #include "base/base_switches.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/move.h" | |
| 17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| 18 #include "base/process/launch.h" | 19 #include "base/process/launch.h" |
| 19 #include "base/process/process_iterator.h" | 20 #include "base/process/process_iterator.h" |
| 20 #include "base/rand_util.h" | 21 #include "base/rand_util.h" |
| 22 #include "base/scoped_generic.h" | |
| 21 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 22 #include "base/strings/string_split.h" | 24 #include "base/strings/string_split.h" |
| 23 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
| 24 #include "base/strings/stringprintf.h" | 26 #include "base/strings/stringprintf.h" |
| 25 #include "base/strings/utf_string_conversions.h" | 27 #include "base/strings/utf_string_conversions.h" |
| 26 #include "base/threading/sequenced_worker_pool.h" | 28 #include "base/threading/sequenced_worker_pool.h" |
| 27 #include "base/win/windows_version.h" | 29 #include "base/win/windows_version.h" |
| 28 #include "build/build_config.h" | 30 #include "build/build_config.h" |
| 29 #include "components/nacl/browser/nacl_browser.h" | 31 #include "components/nacl/browser/nacl_browser.h" |
| 30 #include "components/nacl/browser/nacl_browser_delegate.h" | 32 #include "components/nacl/browser/nacl_browser_delegate.h" |
| 31 #include "components/nacl/browser/nacl_host_message_filter.h" | 33 #include "components/nacl/browser/nacl_host_message_filter.h" |
| 32 #include "components/nacl/common/nacl_cmd_line.h" | 34 #include "components/nacl/common/nacl_cmd_line.h" |
| 33 #include "components/nacl/common/nacl_host_messages.h" | 35 #include "components/nacl/common/nacl_host_messages.h" |
| 34 #include "components/nacl/common/nacl_messages.h" | 36 #include "components/nacl/common/nacl_messages.h" |
| 35 #include "components/nacl/common/nacl_process_type.h" | 37 #include "components/nacl/common/nacl_process_type.h" |
| 36 #include "components/nacl/common/nacl_switches.h" | 38 #include "components/nacl/common/nacl_switches.h" |
| 37 #include "content/public/browser/browser_child_process_host.h" | 39 #include "content/public/browser/browser_child_process_host.h" |
| 38 #include "content/public/browser/browser_ppapi_host.h" | 40 #include "content/public/browser/browser_ppapi_host.h" |
| 39 #include "content/public/browser/child_process_data.h" | 41 #include "content/public/browser/child_process_data.h" |
| 40 #include "content/public/browser/plugin_service.h" | 42 #include "content/public/browser/plugin_service.h" |
| 41 #include "content/public/browser/render_process_host.h" | 43 #include "content/public/browser/render_process_host.h" |
| 42 #include "content/public/browser/web_contents.h" | 44 #include "content/public/browser/web_contents.h" |
| 43 #include "content/public/common/child_process_host.h" | 45 #include "content/public/common/child_process_host.h" |
| 44 #include "content/public/common/content_switches.h" | 46 #include "content/public/common/content_switches.h" |
| 45 #include "content/public/common/process_type.h" | 47 #include "content/public/common/process_type.h" |
| 46 #include "content/public/common/sandboxed_process_launcher_delegate.h" | 48 #include "content/public/common/sandboxed_process_launcher_delegate.h" |
| 47 #include "ipc/ipc_channel.h" | 49 #include "ipc/ipc_channel.h" |
| 50 #include "ipc/ipc_channel_handle.h" | |
| 51 #include "ipc/ipc_platform_file.h" | |
| 48 #include "ipc/ipc_switches.h" | 52 #include "ipc/ipc_switches.h" |
| 49 #include "native_client/src/shared/imc/nacl_imc_c.h" | 53 #include "native_client/src/shared/imc/nacl_imc_c.h" |
| 50 #include "net/base/net_util.h" | 54 #include "net/base/net_util.h" |
| 51 #include "net/socket/tcp_listen_socket.h" | 55 #include "net/socket/tcp_listen_socket.h" |
| 52 #include "ppapi/host/host_factory.h" | 56 #include "ppapi/host/host_factory.h" |
| 53 #include "ppapi/host/ppapi_host.h" | 57 #include "ppapi/host/ppapi_host.h" |
| 54 #include "ppapi/proxy/ppapi_messages.h" | 58 #include "ppapi/proxy/ppapi_messages.h" |
| 55 #include "ppapi/shared_impl/ppapi_constants.h" | 59 #include "ppapi/shared_impl/ppapi_constants.h" |
| 56 #include "ppapi/shared_impl/ppapi_nacl_plugin_args.h" | 60 #include "ppapi/shared_impl/ppapi_nacl_plugin_args.h" |
| 57 | 61 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 return (base::win::OSInfo::GetInstance()->wow64_status() == | 146 return (base::win::OSInfo::GetInstance()->wow64_status() == |
| 143 base::win::OSInfo::WOW64_ENABLED); | 147 base::win::OSInfo::WOW64_ENABLED); |
| 144 } | 148 } |
| 145 | 149 |
| 146 } // namespace | 150 } // namespace |
| 147 | 151 |
| 148 #endif // defined(OS_WIN) | 152 #endif // defined(OS_WIN) |
| 149 | 153 |
| 150 namespace { | 154 namespace { |
| 151 | 155 |
| 156 // Usually, NaClProcessHost is working on IO thread, where file operation is | |
|
Mark Seaborn
2015/04/17 22:13:45
As an aside: I am sceptical that close() or CloseH
hidehiko
2015/04/30 16:33:01
According to my coworker who is the expert of Wind
| |
| 157 // not allowed. So, even just for closing the file, it is necessary to post | |
| 158 // the task to blocking pool. Note that, it is safer to use this from | |
| 159 // NaClProcessHost's destructor runnign on IO thread, because BlockingPool | |
|
Mark Seaborn
2015/04/17 22:13:45
"running"
hidehiko
2015/04/30 16:33:02
Acknowledged.
| |
| 160 // is ensured to be alive while the IO thread is alive. | |
| 161 void CloseFile(base::File file) { | |
|
Mark Seaborn
2015/04/17 22:13:45
CloseFile() is a rather generic name. Maybe Close
hidehiko
2015/04/30 16:33:01
Then, probably PostCloseFile etc. would be better.
| |
| 162 if (!file.IsValid()) { | |
| 163 return; | |
| 164 } | |
| 165 | |
| 166 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 167 FROM_HERE, | |
| 168 base::Bind(&(ignore_result<base::File>), base::Passed(&file))); | |
|
Mark Seaborn
2015/04/17 22:13:45
Nit: is it possible to omit the ()s in "&(ignore_r
hidehiko
2015/04/30 16:33:02
Reflected in another CL. I just misunderstood it m
| |
| 169 } | |
| 170 | |
| 171 // Define "Scoped" handles as utilities to avoid resource leaks. | |
| 172 struct PlatformFileForTransitTraits { | |
| 173 static IPC::PlatformFileForTransit InvalidValue() { | |
| 174 return IPC::InvalidPlatformFileForTransit(); | |
| 175 } | |
| 176 | |
| 177 static void Free(const IPC::PlatformFileForTransit& file) { | |
| 178 CloseFile(IPC::PlatformFileForTransitToFile(file).Pass()); | |
|
Mark Seaborn
2015/04/17 22:13:45
I think this is unsafe on Windows, because this is
hidehiko
2015/04/30 16:33:01
You're right. Fixed.
| |
| 179 } | |
| 180 }; | |
| 181 | |
| 182 typedef base::ScopedGeneric< | |
| 183 IPC::PlatformFileForTransit, PlatformFileForTransitTraits> | |
| 184 ScopedPlatformFileForTransit; | |
| 185 | |
| 186 struct SharedMemoryHandleTraits { | |
| 187 static base::SharedMemoryHandle InvalidValue() { | |
| 188 return base::SharedMemory::NULLHandle(); | |
| 189 } | |
| 190 | |
| 191 static void Free(const base::SharedMemoryHandle& handle) { | |
| 192 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 193 base::SharedMemory::CloseHandle(handle); | |
| 194 } | |
| 195 }; | |
| 196 | |
| 197 typedef base::ScopedGeneric< | |
| 198 base::SharedMemoryHandle, SharedMemoryHandleTraits> | |
| 199 ScopedSharedMemoryHandle; | |
| 200 | |
| 152 // NOTE: changes to this class need to be reviewed by the security team. | 201 // NOTE: changes to this class need to be reviewed by the security team. |
| 153 class NaClSandboxedProcessLauncherDelegate | 202 class NaClSandboxedProcessLauncherDelegate |
| 154 : public content::SandboxedProcessLauncherDelegate { | 203 : public content::SandboxedProcessLauncherDelegate { |
| 155 public: | 204 public: |
| 156 NaClSandboxedProcessLauncherDelegate(ChildProcessHost* host) | 205 NaClSandboxedProcessLauncherDelegate(ChildProcessHost* host) |
| 157 #if defined(OS_POSIX) | 206 #if defined(OS_POSIX) |
| 158 : ipc_fd_(host->TakeClientFileDescriptor()) | 207 : ipc_fd_(host->TakeClientFileDescriptor()) |
| 159 #endif | 208 #endif |
| 160 {} | 209 {} |
| 161 | 210 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 187 | 236 |
| 188 void SetCloseOnExec(NaClHandle fd) { | 237 void SetCloseOnExec(NaClHandle fd) { |
| 189 #if defined(OS_POSIX) | 238 #if defined(OS_POSIX) |
| 190 int flags = fcntl(fd, F_GETFD); | 239 int flags = fcntl(fd, F_GETFD); |
| 191 CHECK_NE(flags, -1); | 240 CHECK_NE(flags, -1); |
| 192 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | 241 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
| 193 CHECK_EQ(rc, 0); | 242 CHECK_EQ(rc, 0); |
| 194 #endif | 243 #endif |
| 195 } | 244 } |
| 196 | 245 |
| 197 bool ShareHandleToSelLdr( | |
| 198 base::ProcessHandle processh, | |
| 199 NaClHandle sourceh, | |
| 200 bool close_source, | |
| 201 std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) { | |
| 202 #if defined(OS_WIN) | |
| 203 HANDLE channel; | |
| 204 int flags = DUPLICATE_SAME_ACCESS; | |
| 205 if (close_source) | |
| 206 flags |= DUPLICATE_CLOSE_SOURCE; | |
| 207 if (!DuplicateHandle(GetCurrentProcess(), | |
| 208 reinterpret_cast<HANDLE>(sourceh), | |
| 209 processh, | |
| 210 &channel, | |
| 211 0, // Unused given DUPLICATE_SAME_ACCESS. | |
| 212 FALSE, | |
| 213 flags)) { | |
| 214 LOG(ERROR) << "DuplicateHandle() failed"; | |
| 215 return false; | |
| 216 } | |
| 217 handles_for_sel_ldr->push_back( | |
| 218 reinterpret_cast<nacl::FileDescriptor>(channel)); | |
| 219 #else | |
| 220 nacl::FileDescriptor channel; | |
| 221 channel.fd = sourceh; | |
| 222 channel.auto_close = close_source; | |
| 223 handles_for_sel_ldr->push_back(channel); | |
| 224 #endif | |
| 225 return true; | |
| 226 } | |
| 227 | |
| 228 void CloseFile(base::File file) { | |
| 229 // The base::File destructor will close the file for us. | |
| 230 } | |
| 231 | |
| 232 } // namespace | 246 } // namespace |
| 233 | 247 |
| 234 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = | 248 unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = |
| 235 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; | 249 ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; |
| 236 | 250 |
| 251 // Unfortunately, we cannot use ScopedGeneric directly for IPC::ChannelHandle, | |
| 252 // because there is neither operator== nor operator!= definition for | |
|
Mark Seaborn
2015/04/17 22:13:45
Did you consider defining those operators on IPC::
hidehiko
2015/04/30 16:33:02
Defining operator== or operator!= needs to be in t
| |
| 253 // IPC::ChannelHandle. Instead, define a simple wrapper for IPC::ChannelHandle, | |
| 254 // here. | |
| 255 class NaClProcessHost::ScopedChannelHandle { | |
| 256 MOVE_ONLY_TYPE_FOR_CPP_03(ScopedChannelHandle, RValue); | |
| 257 public: | |
| 258 ScopedChannelHandle() { | |
| 259 } | |
| 260 ScopedChannelHandle(const IPC::ChannelHandle& handle) : handle_(handle) { | |
| 261 } | |
| 262 ScopedChannelHandle(RValue other) : handle_(other.object->handle_) { | |
| 263 other.object->handle_ = IPC::ChannelHandle(); | |
| 264 } | |
| 265 ~ScopedChannelHandle() { | |
| 266 CloseIfNecessary(); | |
| 267 } | |
| 268 | |
| 269 const IPC::ChannelHandle& get() const { return handle_; } | |
| 270 IPC::ChannelHandle release() WARN_UNUSED_RESULT { | |
| 271 IPC::ChannelHandle result = handle_; | |
| 272 handle_ = IPC::ChannelHandle(); | |
| 273 return result; | |
| 274 } | |
| 275 void reset(const IPC::ChannelHandle& handle = IPC::ChannelHandle()) { | |
| 276 // It is not allowed to reset with the same (non-invalid) handle. | |
|
Mark Seaborn
2015/04/17 22:13:45
Can you say why?
hidehiko
2015/04/30 16:33:02
Done.
| |
| 277 #if defined(OS_WIN) | |
| 278 CHECK(handle.pipe.handle == NULL || | |
| 279 handle.pipe.handle != handle_.pipe.handle); | |
| 280 #elif defined(OS_POSIX) | |
| 281 CHECK(handle.socket.fd == -1 || | |
| 282 !handle.socket.auto_close || | |
|
Mark Seaborn
2015/04/17 22:13:45
Why check auto_close as part of the comparison?
hidehiko
2015/04/30 16:33:02
Acknowledged.
| |
| 283 handle.socket.fd != handle_.socket.fd); | |
| 284 #endif | |
|
Mark Seaborn
2015/04/17 22:13:45
"#else
#error Unknown platform"?
hidehiko
2015/04/30 16:33:02
Acknowledged.
| |
| 285 CloseIfNecessary(); | |
| 286 handle_ = handle; | |
| 287 } | |
| 288 | |
| 289 private: | |
| 290 void CloseIfNecessary() { | |
| 291 #if defined(OS_WIN) | |
|
Mark Seaborn
2015/04/17 22:13:45
How about adding a Close() method to IPC::ChannelH
hidehiko
2015/04/30 16:33:01
Again, our code depends on some constraint, so hav
| |
| 292 // Defer closing task to the ScopedHandle. | |
| 293 base::win::ScopedHandle(handle_.pipe.handle); | |
|
Mark Seaborn
2015/04/17 22:13:45
Strangely, this *isn't* going through BlockingPool
hidehiko
2015/04/30 16:33:02
Acknowledged.
| |
| 294 #elif defined(OS_POSIX) | |
| 295 if (handle_.socket.auto_close) { | |
| 296 // Defer closing task to the ScopedFD. | |
| 297 base::ScopedFD(handle_.socket.fd); | |
| 298 } | |
| 299 #endif | |
|
Mark Seaborn
2015/04/17 22:13:45
Ditto: add an #else #error?
hidehiko
2015/04/30 16:33:01
Acknowledged.
| |
| 300 } | |
| 301 | |
| 302 IPC::ChannelHandle handle_; | |
| 303 }; | |
| 304 | |
| 237 NaClProcessHost::NaClProcessHost( | 305 NaClProcessHost::NaClProcessHost( |
| 238 const GURL& manifest_url, | 306 const GURL& manifest_url, |
| 239 base::File nexe_file, | 307 base::File nexe_file, |
| 240 const NaClFileToken& nexe_token, | 308 const NaClFileToken& nexe_token, |
| 241 const std::vector< | 309 const std::vector< |
| 242 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, | 310 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, |
| 243 ppapi::PpapiPermissions permissions, | 311 ppapi::PpapiPermissions permissions, |
| 244 int render_view_id, | 312 int render_view_id, |
| 245 uint32 permission_bits, | 313 uint32 permission_bits, |
| 246 bool uses_nonsfi_mode, | 314 bool uses_nonsfi_mode, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 276 // for this use case. | 344 // for this use case. |
| 277 process_->SetName(net::FormatUrl(manifest_url_, std::string())); | 345 process_->SetName(net::FormatUrl(manifest_url_, std::string())); |
| 278 | 346 |
| 279 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 347 enable_debug_stub_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 280 switches::kEnableNaClDebug); | 348 switches::kEnableNaClDebug); |
| 281 DCHECK(process_type_ != kUnknownNaClProcessType); | 349 DCHECK(process_type_ != kUnknownNaClProcessType); |
| 282 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; | 350 enable_crash_throttling_ = process_type_ != kNativeNaClProcessType; |
| 283 } | 351 } |
| 284 | 352 |
| 285 NaClProcessHost::~NaClProcessHost() { | 353 NaClProcessHost::~NaClProcessHost() { |
| 354 CloseFile(nexe_file_.Pass()); | |
| 355 | |
| 286 // Report exit status only if the process was successfully started. | 356 // Report exit status only if the process was successfully started. |
| 287 if (process_->GetData().handle != base::kNullProcessHandle) { | 357 if (process_->GetData().handle != base::kNullProcessHandle) { |
| 288 int exit_code = 0; | 358 int exit_code = 0; |
| 289 process_->GetTerminationStatus(false /* known_dead */, &exit_code); | 359 process_->GetTerminationStatus(false /* known_dead */, &exit_code); |
| 290 std::string message = | 360 std::string message = |
| 291 base::StringPrintf("NaCl process exited with status %i (0x%x)", | 361 base::StringPrintf("NaCl process exited with status %i (0x%x)", |
| 292 exit_code, exit_code); | 362 exit_code, exit_code); |
| 293 if (exit_code == 0) { | 363 if (exit_code == 0) { |
| 294 VLOG(1) << message; | 364 VLOG(1) << message; |
| 295 } else { | 365 } else { |
| 296 LOG(ERROR) << message; | 366 LOG(ERROR) << message; |
| 297 } | 367 } |
| 298 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); | 368 NaClBrowser::GetInstance()->OnProcessEnd(process_->GetData().id); |
| 299 } | 369 } |
| 300 | 370 |
| 301 for (size_t i = 0; i < prefetched_resource_files_info_.size(); ++i) { | 371 for (size_t i = 0; i < prefetched_resource_files_info_.size(); ++i) { |
| 302 // The process failed to launch for some reason. Close resource file | 372 // The process failed to launch for some reason. Close resource file |
| 303 // handles. | 373 // handles. |
| 304 base::File file(IPC::PlatformFileForTransitToFile( | 374 CloseFile(IPC::PlatformFileForTransitToFile( |
| 305 prefetched_resource_files_info_[i].file)); | 375 prefetched_resource_files_info_[i].file).Pass()); |
| 306 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 307 FROM_HERE, | |
| 308 base::Bind(&CloseFile, base::Passed(file.Pass()))); | |
| 309 } | 376 } |
| 310 | 377 |
| 311 if (reply_msg_) { | 378 if (reply_msg_) { |
| 312 // The process failed to launch for some reason. | 379 // The process failed to launch for some reason. |
| 313 // Don't keep the renderer hanging. | 380 // Don't keep the renderer hanging. |
| 314 reply_msg_->set_reply_error(); | 381 reply_msg_->set_reply_error(); |
| 315 nacl_host_message_filter_->Send(reply_msg_); | 382 nacl_host_message_filter_->Send(reply_msg_); |
| 316 } | 383 } |
| 317 #if defined(OS_WIN) | 384 #if defined(OS_WIN) |
| 318 if (process_launched_by_broker_) { | 385 if (process_launched_by_broker_) { |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 void NaClProcessHost::OnResourcesReady() { | 742 void NaClProcessHost::OnResourcesReady() { |
| 676 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 743 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 677 if (!nacl_browser->IsReady()) { | 744 if (!nacl_browser->IsReady()) { |
| 678 SendErrorToRenderer("could not acquire shared resources needed by NaCl"); | 745 SendErrorToRenderer("could not acquire shared resources needed by NaCl"); |
| 679 delete this; | 746 delete this; |
| 680 } else if (!StartNaClExecution()) { | 747 } else if (!StartNaClExecution()) { |
| 681 delete this; | 748 delete this; |
| 682 } | 749 } |
| 683 } | 750 } |
| 684 | 751 |
| 685 bool NaClProcessHost::ReplyToRenderer( | 752 void NaClProcessHost::ReplyToRenderer( |
| 686 const IPC::ChannelHandle& ppapi_channel_handle, | 753 ScopedChannelHandle ppapi_channel_handle, |
| 687 const IPC::ChannelHandle& trusted_channel_handle, | 754 ScopedChannelHandle trusted_channel_handle, |
| 688 const IPC::ChannelHandle& manifest_service_channel_handle) { | 755 ScopedChannelHandle manifest_service_channel_handle) { |
| 689 #if defined(OS_WIN) | 756 #if defined(OS_WIN) |
| 690 // If we are on 64-bit Windows, the NaCl process's sandbox is | 757 // If we are on 64-bit Windows, the NaCl process's sandbox is |
| 691 // managed by a different process from the renderer's sandbox. We | 758 // managed by a different process from the renderer's sandbox. We |
| 692 // need to inform the renderer's sandbox about the NaCl process so | 759 // need to inform the renderer's sandbox about the NaCl process so |
| 693 // that the renderer can send handles to the NaCl process using | 760 // that the renderer can send handles to the NaCl process using |
| 694 // BrokerDuplicateHandle(). | 761 // BrokerDuplicateHandle(). |
| 695 if (RunningOnWOW64()) { | 762 if (RunningOnWOW64()) { |
| 696 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { | 763 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
| 697 SendErrorToRenderer("BrokerAddTargetPeer() failed"); | 764 SendErrorToRenderer("BrokerAddTargetPeer() failed"); |
| 698 return false; | 765 return; |
| 699 } | 766 } |
| 700 } | 767 } |
| 701 #endif | 768 #endif |
| 702 | 769 |
| 703 FileDescriptor imc_handle_for_renderer; | 770 ScopedPlatformFileForTransit imc_handle_for_renderer( |
| 704 #if defined(OS_WIN) | 771 IPC::TakeFileHandleForProcess(socket_for_renderer_.Pass(), |
| 705 // Copy the handle into the renderer process. | 772 nacl_host_message_filter_->PeerHandle())); |
| 706 HANDLE handle_in_renderer; | 773 if (!imc_handle_for_renderer.is_valid()) { |
| 707 if (!DuplicateHandle(base::GetCurrentProcessHandle(), | 774 SendErrorToRenderer("TakeFileHandleForProcess() failed"); |
| 708 socket_for_renderer_.TakePlatformFile(), | 775 return; |
| 709 nacl_host_message_filter_->PeerHandle(), | |
| 710 &handle_in_renderer, | |
| 711 0, // Unused given DUPLICATE_SAME_ACCESS. | |
| 712 FALSE, | |
| 713 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { | |
| 714 SendErrorToRenderer("DuplicateHandle() failed"); | |
| 715 return false; | |
| 716 } | 776 } |
| 717 imc_handle_for_renderer = reinterpret_cast<FileDescriptor>( | 777 |
| 718 handle_in_renderer); | 778 ScopedSharedMemoryHandle crash_info_shmem_renderer_handle; |
|
Mark Seaborn
2015/04/17 22:13:45
I think this is unsafe on Windows.
Remember, on W
hidehiko
2015/04/30 16:33:02
You're right. Fixed.
| |
| 719 #else | 779 { |
| 720 // No need to dup the imc_handle - we don't pass it anywhere else so | 780 base::SharedMemoryHandle raw_handle = base::SharedMemory::NULLHandle(); |
| 721 // it cannot be closed. | 781 if (crash_info_shmem_.ShareToProcess( |
| 722 FileDescriptor imc_handle; | 782 nacl_host_message_filter_->PeerHandle(), &raw_handle)) { |
| 723 imc_handle.fd = socket_for_renderer_.TakePlatformFile(); | 783 crash_info_shmem_renderer_handle.reset(raw_handle); |
| 724 imc_handle.auto_close = true; | 784 } |
| 725 imc_handle_for_renderer = imc_handle; | 785 } |
| 726 #endif | 786 if (!crash_info_shmem_renderer_handle.is_valid()) { |
| 787 SendErrorToRenderer("ShareToProcess() failed"); | |
| 788 return; | |
| 789 } | |
| 727 | 790 |
| 728 const ChildProcessData& data = process_->GetData(); | 791 const ChildProcessData& data = process_->GetData(); |
| 729 base::SharedMemoryHandle crash_info_shmem_renderer_handle; | 792 if (SendMessageToRenderer( |
| 730 if (!crash_info_shmem_.ShareToProcess(nacl_host_message_filter_->PeerHandle(), | 793 NaClLaunchResult(imc_handle_for_renderer.get(), |
| 731 &crash_info_shmem_renderer_handle)) { | 794 ppapi_channel_handle.get(), |
| 732 SendErrorToRenderer("ShareToProcess() failed"); | 795 trusted_channel_handle.get(), |
| 733 return false; | 796 manifest_service_channel_handle.get(), |
| 797 base::GetProcId(data.handle), | |
| 798 data.id, | |
| 799 crash_info_shmem_renderer_handle.get()), | |
| 800 std::string() /* error_message */)) { | |
| 801 // On success, the NaClLaunchResult is sent to renderer, so that the | |
| 802 // handles have been delegated to the message. | |
| 803 ignore_result(imc_handle_for_renderer.release()); | |
| 804 ignore_result(ppapi_channel_handle.release()); | |
| 805 ignore_result(trusted_channel_handle.release()); | |
| 806 ignore_result(manifest_service_channel_handle.release()); | |
| 807 ignore_result(crash_info_shmem_renderer_handle.release()); | |
| 734 } | 808 } |
| 735 | 809 |
| 736 SendMessageToRenderer( | |
| 737 NaClLaunchResult(imc_handle_for_renderer, | |
| 738 ppapi_channel_handle, | |
| 739 trusted_channel_handle, | |
| 740 manifest_service_channel_handle, | |
| 741 base::GetProcId(data.handle), | |
| 742 data.id, | |
| 743 crash_info_shmem_renderer_handle), | |
| 744 std::string() /* error_message */); | |
| 745 | |
| 746 // Now that the crash information shmem handles have been shared with the | 810 // Now that the crash information shmem handles have been shared with the |
| 747 // plugin and the renderer, the browser can close its handle. | 811 // plugin and the renderer, the browser can close its handle. |
| 748 crash_info_shmem_.Close(); | 812 crash_info_shmem_.Close(); |
| 749 return true; | |
| 750 } | 813 } |
| 751 | 814 |
| 752 void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) { | 815 void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) { |
| 753 LOG(ERROR) << "NaCl process launch failed: " << error_message; | 816 LOG(ERROR) << "NaCl process launch failed: " << error_message; |
| 754 SendMessageToRenderer(NaClLaunchResult(), error_message); | 817 SendMessageToRenderer(NaClLaunchResult(), error_message); |
| 755 } | 818 } |
| 756 | 819 |
| 757 void NaClProcessHost::SendMessageToRenderer( | 820 bool NaClProcessHost::SendMessageToRenderer( |
| 758 const NaClLaunchResult& result, | 821 const NaClLaunchResult& result, |
| 759 const std::string& error_message) { | 822 const std::string& error_message) { |
| 760 DCHECK(nacl_host_message_filter_.get()); | 823 DCHECK(nacl_host_message_filter_.get()); |
| 761 DCHECK(reply_msg_); | 824 DCHECK(reply_msg_); |
| 762 if (nacl_host_message_filter_.get() != NULL && reply_msg_ != NULL) { | 825 if (nacl_host_message_filter_.get() == NULL || reply_msg_ == NULL) { |
| 763 NaClHostMsg_LaunchNaCl::WriteReplyParams( | 826 return false; |
| 764 reply_msg_, result, error_message); | |
| 765 nacl_host_message_filter_->Send(reply_msg_); | |
| 766 nacl_host_message_filter_ = NULL; | |
| 767 reply_msg_ = NULL; | |
| 768 } | 827 } |
| 828 NaClHostMsg_LaunchNaCl::WriteReplyParams(reply_msg_, result, error_message); | |
| 829 nacl_host_message_filter_->Send(reply_msg_); | |
| 830 nacl_host_message_filter_ = NULL; | |
| 831 reply_msg_ = NULL; | |
| 832 return true; | |
| 769 } | 833 } |
| 770 | 834 |
| 771 void NaClProcessHost::SetDebugStubPort(int port) { | 835 void NaClProcessHost::SetDebugStubPort(int port) { |
| 772 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 836 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 773 nacl_browser->SetProcessGdbDebugStubPort(process_->GetData().id, port); | 837 nacl_browser->SetProcessGdbDebugStubPort(process_->GetData().id, port); |
| 774 } | 838 } |
| 775 | 839 |
| 776 #if defined(OS_POSIX) | 840 #if defined(OS_POSIX) |
| 777 // TCP port we chose for NaCl debug stub. It can be any other number. | 841 // TCP port we chose for NaCl debug stub. It can be any other number. |
| 778 static const uint16_t kInitialDebugStubPort = 4014; | 842 static const uint16_t kInitialDebugStubPort = 4014; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 817 bool NaClProcessHost::StartNaClExecution() { | 881 bool NaClProcessHost::StartNaClExecution() { |
| 818 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 882 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 819 | 883 |
| 820 NaClStartParams params; | 884 NaClStartParams params; |
| 821 | 885 |
| 822 // Enable PPAPI proxy channel creation only for renderer processes. | 886 // Enable PPAPI proxy channel creation only for renderer processes. |
| 823 params.enable_ipc_proxy = enable_ppapi_proxy(); | 887 params.enable_ipc_proxy = enable_ppapi_proxy(); |
| 824 params.process_type = process_type_; | 888 params.process_type = process_type_; |
| 825 bool enable_nacl_debug = enable_debug_stub_ && | 889 bool enable_nacl_debug = enable_debug_stub_ && |
| 826 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); | 890 NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); |
| 891 | |
| 892 // Because this function may return early on failure, so keep the resources | |
| 893 // in local variables, and pass them to params later. | |
| 894 ScopedPlatformFileForTransit socket_for_sel_ldr; | |
| 895 ScopedPlatformFileForTransit irt_file; | |
| 896 #if defined(OS_MACOSX) | |
| 897 base::ScopedFD memory_fd; | |
| 898 #endif | |
| 899 #if defined(OS_POSIX) | |
| 900 base::ScopedFD debug_stub_server_bound_socket; | |
| 901 #endif | |
| 902 | |
| 827 if (uses_nonsfi_mode_) { | 903 if (uses_nonsfi_mode_) { |
| 828 // Currently, non-SFI mode is supported only on Linux. | 904 // Currently, non-SFI mode is supported only on Linux. |
| 829 #if defined(OS_LINUX) | 905 #if defined(OS_LINUX) |
| 830 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is | 906 // In non-SFI mode, we do not use SRPC. Make sure that the socketpair is |
| 831 // not created. | 907 // not created. |
| 832 DCHECK(!socket_for_sel_ldr_.IsValid()); | 908 DCHECK(!socket_for_sel_ldr_.IsValid()); |
| 833 #endif | 909 #endif |
| 834 if (enable_nacl_debug) { | 910 if (enable_nacl_debug) { |
| 835 base::ProcessId pid = base::GetProcId(process_->GetData().handle); | 911 base::ProcessId pid = base::GetProcId(process_->GetData().handle); |
| 836 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; | 912 LOG(WARNING) << "nonsfi nacl plugin running in " << pid; |
| 837 } | 913 } |
| 838 } else { | 914 } else { |
| 839 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); | 915 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); |
| 840 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); | 916 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); |
| 841 params.version = NaClBrowser::GetDelegate()->GetVersionString(); | 917 params.version = NaClBrowser::GetDelegate()->GetVersionString(); |
| 842 params.enable_debug_stub = enable_nacl_debug; | 918 params.enable_debug_stub = enable_nacl_debug; |
| 843 params.enable_mojo = base::CommandLine::ForCurrentProcess()->HasSwitch( | 919 params.enable_mojo = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 844 switches::kEnableNaClMojo); | 920 switches::kEnableNaClMojo); |
| 845 | 921 |
| 846 const ChildProcessData& data = process_->GetData(); | 922 const ChildProcessData& data = process_->GetData(); |
| 847 if (!ShareHandleToSelLdr(data.handle, | 923 socket_for_sel_ldr.reset( |
| 848 socket_for_sel_ldr_.TakePlatformFile(), | 924 IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), |
| 849 true, | 925 data.handle)); |
| 850 ¶ms.handles)) { | 926 if (!socket_for_sel_ldr.is_valid()) { |
| 851 return false; | 927 return false; |
| 852 } | 928 } |
| 853 | 929 |
| 854 const base::File& irt_file = nacl_browser->IrtFile(); | 930 const base::File& original_irt_file = nacl_browser->IrtFile(); |
| 855 CHECK(irt_file.IsValid()); | 931 CHECK(original_irt_file.IsValid()); |
| 856 // Send over the IRT file handle. We don't close our own copy! | 932 // Send over the IRT file handle. We don't close our own copy! |
| 857 if (!ShareHandleToSelLdr(data.handle, irt_file.GetPlatformFile(), false, | 933 irt_file.reset(IPC::GetFileHandleForProcess( |
| 858 ¶ms.handles)) { | 934 original_irt_file.GetPlatformFile(), data.handle, false)); |
| 935 if (!irt_file.is_valid()) { | |
| 936 DLOG(ERROR) << "Failed to create irt_file handler for plugin."; | |
| 859 return false; | 937 return false; |
| 860 } | 938 } |
| 861 | 939 |
| 862 #if defined(OS_MACOSX) | 940 #if defined(OS_MACOSX) |
| 863 // For dynamic loading support, NaCl requires a file descriptor that | 941 // For dynamic loading support, NaCl requires a file descriptor that |
| 864 // was created in /tmp, since those created with shm_open() are not | 942 // was created in /tmp, since those created with shm_open() are not |
| 865 // mappable with PROT_EXEC. Rather than requiring an extra IPC | 943 // mappable with PROT_EXEC. Rather than requiring an extra IPC |
| 866 // round trip out of the sandbox, we create an FD here. | 944 // round trip out of the sandbox, we create an FD here. |
| 867 base::SharedMemory memory_buffer; | 945 base::SharedMemory memory_buffer; |
| 868 base::SharedMemoryCreateOptions options; | 946 base::SharedMemoryCreateOptions options; |
| 869 options.size = 1; | 947 options.size = 1; |
| 870 options.executable = true; | 948 options.executable = true; |
| 871 if (!memory_buffer.Create(options)) { | 949 if (!memory_buffer.Create(options)) { |
| 872 DLOG(ERROR) << "Failed to allocate memory buffer"; | 950 DLOG(ERROR) << "Failed to allocate memory buffer"; |
| 873 return false; | 951 return false; |
| 874 } | 952 } |
| 875 FileDescriptor memory_fd; | 953 memory_fd.reset(dup(memory_buffer.handle().fd)); |
| 876 memory_fd.fd = dup(memory_buffer.handle().fd); | 954 if (!memory_fd.is_valid()) { |
| 877 if (memory_fd.fd < 0) { | |
| 878 DLOG(ERROR) << "Failed to dup() a file descriptor"; | 955 DLOG(ERROR) << "Failed to dup() a file descriptor"; |
| 879 return false; | 956 return false; |
| 880 } | 957 } |
| 881 memory_fd.auto_close = true; | |
| 882 params.handles.push_back(memory_fd); | |
| 883 #endif | 958 #endif |
| 884 | 959 |
| 885 #if defined(OS_POSIX) | 960 #if defined(OS_POSIX) |
| 886 if (params.enable_debug_stub) { | 961 if (params.enable_debug_stub) { |
| 887 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); | 962 net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); |
| 888 if (server_bound_socket != net::kInvalidSocket) { | 963 if (server_bound_socket != net::kInvalidSocket) { |
| 889 params.debug_stub_server_bound_socket = | 964 debug_stub_server_bound_socket.reset(server_bound_socket); |
| 890 FileDescriptor(server_bound_socket, true); | |
| 891 } | 965 } |
| 892 } | 966 } |
| 893 #endif | 967 #endif |
| 894 } | 968 } |
| 895 | 969 |
| 896 if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, | 970 ScopedSharedMemoryHandle crash_info_shmem_handle; |
| 897 ¶ms.crash_info_shmem_handle)) { | 971 { |
| 972 base::SharedMemoryHandle raw_handle; | |
| 973 if (crash_info_shmem_.ShareToProcess( | |
| 974 process_->GetData().handle, &raw_handle)) { | |
| 975 crash_info_shmem_handle.reset(raw_handle); | |
| 976 } | |
| 977 } | |
| 978 if (!crash_info_shmem_handle.is_valid()) { | |
| 898 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; | 979 DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; |
| 899 return false; | 980 return false; |
| 900 } | 981 } |
| 901 | 982 |
| 902 base::FilePath file_path; | 983 // Hereafter, NaClProcessMsg_Start must be (eventually) sent. |
| 984 // Delegate the resources to NaClStartParams. | |
| 985 params.crash_info_shmem_handle = crash_info_shmem_handle.release(); | |
| 903 if (uses_nonsfi_mode_) { | 986 if (uses_nonsfi_mode_) { |
| 987 DCHECK(!socket_for_sel_ldr.is_valid()); | |
| 988 DCHECK(!irt_file.is_valid()); | |
| 989 #if defined(OS_MACOSX) | |
| 990 DCHECK(!memory_fd.is_valid()); | |
| 991 #endif | |
| 992 | |
| 904 // Don't retrieve the file path when using nonsfi mode; there's no | 993 // Don't retrieve the file path when using nonsfi mode; there's no |
| 905 // validation caching in that case, so it's unnecessary work, and would | 994 // validation caching in that case, so it's unnecessary work, and would |
| 906 // expose the file path to the plugin. | 995 // expose the file path to the plugin. |
| 907 | 996 |
| 908 // Pass the pre-opened resource files to the loader. For the same reason | 997 // Pass the pre-opened resource files to the loader. For the same reason |
| 909 // as above, use an empty base::FilePath. | 998 // as above, use an empty base::FilePath. |
| 910 for (size_t i = 0; i < prefetched_resource_files_info_.size(); ++i) { | 999 for (size_t i = 0; i < prefetched_resource_files_info_.size(); ++i) { |
| 911 params.prefetched_resource_files.push_back( | 1000 params.prefetched_resource_files.push_back( |
| 912 NaClResourceFileInfo(prefetched_resource_files_info_[i].file, | 1001 NaClResourceFileInfo(prefetched_resource_files_info_[i].file, |
| 913 base::FilePath(), | 1002 base::FilePath(), |
| 914 prefetched_resource_files_info_[i].file_key)); | 1003 prefetched_resource_files_info_[i].file_key)); |
| 915 } | 1004 } |
| 916 prefetched_resource_files_info_.clear(); | 1005 prefetched_resource_files_info_.clear(); |
| 917 } else { | 1006 } else { |
| 1007 // TODO(yusukes): Handle |prefetched_resource_files_info_| for SFI-NaCl. | |
| 1008 DCHECK(prefetched_resource_files_info_.empty()); | |
| 1009 | |
| 1010 params.handles.push_back(socket_for_sel_ldr.release()); | |
| 1011 params.handles.push_back(irt_file.release()); | |
| 1012 // Note that on OS_POSIX (including OS_MACOSX), IPC::PlatformFileForTransit | |
| 1013 // is the alias of base::FileDescriptor. | |
| 1014 #if defined(OS_MACOSX) | |
| 1015 params.handles.push_back(base::FileDescriptor(memory_fd.release(), true)); | |
| 1016 #endif | |
| 1017 #if defined(OS_POSIX) | |
| 1018 if (debug_stub_server_bound_socket.is_valid()) { | |
| 1019 params.debug_stub_server_bound_socket = | |
| 1020 base::FileDescriptor(debug_stub_server_bound_socket.release(), true); | |
| 1021 } | |
| 1022 #endif | |
| 1023 } | |
| 1024 | |
| 1025 if (!uses_nonsfi_mode_) { | |
| 1026 base::FilePath file_path; | |
| 918 if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, | 1027 if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, |
| 919 nexe_token_.hi, | 1028 nexe_token_.hi, |
| 920 &file_path)) { | 1029 &file_path)) { |
| 921 // We have to reopen the file in the browser process; we don't want a | 1030 // We have to reopen the file in the browser process; we don't want a |
| 922 // compromised renderer to pass an arbitrary fd that could get loaded | 1031 // compromised renderer to pass an arbitrary fd that could get loaded |
| 923 // into the plugin process. | 1032 // into the plugin process. |
| 924 if (base::PostTaskAndReplyWithResult( | 1033 if (base::PostTaskAndReplyWithResult( |
|
hidehiko
2015/04/17 07:25:32
Note: this code also has a potential resource leak
| |
| 925 content::BrowserThread::GetBlockingPool(), | 1034 content::BrowserThread::GetBlockingPool(), |
| 926 FROM_HERE, | 1035 FROM_HERE, |
| 927 base::Bind(OpenNaClReadExecImpl, | 1036 base::Bind(OpenNaClReadExecImpl, |
| 928 file_path, | 1037 file_path, |
| 929 true /* is_executable */), | 1038 true /* is_executable */), |
| 930 base::Bind(&NaClProcessHost::StartNaClFileResolved, | 1039 base::Bind(&NaClProcessHost::StartNaClFileResolved, |
| 931 weak_factory_.GetWeakPtr(), | 1040 weak_factory_.GetWeakPtr(), |
| 932 params, | 1041 params, |
| 933 file_path))) { | 1042 file_path))) { |
| 934 return true; | 1043 return true; |
| 935 } | 1044 } |
| 936 } | 1045 } |
| 937 // TODO(yusukes): Handle |prefetched_resource_files_info_| for SFI-NaCl. | |
| 938 DCHECK(prefetched_resource_files_info_.empty()); | |
| 939 } | 1046 } |
| 940 | 1047 |
| 941 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), | 1048 params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), |
| 942 process_->GetData().handle); | 1049 process_->GetData().handle); |
| 943 process_->Send(new NaClProcessMsg_Start(params)); | 1050 process_->Send(new NaClProcessMsg_Start(params)); |
| 944 return true; | 1051 return true; |
| 945 } | 1052 } |
| 946 | 1053 |
| 947 void NaClProcessHost::StartNaClFileResolved( | 1054 void NaClProcessHost::StartNaClFileResolved( |
| 948 NaClStartParams params, | 1055 NaClStartParams params, |
| 949 const base::FilePath& file_path, | 1056 const base::FilePath& file_path, |
| 950 base::File checked_nexe_file) { | 1057 base::File checked_nexe_file) { |
| 951 if (checked_nexe_file.IsValid()) { | 1058 if (checked_nexe_file.IsValid()) { |
| 952 // Release the file received from the renderer. This has to be done on a | 1059 // Release the file received from the renderer. |
| 953 // thread where IO is permitted, though. | 1060 CloseFile(nexe_file_.Pass()); |
| 954 content::BrowserThread::GetBlockingPool()->PostTask( | |
| 955 FROM_HERE, | |
| 956 base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); | |
| 957 params.nexe_file_path_metadata = file_path; | 1061 params.nexe_file_path_metadata = file_path; |
| 958 params.nexe_file = IPC::TakeFileHandleForProcess( | 1062 params.nexe_file = IPC::TakeFileHandleForProcess( |
| 959 checked_nexe_file.Pass(), process_->GetData().handle); | 1063 checked_nexe_file.Pass(), process_->GetData().handle); |
| 960 } else { | 1064 } else { |
| 961 params.nexe_file = IPC::TakeFileHandleForProcess( | 1065 params.nexe_file = IPC::TakeFileHandleForProcess( |
| 962 nexe_file_.Pass(), process_->GetData().handle); | 1066 nexe_file_.Pass(), process_->GetData().handle); |
| 963 } | 1067 } |
| 964 process_->Send(new NaClProcessMsg_Start(params)); | 1068 process_->Send(new NaClProcessMsg_Start(params)); |
| 965 } | 1069 } |
| 966 | 1070 |
| 967 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is | 1071 // This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
| 968 // received. | 1072 // received. |
| 969 void NaClProcessHost::OnPpapiChannelsCreated( | 1073 void NaClProcessHost::OnPpapiChannelsCreated( |
| 970 const IPC::ChannelHandle& browser_channel_handle, | 1074 const IPC::ChannelHandle& raw_browser_channel_handle, |
| 971 const IPC::ChannelHandle& ppapi_renderer_channel_handle, | 1075 const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, |
| 972 const IPC::ChannelHandle& trusted_renderer_channel_handle, | 1076 const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, |
| 973 const IPC::ChannelHandle& manifest_service_channel_handle) { | 1077 const IPC::ChannelHandle& raw_manifest_service_channel_handle) { |
| 1078 ScopedChannelHandle browser_channel_handle(raw_browser_channel_handle); | |
| 1079 ScopedChannelHandle ppapi_renderer_channel_handle( | |
| 1080 raw_ppapi_renderer_channel_handle); | |
| 1081 ScopedChannelHandle trusted_renderer_channel_handle( | |
| 1082 raw_trusted_renderer_channel_handle); | |
| 1083 ScopedChannelHandle manifest_service_channel_handle( | |
| 1084 raw_manifest_service_channel_handle); | |
| 974 if (!enable_ppapi_proxy()) { | 1085 if (!enable_ppapi_proxy()) { |
| 975 ReplyToRenderer(IPC::ChannelHandle(), | 1086 ReplyToRenderer(ScopedChannelHandle(), |
| 976 trusted_renderer_channel_handle, | 1087 trusted_renderer_channel_handle.Pass(), |
| 977 manifest_service_channel_handle); | 1088 manifest_service_channel_handle.Pass()); |
| 978 return; | 1089 return; |
| 979 } | 1090 } |
| 980 | 1091 |
| 981 if (!ipc_proxy_channel_.get()) { | 1092 if (!ipc_proxy_channel_.get()) { |
| 982 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); | 1093 DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); |
| 983 | 1094 |
| 984 ipc_proxy_channel_ = | 1095 ipc_proxy_channel_ = |
| 985 IPC::ChannelProxy::Create(browser_channel_handle, | 1096 IPC::ChannelProxy::Create(browser_channel_handle.release(), |
| 986 IPC::Channel::MODE_CLIENT, | 1097 IPC::Channel::MODE_CLIENT, |
| 987 NULL, | 1098 NULL, |
| 988 base::MessageLoopProxy::current().get()); | 1099 base::MessageLoopProxy::current().get()); |
| 989 // Create the browser ppapi host and enable PPAPI message dispatching to the | 1100 // Create the browser ppapi host and enable PPAPI message dispatching to the |
| 990 // browser process. | 1101 // browser process. |
| 991 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( | 1102 ppapi_host_.reset(content::BrowserPpapiHost::CreateExternalPluginProcess( |
| 992 ipc_proxy_channel_.get(), // sender | 1103 ipc_proxy_channel_.get(), // sender |
| 993 permissions_, | 1104 permissions_, |
| 994 process_->GetData().handle, | 1105 process_->GetData().handle, |
| 995 ipc_proxy_channel_.get(), | 1106 ipc_proxy_channel_.get(), |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1020 | 1131 |
| 1021 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( | 1132 ppapi_host_->GetPpapiHost()->AddHostFactoryFilter( |
| 1022 scoped_ptr<ppapi::host::HostFactory>( | 1133 scoped_ptr<ppapi::host::HostFactory>( |
| 1023 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( | 1134 NaClBrowser::GetDelegate()->CreatePpapiHostFactory( |
| 1024 ppapi_host_.get()))); | 1135 ppapi_host_.get()))); |
| 1025 | 1136 |
| 1026 // Send a message to initialize the IPC dispatchers in the NaCl plugin. | 1137 // Send a message to initialize the IPC dispatchers in the NaCl plugin. |
| 1027 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); | 1138 ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); |
| 1028 | 1139 |
| 1029 // Let the renderer know that the IPC channels are established. | 1140 // Let the renderer know that the IPC channels are established. |
| 1030 ReplyToRenderer(ppapi_renderer_channel_handle, | 1141 ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), |
| 1031 trusted_renderer_channel_handle, | 1142 trusted_renderer_channel_handle.Pass(), |
| 1032 manifest_service_channel_handle); | 1143 manifest_service_channel_handle.Pass()); |
| 1033 } else { | 1144 } else { |
| 1034 // Attempt to open more than 1 browser channel is not supported. | 1145 // Attempt to open more than 1 browser channel is not supported. |
| 1035 // Shut down the NaCl process. | 1146 // Shut down the NaCl process. |
| 1036 process_->GetHost()->ForceShutdown(); | 1147 process_->GetHost()->ForceShutdown(); |
| 1037 } | 1148 } |
| 1038 } | 1149 } |
| 1039 | 1150 |
| 1040 bool NaClProcessHost::StartWithLaunchedProcess() { | 1151 bool NaClProcessHost::StartWithLaunchedProcess() { |
| 1041 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); | 1152 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); |
| 1042 | 1153 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1208 process.Pass(), info, | 1319 process.Pass(), info, |
| 1209 base::MessageLoopProxy::current(), | 1320 base::MessageLoopProxy::current(), |
| 1210 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, | 1321 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, |
| 1211 weak_factory_.GetWeakPtr())); | 1322 weak_factory_.GetWeakPtr())); |
| 1212 return true; | 1323 return true; |
| 1213 } | 1324 } |
| 1214 } | 1325 } |
| 1215 #endif | 1326 #endif |
| 1216 | 1327 |
| 1217 } // namespace nacl | 1328 } // namespace nacl |
| OLD | NEW |