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 |