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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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) { |
121 // If we're running llc or ld for the PNaCl translator, we don't need to look | 126 // 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 | 127 // up permissions, and we don't have the right browser state to look up some |
123 // of the whitelisting parameters anyway. | 128 // of the whitelisting parameters anyway. |
124 if (launch_params.process_type == kPNaClTranslatorProcessType) { | 129 if (launch_params.process_type == kPNaClTranslatorProcessType) { |
125 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; | 130 uint32 perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; |
126 LaunchNaClContinuation( | 131 LaunchNaClContinuationOnIOThread( |
127 launch_params, | 132 launch_params, |
128 reply_msg, | 133 reply_msg, |
| 134 std::vector<nacl::NaClResourceFileInfo>(), |
129 ppapi::PpapiPermissions(perms)); | 135 ppapi::PpapiPermissions(perms)); |
130 return; | 136 return; |
131 } | 137 } |
132 content::BrowserThread::PostTaskAndReplyWithResult( | 138 content::BrowserThread::PostTask( |
133 content::BrowserThread::UI, | 139 content::BrowserThread::UI, |
134 FROM_HERE, | 140 FROM_HERE, |
135 base::Bind(&GetPpapiPermissions, | |
136 launch_params.permission_bits, | |
137 render_process_id_, | |
138 launch_params.render_view_id), | |
139 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, | 141 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuation, |
140 this, | 142 this, |
141 launch_params, | 143 launch_params, |
142 reply_msg)); | 144 reply_msg)); |
143 } | 145 } |
144 | 146 |
145 void NaClHostMessageFilter::LaunchNaClContinuation( | 147 void NaClHostMessageFilter::LaunchNaClContinuation( |
146 const nacl::NaClLaunchParams& launch_params, | 148 const nacl::NaClLaunchParams& launch_params, |
| 149 IPC::Message* reply_msg) { |
| 150 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 151 |
| 152 ppapi::PpapiPermissions permissions = |
| 153 GetPpapiPermissions(launch_params.permission_bits, |
| 154 render_process_id_, |
| 155 launch_params.render_view_id); |
| 156 |
| 157 content::RenderViewHost* rvh = content::RenderViewHost::FromID( |
| 158 render_process_id(), launch_params.render_view_id); |
| 159 if (!rvh) { |
| 160 BadMessageReceived(); // Kill the renderer. |
| 161 return; |
| 162 } |
| 163 |
| 164 nacl::NaClLaunchParams safe_launch_params(launch_params); |
| 165 safe_launch_params.resource_files_to_prefetch.clear(); |
| 166 |
| 167 content::SiteInstance* site_instance = rvh->GetSiteInstance(); |
| 168 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 169 GURL gurl(launch_params.resource_files_to_prefetch[i].first); |
| 170 // IMPORTANT SECURITY CHECK: Do the same check as OpenNaClExecutable() |
| 171 // in nacl_file_host.cc. |
| 172 if (!content::SiteInstance::IsSameWebSite( |
| 173 site_instance->GetBrowserContext(), |
| 174 site_instance->GetSiteURL(), |
| 175 gurl)) { |
| 176 continue; |
| 177 } |
| 178 safe_launch_params.resource_files_to_prefetch.push_back( |
| 179 launch_params.resource_files_to_prefetch[i]); |
| 180 } |
| 181 |
| 182 // Process a list of resource file URLs in |
| 183 // |launch_params.resource_files_to_prefetch|. |
| 184 content::BrowserThread::PostBlockingPoolTask( |
| 185 FROM_HERE, |
| 186 base::Bind(&NaClHostMessageFilter::BatchOpenResourceFiles, |
| 187 this, |
| 188 safe_launch_params, |
| 189 reply_msg, |
| 190 permissions)); |
| 191 } |
| 192 |
| 193 void NaClHostMessageFilter::BatchOpenResourceFiles( |
| 194 const nacl::NaClLaunchParams& launch_params, |
147 IPC::Message* reply_msg, | 195 IPC::Message* reply_msg, |
148 ppapi::PpapiPermissions permissions) { | 196 ppapi::PpapiPermissions permissions) { |
| 197 std::vector<nacl::NaClResourceFileInfo> prefetched_resource_files_info; |
| 198 for (size_t i = 0; i < launch_params.resource_files_to_prefetch.size(); ++i) { |
| 199 nacl::NaClResourceFileInfo prefetched_resource_file; |
| 200 GURL gurl(launch_params.resource_files_to_prefetch[i].first); |
| 201 if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( |
| 202 gurl, |
| 203 true, // use_blocking_api |
| 204 profile_directory_, |
| 205 &prefetched_resource_file.file_path_metadata)) { |
| 206 continue; |
| 207 } |
| 208 base::File file = nacl::OpenNaClReadExecImpl( |
| 209 prefetched_resource_file.file_path_metadata, |
| 210 true /* is_executable */); |
| 211 if (!file.IsValid()) |
| 212 continue; |
| 213 |
| 214 prefetched_resource_file.file = |
| 215 IPC::TakeFileHandleForProcess(file.Pass(), PeerHandle()); |
| 216 prefetched_resource_file.file_key = |
| 217 launch_params.resource_files_to_prefetch[i].second; |
| 218 |
| 219 prefetched_resource_files_info.push_back(prefetched_resource_file); |
| 220 if (prefetched_resource_files_info.size() >= kMaxPreOpenResourceFiles) |
| 221 break; |
| 222 } |
| 223 |
| 224 content::BrowserThread::PostTask( |
| 225 content::BrowserThread::IO, |
| 226 FROM_HERE, |
| 227 base::Bind(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, |
| 228 this, |
| 229 launch_params, |
| 230 reply_msg, |
| 231 prefetched_resource_files_info, |
| 232 permissions)); |
| 233 } |
| 234 |
| 235 void NaClHostMessageFilter::LaunchNaClContinuationOnIOThread( |
| 236 const nacl::NaClLaunchParams& launch_params, |
| 237 IPC::Message* reply_msg, |
| 238 const std::vector< |
| 239 nacl::NaClResourceFileInfo>& prefetched_resource_files_info, |
| 240 ppapi::PpapiPermissions permissions) { |
| 241 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 242 |
149 NaClFileToken nexe_token = { | 243 NaClFileToken nexe_token = { |
150 launch_params.nexe_token_lo, // lo | 244 launch_params.nexe_token_lo, // lo |
151 launch_params.nexe_token_hi // hi | 245 launch_params.nexe_token_hi // hi |
152 }; | 246 }; |
153 | 247 |
154 base::PlatformFile nexe_file; | 248 base::PlatformFile nexe_file; |
155 #if defined(OS_WIN) | 249 #if defined(OS_WIN) |
156 // Duplicate the nexe file handle from the renderer process into the browser | 250 // Duplicate the nexe file handle from the renderer process into the browser |
157 // process. | 251 // process. |
158 if (!::DuplicateHandle(PeerHandle(), | 252 if (!::DuplicateHandle(PeerHandle(), |
(...skipping 14 matching lines...) Expand all Loading... |
173 nexe_file = | 267 nexe_file = |
174 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); | 268 IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); |
175 #else | 269 #else |
176 #error Unsupported platform. | 270 #error Unsupported platform. |
177 #endif | 271 #endif |
178 | 272 |
179 NaClProcessHost* host = new NaClProcessHost( | 273 NaClProcessHost* host = new NaClProcessHost( |
180 GURL(launch_params.manifest_url), | 274 GURL(launch_params.manifest_url), |
181 base::File(nexe_file), | 275 base::File(nexe_file), |
182 nexe_token, | 276 nexe_token, |
| 277 prefetched_resource_files_info, |
183 permissions, | 278 permissions, |
184 launch_params.render_view_id, | 279 launch_params.render_view_id, |
185 launch_params.permission_bits, | 280 launch_params.permission_bits, |
186 launch_params.uses_nonsfi_mode, | 281 launch_params.uses_nonsfi_mode, |
187 off_the_record_, | 282 off_the_record_, |
188 launch_params.process_type, | 283 launch_params.process_type, |
189 profile_directory_); | 284 profile_directory_); |
190 GURL manifest_url(launch_params.manifest_url); | 285 GURL manifest_url(launch_params.manifest_url); |
191 base::FilePath manifest_path; | 286 base::FilePath manifest_path; |
192 // We're calling MapUrlToLocalFilePath with the non-blocking API | 287 // 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); | 391 reply_msg); |
297 } | 392 } |
298 | 393 |
299 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, | 394 void NaClHostMessageFilter::OnNaClDebugEnabledForURL(const GURL& nmf_url, |
300 bool* should_debug) { | 395 bool* should_debug) { |
301 *should_debug = | 396 *should_debug = |
302 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); | 397 nacl::NaClBrowser::GetDelegate()->URLMatchesDebugPatterns(nmf_url); |
303 } | 398 } |
304 | 399 |
305 } // namespace nacl | 400 } // namespace nacl |
OLD | NEW |