Index: components/nacl/browser/nacl_process_host.cc |
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc |
index 033502986c932dc6c41873e3eb18163df66670dd..ad82e31f8e86ac1f3dde600785989a1f4c8b1a18 100644 |
--- a/components/nacl/browser/nacl_process_host.cc |
+++ b/components/nacl/browser/nacl_process_host.cc |
@@ -14,10 +14,12 @@ |
#include "base/files/file_util.h" |
#include "base/message_loop/message_loop.h" |
#include "base/metrics/histogram.h" |
+#include "base/move.h" |
#include "base/path_service.h" |
#include "base/process/launch.h" |
#include "base/process/process_iterator.h" |
#include "base/rand_util.h" |
+#include "base/scoped_generic.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_split.h" |
#include "base/strings/string_util.h" |
@@ -45,6 +47,8 @@ |
#include "content/public/common/process_type.h" |
#include "content/public/common/sandboxed_process_launcher_delegate.h" |
#include "ipc/ipc_channel.h" |
+#include "ipc/ipc_channel_handle.h" |
+#include "ipc/ipc_platform_file.h" |
#include "ipc/ipc_switches.h" |
#include "native_client/src/shared/imc/nacl_imc_c.h" |
#include "net/base/net_util.h" |
@@ -149,6 +153,51 @@ bool RunningOnWOW64() { |
namespace { |
+// 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
|
+// not allowed. So, even just for closing the file, it is necessary to post |
+// the task to blocking pool. Note that, it is safer to use this from |
+// 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.
|
+// is ensured to be alive while the IO thread is alive. |
+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.
|
+ if (!file.IsValid()) { |
+ return; |
+ } |
+ |
+ content::BrowserThread::GetBlockingPool()->PostTask( |
+ FROM_HERE, |
+ 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
|
+} |
+ |
+// Define "Scoped" handles as utilities to avoid resource leaks. |
+struct PlatformFileForTransitTraits { |
+ static IPC::PlatformFileForTransit InvalidValue() { |
+ return IPC::InvalidPlatformFileForTransit(); |
+ } |
+ |
+ static void Free(const IPC::PlatformFileForTransit& file) { |
+ 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.
|
+ } |
+}; |
+ |
+typedef base::ScopedGeneric< |
+ IPC::PlatformFileForTransit, PlatformFileForTransitTraits> |
+ ScopedPlatformFileForTransit; |
+ |
+struct SharedMemoryHandleTraits { |
+ static base::SharedMemoryHandle InvalidValue() { |
+ return base::SharedMemory::NULLHandle(); |
+ } |
+ |
+ static void Free(const base::SharedMemoryHandle& handle) { |
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
+ base::SharedMemory::CloseHandle(handle); |
+ } |
+}; |
+ |
+typedef base::ScopedGeneric< |
+ base::SharedMemoryHandle, SharedMemoryHandleTraits> |
+ ScopedSharedMemoryHandle; |
+ |
// NOTE: changes to this class need to be reviewed by the security team. |
class NaClSandboxedProcessLauncherDelegate |
: public content::SandboxedProcessLauncherDelegate { |
@@ -194,46 +243,65 @@ void SetCloseOnExec(NaClHandle fd) { |
#endif |
} |
-bool ShareHandleToSelLdr( |
- base::ProcessHandle processh, |
- NaClHandle sourceh, |
- bool close_source, |
- std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) { |
-#if defined(OS_WIN) |
- HANDLE channel; |
- int flags = DUPLICATE_SAME_ACCESS; |
- if (close_source) |
- flags |= DUPLICATE_CLOSE_SOURCE; |
- if (!DuplicateHandle(GetCurrentProcess(), |
- reinterpret_cast<HANDLE>(sourceh), |
- processh, |
- &channel, |
- 0, // Unused given DUPLICATE_SAME_ACCESS. |
- FALSE, |
- flags)) { |
- LOG(ERROR) << "DuplicateHandle() failed"; |
- return false; |
- } |
- handles_for_sel_ldr->push_back( |
- reinterpret_cast<nacl::FileDescriptor>(channel)); |
-#else |
- nacl::FileDescriptor channel; |
- channel.fd = sourceh; |
- channel.auto_close = close_source; |
- handles_for_sel_ldr->push_back(channel); |
-#endif |
- return true; |
-} |
- |
-void CloseFile(base::File file) { |
- // The base::File destructor will close the file for us. |
-} |
- |
} // namespace |
unsigned NaClProcessHost::keepalive_throttle_interval_milliseconds_ = |
ppapi::kKeepaliveThrottleIntervalDefaultMilliseconds; |
+// Unfortunately, we cannot use ScopedGeneric directly for IPC::ChannelHandle, |
+// 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
|
+// IPC::ChannelHandle. Instead, define a simple wrapper for IPC::ChannelHandle, |
+// here. |
+class NaClProcessHost::ScopedChannelHandle { |
+ MOVE_ONLY_TYPE_FOR_CPP_03(ScopedChannelHandle, RValue); |
+ public: |
+ ScopedChannelHandle() { |
+ } |
+ ScopedChannelHandle(const IPC::ChannelHandle& handle) : handle_(handle) { |
+ } |
+ ScopedChannelHandle(RValue other) : handle_(other.object->handle_) { |
+ other.object->handle_ = IPC::ChannelHandle(); |
+ } |
+ ~ScopedChannelHandle() { |
+ CloseIfNecessary(); |
+ } |
+ |
+ const IPC::ChannelHandle& get() const { return handle_; } |
+ IPC::ChannelHandle release() WARN_UNUSED_RESULT { |
+ IPC::ChannelHandle result = handle_; |
+ handle_ = IPC::ChannelHandle(); |
+ return result; |
+ } |
+ void reset(const IPC::ChannelHandle& handle = IPC::ChannelHandle()) { |
+ // 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.
|
+#if defined(OS_WIN) |
+ CHECK(handle.pipe.handle == NULL || |
+ handle.pipe.handle != handle_.pipe.handle); |
+#elif defined(OS_POSIX) |
+ CHECK(handle.socket.fd == -1 || |
+ !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.
|
+ handle.socket.fd != handle_.socket.fd); |
+#endif |
Mark Seaborn
2015/04/17 22:13:45
"#else
#error Unknown platform"?
hidehiko
2015/04/30 16:33:02
Acknowledged.
|
+ CloseIfNecessary(); |
+ handle_ = handle; |
+ } |
+ |
+ private: |
+ void CloseIfNecessary() { |
+#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
|
+ // Defer closing task to the ScopedHandle. |
+ 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.
|
+#elif defined(OS_POSIX) |
+ if (handle_.socket.auto_close) { |
+ // Defer closing task to the ScopedFD. |
+ base::ScopedFD(handle_.socket.fd); |
+ } |
+#endif |
Mark Seaborn
2015/04/17 22:13:45
Ditto: add an #else #error?
hidehiko
2015/04/30 16:33:01
Acknowledged.
|
+ } |
+ |
+ IPC::ChannelHandle handle_; |
+}; |
+ |
NaClProcessHost::NaClProcessHost( |
const GURL& manifest_url, |
base::File nexe_file, |
@@ -283,6 +351,8 @@ NaClProcessHost::NaClProcessHost( |
} |
NaClProcessHost::~NaClProcessHost() { |
+ CloseFile(nexe_file_.Pass()); |
+ |
// Report exit status only if the process was successfully started. |
if (process_->GetData().handle != base::kNullProcessHandle) { |
int exit_code = 0; |
@@ -301,11 +371,8 @@ NaClProcessHost::~NaClProcessHost() { |
for (size_t i = 0; i < prefetched_resource_files_info_.size(); ++i) { |
// The process failed to launch for some reason. Close resource file |
// handles. |
- base::File file(IPC::PlatformFileForTransitToFile( |
- prefetched_resource_files_info_[i].file)); |
- content::BrowserThread::GetBlockingPool()->PostTask( |
- FROM_HERE, |
- base::Bind(&CloseFile, base::Passed(file.Pass()))); |
+ CloseFile(IPC::PlatformFileForTransitToFile( |
+ prefetched_resource_files_info_[i].file).Pass()); |
} |
if (reply_msg_) { |
@@ -682,10 +749,10 @@ void NaClProcessHost::OnResourcesReady() { |
} |
} |
-bool NaClProcessHost::ReplyToRenderer( |
- const IPC::ChannelHandle& ppapi_channel_handle, |
- const IPC::ChannelHandle& trusted_channel_handle, |
- const IPC::ChannelHandle& manifest_service_channel_handle) { |
+void NaClProcessHost::ReplyToRenderer( |
+ ScopedChannelHandle ppapi_channel_handle, |
+ ScopedChannelHandle trusted_channel_handle, |
+ ScopedChannelHandle manifest_service_channel_handle) { |
#if defined(OS_WIN) |
// If we are on 64-bit Windows, the NaCl process's sandbox is |
// managed by a different process from the renderer's sandbox. We |
@@ -695,58 +762,54 @@ bool NaClProcessHost::ReplyToRenderer( |
if (RunningOnWOW64()) { |
if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { |
SendErrorToRenderer("BrokerAddTargetPeer() failed"); |
- return false; |
+ return; |
} |
} |
#endif |
- FileDescriptor imc_handle_for_renderer; |
-#if defined(OS_WIN) |
- // Copy the handle into the renderer process. |
- HANDLE handle_in_renderer; |
- if (!DuplicateHandle(base::GetCurrentProcessHandle(), |
- socket_for_renderer_.TakePlatformFile(), |
- nacl_host_message_filter_->PeerHandle(), |
- &handle_in_renderer, |
- 0, // Unused given DUPLICATE_SAME_ACCESS. |
- FALSE, |
- DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
- SendErrorToRenderer("DuplicateHandle() failed"); |
- return false; |
+ ScopedPlatformFileForTransit imc_handle_for_renderer( |
+ IPC::TakeFileHandleForProcess(socket_for_renderer_.Pass(), |
+ nacl_host_message_filter_->PeerHandle())); |
+ if (!imc_handle_for_renderer.is_valid()) { |
+ SendErrorToRenderer("TakeFileHandleForProcess() failed"); |
+ return; |
} |
- imc_handle_for_renderer = reinterpret_cast<FileDescriptor>( |
- handle_in_renderer); |
-#else |
- // No need to dup the imc_handle - we don't pass it anywhere else so |
- // it cannot be closed. |
- FileDescriptor imc_handle; |
- imc_handle.fd = socket_for_renderer_.TakePlatformFile(); |
- imc_handle.auto_close = true; |
- imc_handle_for_renderer = imc_handle; |
-#endif |
- const ChildProcessData& data = process_->GetData(); |
- base::SharedMemoryHandle crash_info_shmem_renderer_handle; |
- if (!crash_info_shmem_.ShareToProcess(nacl_host_message_filter_->PeerHandle(), |
- &crash_info_shmem_renderer_handle)) { |
+ 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.
|
+ { |
+ base::SharedMemoryHandle raw_handle = base::SharedMemory::NULLHandle(); |
+ if (crash_info_shmem_.ShareToProcess( |
+ nacl_host_message_filter_->PeerHandle(), &raw_handle)) { |
+ crash_info_shmem_renderer_handle.reset(raw_handle); |
+ } |
+ } |
+ if (!crash_info_shmem_renderer_handle.is_valid()) { |
SendErrorToRenderer("ShareToProcess() failed"); |
- return false; |
+ return; |
} |
- SendMessageToRenderer( |
- NaClLaunchResult(imc_handle_for_renderer, |
- ppapi_channel_handle, |
- trusted_channel_handle, |
- manifest_service_channel_handle, |
- base::GetProcId(data.handle), |
- data.id, |
- crash_info_shmem_renderer_handle), |
- std::string() /* error_message */); |
+ const ChildProcessData& data = process_->GetData(); |
+ if (SendMessageToRenderer( |
+ NaClLaunchResult(imc_handle_for_renderer.get(), |
+ ppapi_channel_handle.get(), |
+ trusted_channel_handle.get(), |
+ manifest_service_channel_handle.get(), |
+ base::GetProcId(data.handle), |
+ data.id, |
+ crash_info_shmem_renderer_handle.get()), |
+ std::string() /* error_message */)) { |
+ // On success, the NaClLaunchResult is sent to renderer, so that the |
+ // handles have been delegated to the message. |
+ ignore_result(imc_handle_for_renderer.release()); |
+ ignore_result(ppapi_channel_handle.release()); |
+ ignore_result(trusted_channel_handle.release()); |
+ ignore_result(manifest_service_channel_handle.release()); |
+ ignore_result(crash_info_shmem_renderer_handle.release()); |
+ } |
// Now that the crash information shmem handles have been shared with the |
// plugin and the renderer, the browser can close its handle. |
crash_info_shmem_.Close(); |
- return true; |
} |
void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) { |
@@ -754,18 +817,19 @@ void NaClProcessHost::SendErrorToRenderer(const std::string& error_message) { |
SendMessageToRenderer(NaClLaunchResult(), error_message); |
} |
-void NaClProcessHost::SendMessageToRenderer( |
+bool NaClProcessHost::SendMessageToRenderer( |
const NaClLaunchResult& result, |
const std::string& error_message) { |
DCHECK(nacl_host_message_filter_.get()); |
DCHECK(reply_msg_); |
- if (nacl_host_message_filter_.get() != NULL && reply_msg_ != NULL) { |
- NaClHostMsg_LaunchNaCl::WriteReplyParams( |
- reply_msg_, result, error_message); |
- nacl_host_message_filter_->Send(reply_msg_); |
- nacl_host_message_filter_ = NULL; |
- reply_msg_ = NULL; |
+ if (nacl_host_message_filter_.get() == NULL || reply_msg_ == NULL) { |
+ return false; |
} |
+ NaClHostMsg_LaunchNaCl::WriteReplyParams(reply_msg_, result, error_message); |
+ nacl_host_message_filter_->Send(reply_msg_); |
+ nacl_host_message_filter_ = NULL; |
+ reply_msg_ = NULL; |
+ return true; |
} |
void NaClProcessHost::SetDebugStubPort(int port) { |
@@ -824,6 +888,18 @@ bool NaClProcessHost::StartNaClExecution() { |
params.process_type = process_type_; |
bool enable_nacl_debug = enable_debug_stub_ && |
NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(manifest_url_); |
+ |
+ // Because this function may return early on failure, so keep the resources |
+ // in local variables, and pass them to params later. |
+ ScopedPlatformFileForTransit socket_for_sel_ldr; |
+ ScopedPlatformFileForTransit irt_file; |
+#if defined(OS_MACOSX) |
+ base::ScopedFD memory_fd; |
+#endif |
+#if defined(OS_POSIX) |
+ base::ScopedFD debug_stub_server_bound_socket; |
+#endif |
+ |
if (uses_nonsfi_mode_) { |
// Currently, non-SFI mode is supported only on Linux. |
#if defined(OS_LINUX) |
@@ -844,18 +920,20 @@ bool NaClProcessHost::StartNaClExecution() { |
switches::kEnableNaClMojo); |
const ChildProcessData& data = process_->GetData(); |
- if (!ShareHandleToSelLdr(data.handle, |
- socket_for_sel_ldr_.TakePlatformFile(), |
- true, |
- ¶ms.handles)) { |
+ socket_for_sel_ldr.reset( |
+ IPC::TakeFileHandleForProcess(socket_for_sel_ldr_.Pass(), |
+ data.handle)); |
+ if (!socket_for_sel_ldr.is_valid()) { |
return false; |
} |
- const base::File& irt_file = nacl_browser->IrtFile(); |
- CHECK(irt_file.IsValid()); |
+ const base::File& original_irt_file = nacl_browser->IrtFile(); |
+ CHECK(original_irt_file.IsValid()); |
// Send over the IRT file handle. We don't close our own copy! |
- if (!ShareHandleToSelLdr(data.handle, irt_file.GetPlatformFile(), false, |
- ¶ms.handles)) { |
+ irt_file.reset(IPC::GetFileHandleForProcess( |
+ original_irt_file.GetPlatformFile(), data.handle, false)); |
+ if (!irt_file.is_valid()) { |
+ DLOG(ERROR) << "Failed to create irt_file handler for plugin."; |
return false; |
} |
@@ -872,35 +950,46 @@ bool NaClProcessHost::StartNaClExecution() { |
DLOG(ERROR) << "Failed to allocate memory buffer"; |
return false; |
} |
- FileDescriptor memory_fd; |
- memory_fd.fd = dup(memory_buffer.handle().fd); |
- if (memory_fd.fd < 0) { |
+ memory_fd.reset(dup(memory_buffer.handle().fd)); |
+ if (!memory_fd.is_valid()) { |
DLOG(ERROR) << "Failed to dup() a file descriptor"; |
return false; |
} |
- memory_fd.auto_close = true; |
- params.handles.push_back(memory_fd); |
#endif |
#if defined(OS_POSIX) |
if (params.enable_debug_stub) { |
net::SocketDescriptor server_bound_socket = GetDebugStubSocketHandle(); |
if (server_bound_socket != net::kInvalidSocket) { |
- params.debug_stub_server_bound_socket = |
- FileDescriptor(server_bound_socket, true); |
+ debug_stub_server_bound_socket.reset(server_bound_socket); |
} |
} |
#endif |
} |
- if (!crash_info_shmem_.ShareToProcess(process_->GetData().handle, |
- ¶ms.crash_info_shmem_handle)) { |
+ ScopedSharedMemoryHandle crash_info_shmem_handle; |
+ { |
+ base::SharedMemoryHandle raw_handle; |
+ if (crash_info_shmem_.ShareToProcess( |
+ process_->GetData().handle, &raw_handle)) { |
+ crash_info_shmem_handle.reset(raw_handle); |
+ } |
+ } |
+ if (!crash_info_shmem_handle.is_valid()) { |
DLOG(ERROR) << "Failed to ShareToProcess() a shared memory buffer"; |
return false; |
} |
- base::FilePath file_path; |
+ // Hereafter, NaClProcessMsg_Start must be (eventually) sent. |
+ // Delegate the resources to NaClStartParams. |
+ params.crash_info_shmem_handle = crash_info_shmem_handle.release(); |
if (uses_nonsfi_mode_) { |
+ DCHECK(!socket_for_sel_ldr.is_valid()); |
+ DCHECK(!irt_file.is_valid()); |
+#if defined(OS_MACOSX) |
+ DCHECK(!memory_fd.is_valid()); |
+#endif |
+ |
// Don't retrieve the file path when using nonsfi mode; there's no |
// validation caching in that case, so it's unnecessary work, and would |
// expose the file path to the plugin. |
@@ -915,6 +1004,26 @@ bool NaClProcessHost::StartNaClExecution() { |
} |
prefetched_resource_files_info_.clear(); |
} else { |
+ // TODO(yusukes): Handle |prefetched_resource_files_info_| for SFI-NaCl. |
+ DCHECK(prefetched_resource_files_info_.empty()); |
+ |
+ params.handles.push_back(socket_for_sel_ldr.release()); |
+ params.handles.push_back(irt_file.release()); |
+ // Note that on OS_POSIX (including OS_MACOSX), IPC::PlatformFileForTransit |
+ // is the alias of base::FileDescriptor. |
+#if defined(OS_MACOSX) |
+ params.handles.push_back(base::FileDescriptor(memory_fd.release(), true)); |
+#endif |
+#if defined(OS_POSIX) |
+ if (debug_stub_server_bound_socket.is_valid()) { |
+ params.debug_stub_server_bound_socket = |
+ base::FileDescriptor(debug_stub_server_bound_socket.release(), true); |
+ } |
+#endif |
+ } |
+ |
+ if (!uses_nonsfi_mode_) { |
+ base::FilePath file_path; |
if (NaClBrowser::GetInstance()->GetFilePath(nexe_token_.lo, |
nexe_token_.hi, |
&file_path)) { |
@@ -934,8 +1043,6 @@ bool NaClProcessHost::StartNaClExecution() { |
return true; |
} |
} |
- // TODO(yusukes): Handle |prefetched_resource_files_info_| for SFI-NaCl. |
- DCHECK(prefetched_resource_files_info_.empty()); |
} |
params.nexe_file = IPC::TakeFileHandleForProcess(nexe_file_.Pass(), |
@@ -949,11 +1056,8 @@ void NaClProcessHost::StartNaClFileResolved( |
const base::FilePath& file_path, |
base::File checked_nexe_file) { |
if (checked_nexe_file.IsValid()) { |
- // Release the file received from the renderer. This has to be done on a |
- // thread where IO is permitted, though. |
- content::BrowserThread::GetBlockingPool()->PostTask( |
- FROM_HERE, |
- base::Bind(&CloseFile, base::Passed(nexe_file_.Pass()))); |
+ // Release the file received from the renderer. |
+ CloseFile(nexe_file_.Pass()); |
params.nexe_file_path_metadata = file_path; |
params.nexe_file = IPC::TakeFileHandleForProcess( |
checked_nexe_file.Pass(), process_->GetData().handle); |
@@ -967,14 +1071,21 @@ void NaClProcessHost::StartNaClFileResolved( |
// This method is called when NaClProcessHostMsg_PpapiChannelCreated is |
// received. |
void NaClProcessHost::OnPpapiChannelsCreated( |
- const IPC::ChannelHandle& browser_channel_handle, |
- const IPC::ChannelHandle& ppapi_renderer_channel_handle, |
- const IPC::ChannelHandle& trusted_renderer_channel_handle, |
- const IPC::ChannelHandle& manifest_service_channel_handle) { |
+ const IPC::ChannelHandle& raw_browser_channel_handle, |
+ const IPC::ChannelHandle& raw_ppapi_renderer_channel_handle, |
+ const IPC::ChannelHandle& raw_trusted_renderer_channel_handle, |
+ const IPC::ChannelHandle& raw_manifest_service_channel_handle) { |
+ ScopedChannelHandle browser_channel_handle(raw_browser_channel_handle); |
+ ScopedChannelHandle ppapi_renderer_channel_handle( |
+ raw_ppapi_renderer_channel_handle); |
+ ScopedChannelHandle trusted_renderer_channel_handle( |
+ raw_trusted_renderer_channel_handle); |
+ ScopedChannelHandle manifest_service_channel_handle( |
+ raw_manifest_service_channel_handle); |
if (!enable_ppapi_proxy()) { |
- ReplyToRenderer(IPC::ChannelHandle(), |
- trusted_renderer_channel_handle, |
- manifest_service_channel_handle); |
+ ReplyToRenderer(ScopedChannelHandle(), |
+ trusted_renderer_channel_handle.Pass(), |
+ manifest_service_channel_handle.Pass()); |
return; |
} |
@@ -982,7 +1093,7 @@ void NaClProcessHost::OnPpapiChannelsCreated( |
DCHECK_EQ(PROCESS_TYPE_NACL_LOADER, process_->GetData().process_type); |
ipc_proxy_channel_ = |
- IPC::ChannelProxy::Create(browser_channel_handle, |
+ IPC::ChannelProxy::Create(browser_channel_handle.release(), |
IPC::Channel::MODE_CLIENT, |
NULL, |
base::MessageLoopProxy::current().get()); |
@@ -1027,9 +1138,9 @@ void NaClProcessHost::OnPpapiChannelsCreated( |
ipc_proxy_channel_->Send(new PpapiMsg_InitializeNaClDispatcher(args)); |
// Let the renderer know that the IPC channels are established. |
- ReplyToRenderer(ppapi_renderer_channel_handle, |
- trusted_renderer_channel_handle, |
- manifest_service_channel_handle); |
+ ReplyToRenderer(ppapi_renderer_channel_handle.Pass(), |
+ trusted_renderer_channel_handle.Pass(), |
+ manifest_service_channel_handle.Pass()); |
} else { |
// Attempt to open more than 1 browser channel is not supported. |
// Shut down the NaCl process. |