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 "chrome/renderer/pepper/ppb_nacl_private_impl.h" | 5 #include "chrome/renderer/pepper/ppb_nacl_private_impl.h" |
6 | 6 |
7 #ifndef DISABLE_NACL | 7 #ifndef DISABLE_NACL |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
13 #include "chrome/common/chrome_switches.h" | 13 #include "chrome/common/chrome_switches.h" |
14 #include "chrome/common/nacl_host_messages.h" | 14 #include "chrome/common/nacl_host_messages.h" |
15 #include "chrome/common/nacl_types.h" | 15 #include "chrome/common/nacl_types.h" |
16 #include "chrome/renderer/chrome_render_process_observer.h" | 16 #include "chrome/renderer/chrome_render_process_observer.h" |
17 #include "chrome/renderer/pepper/pnacl_translation_resource_host.h" | 17 #include "chrome/renderer/pepper/pnacl_translation_resource_host.h" |
18 #include "content/public/common/content_client.h" | 18 #include "content/public/common/content_client.h" |
19 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
20 #include "content/public/common/sandbox_init.h" | 20 #include "content/public/common/sandbox_init.h" |
21 #include "content/public/renderer/renderer_ppapi_host.h" | 21 #include "content/public/renderer/renderer_ppapi_host.h" |
22 #include "content/public/renderer/render_thread.h" | 22 #include "content/public/renderer/render_thread.h" |
23 #include "content/public/renderer/render_view.h" | 23 #include "content/public/renderer/render_view.h" |
24 #include "ppapi/c/pp_bool.h" | 24 #include "ppapi/c/pp_bool.h" |
25 #include "ppapi/c/private/pp_file_handle.h" | 25 #include "ppapi/c/private/pp_file_handle.h" |
26 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" | 26 #include "ppapi/native_client/src/trusted/plugin/nacl_entry_points.h" |
| 27 #include "ppapi/shared_impl/ppapi_permissions.h" |
27 #include "ppapi/shared_impl/ppapi_preferences.h" | 28 #include "ppapi/shared_impl/ppapi_preferences.h" |
28 #include "ppapi/shared_impl/var.h" | 29 #include "ppapi/shared_impl/var.h" |
29 #include "ppapi/thunk/enter.h" | 30 #include "ppapi/thunk/enter.h" |
30 #include "third_party/WebKit/public/web/WebDocument.h" | 31 #include "third_party/WebKit/public/web/WebDocument.h" |
31 #include "third_party/WebKit/public/web/WebElement.h" | 32 #include "third_party/WebKit/public/web/WebElement.h" |
32 #include "third_party/WebKit/public/web/WebFrame.h" | 33 #include "third_party/WebKit/public/web/WebFrame.h" |
33 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 34 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
34 #include "third_party/WebKit/public/web/WebView.h" | 35 #include "third_party/WebKit/public/web/WebView.h" |
35 #include "webkit/plugins/ppapi/host_globals.h" | 36 #include "webkit/plugins/ppapi/host_globals.h" |
36 #include "webkit/plugins/ppapi/plugin_module.h" | |
37 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 37 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> > | 41 base::LazyInstance<scoped_refptr<PnaclTranslationResourceHost> > |
42 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER; | 42 g_pnacl_resource_host = LAZY_INSTANCE_INITIALIZER; |
43 | 43 |
44 static bool InitializePnaclResourceHost() { | 44 static bool InitializePnaclResourceHost() { |
45 if (!g_pnacl_resource_host.Get()) { | 45 if (!g_pnacl_resource_host.Get()) { |
46 content::RenderThread* render_thread = content::RenderThread::Get(); | 46 content::RenderThread* render_thread = content::RenderThread::Get(); |
(...skipping 24 matching lines...) Expand all Loading... |
71 // Check that we are on the main renderer thread. | 71 // Check that we are on the main renderer thread. |
72 DCHECK(content::RenderThread::Get()); | 72 DCHECK(content::RenderThread::Get()); |
73 content::RendererPpapiHost *host = | 73 content::RendererPpapiHost *host = |
74 content::RendererPpapiHost::GetForPPInstance(instance); | 74 content::RendererPpapiHost::GetForPPInstance(instance); |
75 if (!host) | 75 if (!host) |
76 return 0; | 76 return 0; |
77 return host->GetRoutingIDForWidget(instance); | 77 return host->GetRoutingIDForWidget(instance); |
78 } | 78 } |
79 | 79 |
80 // Launch NaCl's sel_ldr process. | 80 // Launch NaCl's sel_ldr process. |
81 PP_NaClResult LaunchSelLdr(PP_Instance instance, | 81 PP_ExternalPluginResult LaunchSelLdr(PP_Instance instance, |
82 const char* alleged_url, | 82 const char* alleged_url, |
83 PP_Bool uses_irt, | 83 PP_Bool uses_irt, |
84 PP_Bool uses_ppapi, | 84 PP_Bool uses_ppapi, |
85 PP_Bool enable_ppapi_dev, | 85 PP_Bool enable_ppapi_dev, |
86 PP_Bool enable_dyncode_syscalls, | 86 PP_Bool enable_dyncode_syscalls, |
87 PP_Bool enable_exception_handling, | 87 PP_Bool enable_exception_handling, |
88 void* imc_handle, | 88 void* imc_handle, |
89 struct PP_Var* error_message) { | 89 struct PP_Var* error_message) { |
90 nacl::FileDescriptor result_socket; | 90 nacl::FileDescriptor result_socket; |
91 IPC::Sender* sender = content::RenderThread::Get(); | 91 IPC::Sender* sender = content::RenderThread::Get(); |
92 DCHECK(sender); | 92 DCHECK(sender); |
93 *error_message = PP_MakeUndefined(); | 93 *error_message = PP_MakeUndefined(); |
94 int routing_id = 0; | 94 int routing_id = 0; |
95 // If the nexe uses ppapi APIs, we need a routing ID. | 95 // If the nexe uses ppapi APIs, we need a routing ID. |
96 // To get the routing ID, we must be on the main thread. | 96 // To get the routing ID, we must be on the main thread. |
97 // Some nexes do not use ppapi and launch from the background thread, | 97 // Some nexes do not use ppapi and launch from the background thread, |
98 // so those nexes can skip finding a routing_id. | 98 // so those nexes can skip finding a routing_id. |
99 if (uses_ppapi) { | 99 if (uses_ppapi) { |
100 routing_id = GetRoutingID(instance); | 100 routing_id = GetRoutingID(instance); |
101 if (!routing_id) | 101 if (!routing_id) |
102 return PP_NACL_FAILED; | 102 return PP_EXTERNAL_PLUGIN_FAILED; |
103 } | 103 } |
104 | 104 |
105 InstanceInfo instance_info; | 105 InstanceInfo instance_info; |
106 instance_info.url = GURL(alleged_url); | 106 instance_info.url = GURL(alleged_url); |
107 | 107 |
108 uint32_t perm_bits = ppapi::PERMISSION_NONE; | 108 uint32_t perm_bits = ppapi::PERMISSION_NONE; |
109 // Conditionally block 'Dev' interfaces. We do this for the NaCl process, so | 109 // Conditionally block 'Dev' interfaces. We do this for the NaCl process, so |
110 // it's clearer to developers when they are using 'Dev' inappropriately. We | 110 // it's clearer to developers when they are using 'Dev' inappropriately. We |
111 // must also check on the trusted side of the proxy. | 111 // must also check on the trusted side of the proxy. |
112 if (enable_ppapi_dev) | 112 if (enable_ppapi_dev) |
113 perm_bits |= ppapi::PERMISSION_DEV; | 113 perm_bits |= ppapi::PERMISSION_DEV; |
114 instance_info.permissions = | 114 instance_info.permissions = |
115 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); | 115 ppapi::PpapiPermissions::GetForCommandLine(perm_bits); |
116 std::string error_message_string; | 116 std::string error_message_string; |
117 nacl::NaClLaunchResult launch_result; | 117 nacl::NaClLaunchResult launch_result; |
118 | 118 |
119 if (!sender->Send(new NaClHostMsg_LaunchNaCl( | 119 if (!sender->Send(new NaClHostMsg_LaunchNaCl( |
120 nacl::NaClLaunchParams(instance_info.url.spec(), | 120 nacl::NaClLaunchParams(instance_info.url.spec(), |
121 routing_id, | 121 routing_id, |
122 perm_bits, | 122 perm_bits, |
123 PP_ToBool(uses_irt), | 123 PP_ToBool(uses_irt), |
124 PP_ToBool(enable_dyncode_syscalls), | 124 PP_ToBool(enable_dyncode_syscalls), |
125 PP_ToBool(enable_exception_handling)), | 125 PP_ToBool(enable_exception_handling)), |
126 &launch_result, | 126 &launch_result, |
127 &error_message_string))) { | 127 &error_message_string))) { |
128 return PP_NACL_FAILED; | 128 return PP_EXTERNAL_PLUGIN_FAILED; |
129 } | 129 } |
130 if (!error_message_string.empty()) { | 130 if (!error_message_string.empty()) { |
131 *error_message = ppapi::StringVar::StringToPPVar(error_message_string); | 131 *error_message = ppapi::StringVar::StringToPPVar(error_message_string); |
132 return PP_NACL_FAILED; | 132 return PP_EXTERNAL_PLUGIN_FAILED; |
133 } | 133 } |
134 result_socket = launch_result.imc_channel_handle; | 134 result_socket = launch_result.imc_channel_handle; |
135 instance_info.channel_handle = launch_result.ipc_channel_handle; | 135 instance_info.channel_handle = launch_result.ipc_channel_handle; |
136 instance_info.plugin_pid = launch_result.plugin_pid; | 136 instance_info.plugin_pid = launch_result.plugin_pid; |
137 instance_info.plugin_child_id = launch_result.plugin_child_id; | 137 instance_info.plugin_child_id = launch_result.plugin_child_id; |
138 // Don't save instance_info if channel handle is invalid. | 138 // Don't save instance_info if channel handle is invalid. |
139 bool invalid_handle = instance_info.channel_handle.name.empty(); | 139 bool invalid_handle = instance_info.channel_handle.name.empty(); |
140 #if defined(OS_POSIX) | 140 #if defined(OS_POSIX) |
141 if (!invalid_handle) | 141 if (!invalid_handle) |
142 invalid_handle = (instance_info.channel_handle.socket.fd == -1); | 142 invalid_handle = (instance_info.channel_handle.socket.fd == -1); |
143 #endif | 143 #endif |
144 if (!invalid_handle) | 144 if (!invalid_handle) |
145 g_instance_info.Get()[instance] = instance_info; | 145 g_instance_info.Get()[instance] = instance_info; |
146 | 146 |
147 *(static_cast<NaClHandle*>(imc_handle)) = | 147 *(static_cast<NaClHandle*>(imc_handle)) = |
148 nacl::ToNativeHandle(result_socket); | 148 nacl::ToNativeHandle(result_socket); |
149 | 149 |
150 return PP_NACL_OK; | 150 return PP_EXTERNAL_PLUGIN_OK; |
151 } | 151 } |
152 | 152 |
153 PP_NaClResult StartPpapiProxy(PP_Instance instance) { | 153 PP_ExternalPluginResult StartPpapiProxy(PP_Instance instance) { |
154 InstanceInfoMap& map = g_instance_info.Get(); | 154 InstanceInfoMap& map = g_instance_info.Get(); |
155 InstanceInfoMap::iterator it = map.find(instance); | 155 InstanceInfoMap::iterator it = map.find(instance); |
156 if (it == map.end()) { | 156 if (it == map.end()) { |
157 DLOG(ERROR) << "Could not find instance ID"; | 157 DLOG(ERROR) << "Could not find instance ID"; |
158 return PP_NACL_FAILED; | 158 return PP_EXTERNAL_PLUGIN_FAILED; |
159 } | 159 } |
160 InstanceInfo instance_info = it->second; | 160 InstanceInfo instance_info = it->second; |
161 map.erase(it); | 161 map.erase(it); |
162 | 162 |
163 webkit::ppapi::PluginInstance* plugin_instance = | 163 webkit::ppapi::PluginInstance* plugin_instance = |
164 content::GetHostGlobals()->GetInstance(instance); | 164 content::GetHostGlobals()->GetInstance(instance); |
165 if (!plugin_instance) { | 165 if (!plugin_instance) { |
166 DLOG(ERROR) << "GetInstance() failed"; | 166 DLOG(ERROR) << "GetInstance() failed"; |
167 return PP_NACL_ERROR_MODULE; | 167 return PP_EXTERNAL_PLUGIN_ERROR_MODULE; |
168 } | 168 } |
169 | 169 |
170 // Create a new module for each instance of the NaCl plugin that is using | 170 return plugin_instance->SwitchToOutOfProcessProxy( |
171 // the IPC based out-of-process proxy. We can't use the existing module, | 171 base::FilePath().AppendASCII(instance_info.url.spec()), |
172 // because it is configured for the in-process NaCl plugin, and we must | 172 instance_info.permissions, |
173 // keep it that way to allow the page to create other instances. | 173 instance_info.channel_handle, |
174 webkit::ppapi::PluginModule* plugin_module = plugin_instance->module(); | 174 instance_info.plugin_pid, |
175 scoped_refptr<webkit::ppapi::PluginModule> nacl_plugin_module( | 175 instance_info.plugin_child_id); |
176 plugin_module->CreateModuleForNaClInstance()); | |
177 | |
178 content::RendererPpapiHost* renderer_ppapi_host = | |
179 content::RendererPpapiHost::CreateExternalPluginModule( | |
180 nacl_plugin_module, | |
181 plugin_instance, | |
182 base::FilePath().AppendASCII(instance_info.url.spec()), | |
183 instance_info.permissions, | |
184 instance_info.channel_handle, | |
185 instance_info.plugin_pid, | |
186 instance_info.plugin_child_id); | |
187 if (!renderer_ppapi_host) { | |
188 DLOG(ERROR) << "CreateExternalPluginModule() failed"; | |
189 return PP_NACL_ERROR_MODULE; | |
190 } | |
191 | |
192 // Finally, switch the instance to the proxy. | |
193 return nacl_plugin_module->InitAsProxiedNaCl(plugin_instance); | |
194 } | 176 } |
195 | 177 |
196 int UrandomFD(void) { | 178 int UrandomFD(void) { |
197 #if defined(OS_POSIX) | 179 #if defined(OS_POSIX) |
198 return base::GetUrandomFD(); | 180 return base::GetUrandomFD(); |
199 #else | 181 #else |
200 return -1; | 182 return -1; |
201 #endif | 183 #endif |
202 } | 184 } |
203 | 185 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 291 |
310 PP_Bool IsOffTheRecord() { | 292 PP_Bool IsOffTheRecord() { |
311 return PP_FromBool(ChromeRenderProcessObserver::is_incognito_process()); | 293 return PP_FromBool(ChromeRenderProcessObserver::is_incognito_process()); |
312 } | 294 } |
313 | 295 |
314 PP_Bool IsPnaclEnabled() { | 296 PP_Bool IsPnaclEnabled() { |
315 return PP_FromBool( | 297 return PP_FromBool( |
316 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePnacl)); | 298 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePnacl)); |
317 } | 299 } |
318 | 300 |
319 PP_NaClResult ReportNaClError(PP_Instance instance, | 301 PP_ExternalPluginResult ReportNaClError(PP_Instance instance, |
320 PP_NaClError error_id) { | 302 PP_NaClError error_id) { |
321 IPC::Sender* sender = content::RenderThread::Get(); | 303 IPC::Sender* sender = content::RenderThread::Get(); |
322 | 304 |
323 if (!sender->Send( | 305 if (!sender->Send( |
324 new NaClHostMsg_NaClErrorStatus( | 306 new NaClHostMsg_NaClErrorStatus( |
325 // TODO(dschuff): does this enum need to be sent as an int, | 307 // TODO(dschuff): does this enum need to be sent as an int, |
326 // or is it safe to include the appropriate headers in | 308 // or is it safe to include the appropriate headers in |
327 // render_messages.h? | 309 // render_messages.h? |
328 GetRoutingID(instance), static_cast<int>(error_id)))) { | 310 GetRoutingID(instance), static_cast<int>(error_id)))) { |
329 return PP_NACL_FAILED; | 311 return PP_EXTERNAL_PLUGIN_FAILED; |
330 } | 312 } |
331 return PP_NACL_OK; | 313 return PP_EXTERNAL_PLUGIN_OK; |
332 } | 314 } |
333 | 315 |
334 PP_FileHandle OpenNaClExecutable(PP_Instance instance, | 316 PP_FileHandle OpenNaClExecutable(PP_Instance instance, |
335 const char* file_url, | 317 const char* file_url, |
336 uint64_t* nonce_lo, | 318 uint64_t* nonce_lo, |
337 uint64_t* nonce_hi) { | 319 uint64_t* nonce_hi) { |
338 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); | 320 IPC::PlatformFileForTransit out_fd = IPC::InvalidPlatformFileForTransit(); |
339 IPC::Sender* sender = content::RenderThread::Get(); | 321 IPC::Sender* sender = content::RenderThread::Get(); |
340 DCHECK(sender); | 322 DCHECK(sender); |
341 *nonce_lo = 0; | 323 *nonce_lo = 0; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 &OpenNaClExecutable | 357 &OpenNaClExecutable |
376 }; | 358 }; |
377 | 359 |
378 } // namespace | 360 } // namespace |
379 | 361 |
380 const PPB_NaCl_Private* PPB_NaCl_Private_Impl::GetInterface() { | 362 const PPB_NaCl_Private* PPB_NaCl_Private_Impl::GetInterface() { |
381 return &nacl_interface; | 363 return &nacl_interface; |
382 } | 364 } |
383 | 365 |
384 #endif // DISABLE_NACL | 366 #endif // DISABLE_NACL |
OLD | NEW |