OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_host_message_filter.h" | 5 #include "components/nacl/browser/nacl_host_message_filter.h" |
6 | 6 |
7 #include "base/sys_info.h" | 7 #include "base/sys_info.h" |
8 #include "components/nacl/browser/nacl_browser.h" | 8 #include "components/nacl/browser/nacl_browser.h" |
9 #include "components/nacl/browser/nacl_file_host.h" | 9 #include "components/nacl/browser/nacl_file_host.h" |
10 #include "components/nacl/browser/nacl_process_host.h" | 10 #include "components/nacl/browser/nacl_process_host.h" |
11 #include "components/nacl/browser/pnacl_host.h" | 11 #include "components/nacl/browser/pnacl_host.h" |
12 #include "components/nacl/common/nacl_host_messages.h" | 12 #include "components/nacl/common/nacl_host_messages.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "content/public/browser/plugin_service.h" | 14 #include "content/public/browser/plugin_service.h" |
15 #include "content/public/browser/render_process_host.h" | 15 #include "content/public/browser/render_process_host.h" |
16 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
17 #include "ipc/ipc_platform_file.h" | 17 #include "ipc/ipc_platform_file.h" |
18 #include "native_client/src/public/nacl_file_info.h" | 18 #include "native_client/src/public/nacl_file_info.h" |
19 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
20 #include "net/url_request/url_request_context_getter.h" | 20 #include "net/url_request/url_request_context_getter.h" |
21 #include "ppapi/shared_impl/ppapi_permissions.h" | 21 #include "ppapi/shared_impl/ppapi_permissions.h" |
22 #include "url/gurl.h" | 22 #include "url/gurl.h" |
23 | 23 |
24 namespace nacl { | 24 namespace nacl { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 // The maximum number of resource file handles NaClProcessMsg_Start message | |
29 // can have. | |
30 // TODO(yusukes): Increase the number. | |
31 const size_t kMaxPreOpenResourceFiles = 2; | |
32 | |
28 ppapi::PpapiPermissions GetNaClPermissions( | 33 ppapi::PpapiPermissions GetNaClPermissions( |
29 uint32 permission_bits, | 34 uint32 permission_bits, |
30 content::BrowserContext* browser_context, | 35 content::BrowserContext* browser_context, |
31 const GURL& document_url) { | 36 const GURL& document_url) { |
32 // Only allow NaCl plugins to request certain permissions. We don't want | 37 // Only allow NaCl plugins to request certain permissions. We don't want |
33 // a compromised renderer to be able to start a nacl plugin with e.g. Flash | 38 // a compromised renderer to be able to start a nacl plugin with e.g. Flash |
34 // permissions which may expand the surface area of the sandbox. | 39 // permissions which may expand the surface area of the sandbox. |
35 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; | 40 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; |
36 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( | 41 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( |
37 browser_context, document_url)) | 42 browser_context, document_url)) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 return handled; | 116 return handled; |
112 } | 117 } |
113 | 118 |
114 net::HostResolver* NaClHostMessageFilter::GetHostResolver() { | 119 net::HostResolver* NaClHostMessageFilter::GetHostResolver() { |
115 return request_context_->GetURLRequestContext()->host_resolver(); | 120 return request_context_->GetURLRequestContext()->host_resolver(); |
116 } | 121 } |
117 | 122 |
118 void NaClHostMessageFilter::OnLaunchNaCl( | 123 void NaClHostMessageFilter::OnLaunchNaCl( |
119 const nacl::NaClLaunchParams& launch_params, | 124 const nacl::NaClLaunchParams& launch_params, |
120 IPC::Message* reply_msg) { | 125 IPC::Message* reply_msg) { |
126 const std::vector<nacl::NaClResourceFileInfo> empty; | |
121 // If we're running llc or ld for the PNaCl translator, we don't need to look | 127 // If we're running llc or ld for the PNaCl translator, we don't need to look |
122 // up permissions, and we don't have the right browser state to look up some | 128 // up permissions, and we don't have the right browser state to look up some |
123 // of the whitelisting parameters anyway. | 129 // of the whitelisting parameters anyway. |
124 if (launch_params.process_type == kPNaClTranslatorProcessType) { | 130 if (launch_params.process_type == kPNaClTranslatorProcessType) { |
125 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; | 131 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; |
126 LaunchNaClContinuation( | 132 LaunchNaClContinuation( |
127 launch_params, | 133 launch_params, |
128 reply_msg, | 134 reply_msg, |
135 empty, | |
129 ppapi::PpapiPermissions(perms)); | 136 ppapi::PpapiPermissions(perms)); |
130 return; | 137 return; |
131 } | 138 } |
132 content::BrowserThread::PostTaskAndReplyWithResult( | 139 content::BrowserThread::PostTaskAndReplyWithResult( |
133 content::BrowserThread::UI, | 140 content::BrowserThread::UI, |
134 FROM_HERE, | 141 FROM_HERE, |
135 base::Bind(&GetPpapiPermissions, | 142 base::Bind(&GetPpapiPermissions, |
136 launch_params.permission_bits, | 143 launch_params.permission_bits, |
137 render_process_id_, | 144 render_process_id_, |
138 launch_params.render_view_id), | 145 launch_params.render_view_id), |
139 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, | 146 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, |
140 this, | 147 this, |
141 launch_params, | 148 launch_params, |
142 reply_msg)); | 149 reply_msg, |
150 empty)); | |
151 } | |
152 | |
153 void NaClHostMessageFilter::BatchOpenResourceFiles( | |
154 const nacl::NaClLaunchParams& launch_params, | |
155 IPC::Message* reply_msg, | |
156 ppapi::PpapiPermissions permissions) { | |
157 content::RenderViewHost* rvh = content::RenderViewHost::FromID( | |
Mark Seaborn
2015/02/25 20:01:23
You're doing things in this PostBlockingPoolTask()
Yusuke Sato
2015/03/01 06:59:37
No, it's not valid. RVH::FromID has to be called i
| |
158 render_process_id(), launch_params.render_view_id); | |
159 if (!rvh) { | |
160 BadMessageReceived(); // Kill the renderer. | |
161 return; | |
162 } | |
163 | |
164 std::vector<nacl::NaClResourceFileInfo> prefetched_resource_files_info; | |
165 // TODO(yusukes): Support SFI mode. | |
166 if (launch_params.uses_nonsfi_mode) { | |
Yusuke Sato
2015/03/01 06:59:37
removed the IF
| |
167 content::SiteInstance* site_instance = rvh->GetSiteInstance(); | |
168 for (size_t i = 0; | |
169 i < launch_params.prefetched_resource_files.size(); ++i) { | |
170 nacl::NaClResourceFileInfo prefetched_resource_file; | |
171 GURL gurl(launch_params.prefetched_resource_files[i].first); | |
172 // IMPORTANT SECURITY CHECK: Do the same check as OpenNaClExecutable() | |
173 // in nacl_file_host.cc. | |
174 if (!content::SiteInstance::IsSameWebSite( | |
175 site_instance->GetBrowserContext(), | |
176 site_instance->GetSiteURL(), | |
177 gurl)) { | |
178 continue; | |
179 } | |
180 if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( | |
181 gurl, | |
182 true, // blocking | |
Mark Seaborn
2015/02/25 20:01:23
Nit: "use_blocking_api" (for consistency)
Yusuke Sato
2015/03/01 06:59:37
Done.
| |
183 profile_directory_, | |
184 &prefetched_resource_file.file_path)) { | |
185 continue; | |
186 } | |
187 base::File file = nacl::OpenNaClReadExecImpl( | |
188 prefetched_resource_file.file_path, true /* is_executable */); | |
189 if (!file.IsValid()) | |
190 continue; | |
191 | |
192 prefetched_resource_file.file = | |
193 IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()); | |
194 prefetched_resource_file.file_key = | |
195 launch_params.prefetched_resource_files[i].second; | |
196 | |
197 prefetched_resource_files_info.push_back(prefetched_resource_file); | |
198 if (prefetched_resource_files_info.size() > kMaxPreOpenResourceFiles) | |
199 break; | |
200 } | |
201 } | |
202 | |
203 nacl::NaClLaunchParams new_launch_params(launch_params); | |
204 new_launch_params.prefetched_resource_files.clear(); | |
205 | |
206 if (!content::BrowserThread::PostTask( | |
207 content::BrowserThread::IO, | |
208 FROM_HERE, | |
209 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, | |
210 this, | |
211 new_launch_params, | |
212 reply_msg, | |
213 prefetched_resource_files_info, | |
214 permissions))) { | |
215 for (size_t i = 0; i < prefetched_resource_files_info.size(); ++i) { | |
Mark Seaborn
2015/02/25 20:01:23
This error handling seems unnecessary. When would
Yusuke Sato
2015/03/01 06:59:37
Removed. Looks like PostTask always returns true a
| |
216 // The base::File destructor will close the file. | |
217 base::File file(IPC::PlatformFileForTransitToFile( | |
218 prefetched_resource_files_info[i].file)); | |
219 } | |
220 NaClHostMsg_LaunchNaCl::WriteReplyParams( | |
221 reply_msg, | |
222 NaClLaunchResult(), | |
223 std::string("Failed to open resource files")); | |
224 Send(reply_msg); | |
225 } | |
143 } | 226 } |
144 | 227 |
145 void NaClHostMessageFilter::LaunchNaClContinuation( | 228 void NaClHostMessageFilter::LaunchNaClContinuation( |
146 const nacl::NaClLaunchParams& launch_params, | 229 const nacl::NaClLaunchParams& launch_params, |
147 IPC::Message* reply_msg, | 230 IPC::Message* reply_msg, |
231 const std::vector< | |
232 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, | |
148 ppapi::PpapiPermissions permissions) { | 233 ppapi::PpapiPermissions permissions) { |
234 if (!launch_params.prefetched_resource_files.empty()) { | |
235 // Process a list of resource file URLs in | |
236 // |launch_params.prefetched_resource_files|. | |
237 // BatchOpenResourceFiles calls this function again with an empty | |
Mark Seaborn
2015/02/25 20:01:23
It seems kind of hacky for a function to call itse
Yusuke Sato
2015/03/01 06:59:37
Done.
| |
238 // |launch_params.prefetched_resource_files|. | |
239 DCHECK(prefetched_resource_files_info.empty()); | |
240 if (!content::BrowserThread::PostBlockingPoolTask( | |
241 FROM_HERE, | |
242 base::Bind(&NaClHostMessageFilter::BatchOpenResourceFiles, | |
243 this, | |
244 launch_params, | |
245 reply_msg, | |
246 permissions))) { | |
247 NaClHostMsg_LaunchNaCl::WriteReplyParams( | |
248 reply_msg, | |
249 NaClLaunchResult(), | |
250 std::string("Failed to open resource files")); | |
251 Send(reply_msg); | |
252 } | |
253 return; | |
254 } | |
255 | |
149 NaClFileToken nexe_token = { | 256 NaClFileToken nexe_token = { |
150 launch_params.nexe_token_lo, // lo | 257 launch_params.nexe_token_lo, // lo |
151 launch_params.nexe_token_hi // hi | 258 launch_params.nexe_token_hi // hi |
152 }; | 259 }; |
153 | 260 |
154 base::PlatformFile nexe_file; | 261 base::PlatformFile nexe_file; |
155 #if defined(OS_WIN) | 262 #if defined(OS_WIN) |
156 // Duplicate the nexe file handle from the renderer process into the browser | 263 // Duplicate the nexe file handle from the renderer process into the browser |
157 // process. | 264 // process. |
158 if (!::DuplicateHandle(PeerHandle(), | 265 if (!::DuplicateHandle(PeerHandle(), |
(...skipping 14 matching lines...) Expand all Loading... | |
173 nexe_file = | 280 nexe_file = |
174 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); | 281 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); |
175 #else | 282 #else |
176 #error Unsupported platform. | 283 #error Unsupported platform. |
177 #endif | 284 #endif |
178 | 285 |
179 NaClProcessHost* host = new NaClProcessHost( | 286 NaClProcessHost* host = new NaClProcessHost( |
180 GURL(launch_params.manifest_url), | 287 GURL(launch_params.manifest_url), |
181 base::File(nexe_file), | 288 base::File(nexe_file), |
182 nexe_token, | 289 nexe_token, |
290 prefetched_resource_files_info, | |
183 permissions, | 291 permissions, |
184 launch_params.render_view_id, | 292 launch_params.render_view_id, |
185 launch_params.permission_bits, | 293 launch_params.permission_bits, |
186 launch_params.uses_nonsfi_mode, | 294 launch_params.uses_nonsfi_mode, |
187 off_the_record_, | 295 off_the_record_, |
188 launch_params.process_type, | 296 launch_params.process_type, |
189 profile_directory_); | 297 profile_directory_); |
190 GURL manifest_url(launch_params.manifest_url); | 298 GURL manifest_url(launch_params.manifest_url); |
191 base::FilePath manifest_path; | 299 base::FilePath manifest_path; |
192 // We're calling MapUrlToLocalFilePath with the non-blocking API | 300 // We're calling MapUrlToLocalFilePath with the non-blocking API |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
296 reply_msg); | 404 reply_msg); |
297 } | 405 } |
298 | 406 |
299 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, | 407 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, |
300 bool* should_debug) { | 408 bool* should_debug) { |
301 *should_debug = | 409 *should_debug = |
302 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); | 410 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); |
303 } | 411 } |
304 | 412 |
305 } // namespace nacl | 413 } // namespace nacl |
OLD | NEW |