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 "net/url_request/url_request_context.h" | 18 #include "net/url_request/url_request_context.h" |
19 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
20 #include "ppapi/shared_impl/ppapi_permissions.h" | 20 #include "ppapi/shared_impl/ppapi_permissions.h" |
21 #include "url/gurl.h" | 21 #include "url/gurl.h" |
22 | 22 |
23 namespace nacl { | 23 namespace nacl { |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
| 27 // The maximum number of resource file handles NaClProcessMsg_Start message |
| 28 // can have. |
| 29 // TODO(yusukes): Increase the number. |
| 30 const size_t kMaxPreOpenResourceFiles = 2; |
| 31 |
27 ppapi::PpapiPermissions GetNaClPermissions( | 32 ppapi::PpapiPermissions GetNaClPermissions( |
28 uint32 permission_bits, | 33 uint32 permission_bits, |
29 content::BrowserContext* browser_context, | 34 content::BrowserContext* browser_context, |
30 const GURL& document_url) { | 35 const GURL& document_url) { |
31 // Only allow NaCl plugins to request certain permissions. We don't want | 36 // Only allow NaCl plugins to request certain permissions. We don't want |
32 // a compromised renderer to be able to start a nacl plugin with e.g. Flash | 37 // a compromised renderer to be able to start a nacl plugin with e.g. Flash |
33 // permissions which may expand the surface area of the sandbox. | 38 // permissions which may expand the surface area of the sandbox. |
34 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; | 39 uint32 masked_bits = permission_bits & ppapi::PERMISSION_DEV; |
35 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( | 40 if (content::PluginService::GetInstance()->PpapiDevChannelSupported( |
36 browser_context, document_url)) | 41 browser_context, document_url)) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 120 } |
116 | 121 |
117 void NaClHostMessageFilter::OnLaunchNaCl( | 122 void NaClHostMessageFilter::OnLaunchNaCl( |
118 const nacl::NaClLaunchParams& launch_params, | 123 const nacl::NaClLaunchParams& launch_params, |
119 IPC::Message* reply_msg) { | 124 IPC::Message* reply_msg) { |
120 // If we're running llc or ld for the PNaCl translator, we don't need to look | 125 // If we're running llc or ld for the PNaCl translator, we don't need to look |
121 // up permissions, and we don't have the right browser state to look up some | 126 // up permissions, and we don't have the right browser state to look up some |
122 // of the whitelisting parameters anyway. | 127 // of the whitelisting parameters anyway. |
123 if (launch_params.process_type == kPNaClTranslatorProcessType) { | 128 if (launch_params.process_type == kPNaClTranslatorProcessType) { |
124 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; | 129 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; |
125 LaunchNaClContinuation( | 130 LaunchNaClContinuationOnIOThread( |
126 launch_params, | 131 launch_params, |
127 reply_msg, | 132 reply_msg, |
| 133 std::vector<nacl::NaClResourceFileInfo>(), |
128 ppapi::PpapiPermissions(perms)); | 134 ppapi::PpapiPermissions(perms)); |
129 return; | 135 return; |
130 } | 136 } |
131 content::BrowserThread::PostTaskAndReplyWithResult( | 137 content::BrowserThread::PostTask( |
132 content::BrowserThread::UI, | 138 content::BrowserThread::UI, |
133 FROM_HERE, | 139 FROM_HERE, |
134 base::Bind(&GetPpapiPermissions, | |
135 launch_params.permission_bits, | |
136 render_process_id_, | |
137 launch_params.render_view_id), | |
138 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, | 140 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, |
139 this, | 141 this, |
140 launch_params, | 142 launch_params, |
141 reply_msg)); | 143 reply_msg)); |
142 } | 144 } |
143 | 145 |
144 void NaClHostMessageFilter::LaunchNaClContinuation( | 146 void NaClHostMessageFilter::LaunchNaClContinuation( |
145 const nacl::NaClLaunchParams& launch_params, | 147 const nacl::NaClLaunchParams& launch_params, |
| 148 IPC::Message* reply_msg) { |
| 149 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 150 |
| 151 ppapi::PpapiPermissions permissions = |
| 152 GetPpapiPermissions(launch_params.permission_bits, |
| 153 render_process_id_, |
| 154 launch_params.render_view_id); |
| 155 |
| 156 content::RenderViewHost* rvh = content::RenderViewHost::FromID( |
| 157 render_process_id(), launch_params.render_view_id); |
| 158 if (!rvh) { |
| 159 BadMessageReceived(); // Kill the renderer. |
| 160 return; |
| 161 } |
| 162 |
| 163 nacl::NaClLaunchParams safe_launch_params(launch_params); |
| 164 safe_launch_params.resource_files_to_prefetch.clear(); |
| 165 |
| 166 content::SiteInstance* site_instance = rvh->GetSiteInstance(); |
| 167 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 168 GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
| 169 // Important security check: Do the same check as OpenNaClExecutable() |
| 170 // in nacl_file_host.cc. |
| 171 if (!content::SiteInstance::IsSameWebSite( |
| 172 site_instance->GetBrowserContext(), |
| 173 site_instance->GetSiteURL(), |
| 174 gurl)) { |
| 175 continue; |
| 176 } |
| 177 safe_launch_params.resource_files_to_prefetch.push_back( |
| 178 launch_params.resource_files_to_prefetch[i]); |
| 179 } |
| 180 |
| 181 // Process a list of resource file URLs in |
| 182 // |launch_params.resource_files_to_prefetch|. |
| 183 content::BrowserThread::PostBlockingPoolTask( |
| 184 FROM_HERE, |
| 185 base::Bind(&NaClHostMessageFilter::BatchOpenResourceFiles, |
| 186 this, |
| 187 safe_launch_params, |
| 188 reply_msg, |
| 189 permissions)); |
| 190 } |
| 191 |
| 192 void NaClHostMessageFilter::BatchOpenResourceFiles( |
| 193 const nacl::NaClLaunchParams& launch_params, |
146 IPC::Message* reply_msg, | 194 IPC::Message* reply_msg, |
147 ppapi::PpapiPermissions permissions) { | 195 ppapi::PpapiPermissions permissions) { |
| 196 std::vector<nacl::NaClResourceFileInfo> prefetched_resource_files_info; |
| 197 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 198 nacl::NaClResourceFileInfo prefetched_resource_file; |
| 199 GURL gurl(launch_params.resource_files_to_prefetch[i].second); |
| 200 if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( |
| 201 gurl, |
| 202 true, // use_blocking_api |
| 203 profile_directory_, |
| 204 &prefetched_resource_file.file_path_metadata)) { |
| 205 continue; |
| 206 } |
| 207 base::File file = nacl::OpenNaClReadExecImpl( |
| 208 prefetched_resource_file.file_path_metadata, |
| 209 true /* is_executable */); |
| 210 if (!file.IsValid()) |
| 211 continue; |
| 212 |
| 213 prefetched_resource_file.file = |
| 214 IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()); |
| 215 prefetched_resource_file.file_key = |
| 216 launch_params.resource_files_to_prefetch[i].first; |
| 217 |
| 218 prefetched_resource_files_info.push_back(prefetched_resource_file); |
| 219 if (prefetched_resource_files_info.size() >= kMaxPreOpenResourceFiles) |
| 220 break; |
| 221 } |
| 222 |
| 223 content::BrowserThread::PostTask( |
| 224 content::BrowserThread::IO, |
| 225 FROM_HERE, |
| 226 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, |
| 227 this, |
| 228 launch_params, |
| 229 reply_msg, |
| 230 prefetched_resource_files_info, |
| 231 permissions)); |
| 232 } |
| 233 |
| 234 void NaClHostMessageFilter::LaunchNaClContinuationOnIOThread( |
| 235 const nacl::NaClLaunchParams& launch_params, |
| 236 IPC::Message* reply_msg, |
| 237 const std::vector< |
| 238 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, |
| 239 ppapi::PpapiPermissions permissions) { |
| 240 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 241 |
148 NaClFileToken nexe_token = { | 242 NaClFileToken nexe_token = { |
149 launch_params.nexe_token_lo, // lo | 243 launch_params.nexe_token_lo, // lo |
150 launch_params.nexe_token_hi // hi | 244 launch_params.nexe_token_hi // hi |
151 }; | 245 }; |
152 | 246 |
153 base::PlatformFile nexe_file; | 247 base::PlatformFile nexe_file; |
154 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
155 // Duplicate the nexe file handle from the renderer process into the browser | 249 // Duplicate the nexe file handle from the renderer process into the browser |
156 // process. | 250 // process. |
157 if (!::DuplicateHandle(PeerHandle(), | 251 if (!::DuplicateHandle(PeerHandle(), |
(...skipping 14 matching lines...) Expand all Loading... |
172 nexe_file = | 266 nexe_file = |
173 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); | 267 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); |
174 #else | 268 #else |
175 #error Unsupported platform. | 269 #error Unsupported platform. |
176 #endif | 270 #endif |
177 | 271 |
178 NaClProcessHost* host = new NaClProcessHost( | 272 NaClProcessHost* host = new NaClProcessHost( |
179 GURL(launch_params.manifest_url), | 273 GURL(launch_params.manifest_url), |
180 base::File(nexe_file), | 274 base::File(nexe_file), |
181 nexe_token, | 275 nexe_token, |
| 276 prefetched_resource_files_info, |
182 permissions, | 277 permissions, |
183 launch_params.render_view_id, | 278 launch_params.render_view_id, |
184 launch_params.permission_bits, | 279 launch_params.permission_bits, |
185 launch_params.uses_nonsfi_mode, | 280 launch_params.uses_nonsfi_mode, |
186 off_the_record_, | 281 off_the_record_, |
187 launch_params.process_type, | 282 launch_params.process_type, |
188 profile_directory_); | 283 profile_directory_); |
189 GURL manifest_url(launch_params.manifest_url); | 284 GURL manifest_url(launch_params.manifest_url); |
190 base::FilePath manifest_path; | 285 base::FilePath manifest_path; |
191 // We're calling MapUrlToLocalFilePath with the non-blocking API | 286 // We're calling MapUrlToLocalFilePath with the non-blocking API |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 reply_msg); | 390 reply_msg); |
296 } | 391 } |
297 | 392 |
298 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, | 393 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, |
299 bool* should_debug) { | 394 bool* should_debug) { |
300 *should_debug = | 395 *should_debug = |
301 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); | 396 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); |
302 } | 397 } |
303 | 398 |
304 } // namespace nacl | 399 } // namespace nacl |
OLD | NEW |