Chromium Code Reviews| 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 "content/browser/child_process_security_policy_impl.h" | 5 #include "content/browser/child_process_security_policy_impl.h" | 
| 6 | 6 | 
| 7 #include <utility> | |
| 8 | |
| 7 #include "base/command_line.h" | 9 #include "base/command_line.h" | 
| 8 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" | 
| 9 #include "base/logging.h" | 11 #include "base/logging.h" | 
| 10 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" | 
| 11 #include "base/stl_util.h" | 13 #include "base/stl_util.h" | 
| 12 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" | 
| 13 #include "content/browser/plugin_process_host.h" | 15 #include "content/browser/plugin_process_host.h" | 
| 14 #include "content/browser/site_instance_impl.h" | 16 #include "content/browser/site_instance_impl.h" | 
| 15 #include "content/common/site_isolation_policy.h" | 17 #include "content/common/site_isolation_policy.h" | 
| 16 #include "content/public/browser/child_process_data.h" | 18 #include "content/public/browser/child_process_data.h" | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 } | 87 } | 
| 86 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.PerChildFilePermissions", | 88 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.PerChildFilePermissions", | 
| 87 file_permissions_.size()); | 89 file_permissions_.size()); | 
| 88 } | 90 } | 
| 89 | 91 | 
| 90 // Grant permission to request URLs with the specified scheme. | 92 // Grant permission to request URLs with the specified scheme. | 
| 91 void GrantScheme(const std::string& scheme) { | 93 void GrantScheme(const std::string& scheme) { | 
| 92 scheme_policy_[scheme] = true; | 94 scheme_policy_[scheme] = true; | 
| 93 } | 95 } | 
| 94 | 96 | 
| 97 // Grant permission to request URLs with both the specified scheme and host. | |
| 98 void GrantSchemeHost(const std::string& scheme, const std::string& host) { | |
| 99 scheme_host_policy_[std::make_pair(scheme, host)] = true; | |
| 100 } | |
| 101 | |
| 95 // Revoke permission to request URLs with the specified scheme. | 102 // Revoke permission to request URLs with the specified scheme. | 
| 96 void RevokeScheme(const std::string& scheme) { | 103 void RevokeScheme(const std::string& scheme) { | 
| 97 scheme_policy_[scheme] = false; | 104 scheme_policy_[scheme] = false; | 
| 98 } | 105 } | 
| 99 | 106 | 
| 107 // Revoke permission to request URLs with both the specified scheme and host. | |
| 108 void RevokeSchemeHost(const std::string& scheme, const std::string& host) { | |
| 
 
Charlie Reis
2015/09/22 17:38:15
We shouldn't introduce new methods until they're n
 
paulmeyer
2015/09/22 22:13:57
I was thinking the same thing, though RevokeScheme
 
Charlie Reis
2015/09/23 00:07:15
Not in this CL.  We can probably remove it as dead
 
paulmeyer
2015/09/23 17:03:53
Acknowledged.
 
 | |
| 109 scheme_host_policy_[std::make_pair(scheme, host)] = false; | |
| 110 } | |
| 111 | |
| 100 // Grant certain permissions to a file. | 112 // Grant certain permissions to a file. | 
| 101 void GrantPermissionsForFile(const base::FilePath& file, int permissions) { | 113 void GrantPermissionsForFile(const base::FilePath& file, int permissions) { | 
| 102 base::FilePath stripped = file.StripTrailingSeparators(); | 114 base::FilePath stripped = file.StripTrailingSeparators(); | 
| 103 file_permissions_[stripped] |= permissions; | 115 file_permissions_[stripped] |= permissions; | 
| 104 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.FilePermissionPathLength", | 116 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.FilePermissionPathLength", | 
| 105 stripped.value().size()); | 117 stripped.value().size()); | 
| 106 } | 118 } | 
| 107 | 119 | 
| 108 // Grant navigation to a file but not the file:// scheme in general. | 120 // Grant navigation to a file but not the file:// scheme in general. | 
| 109 void GrantRequestOfSpecificFile(const base::FilePath &file) { | 121 void GrantRequestOfSpecificFile(const base::FilePath &file) { | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 void RevokeReadRawCookies() { | 173 void RevokeReadRawCookies() { | 
| 162 can_read_raw_cookies_ = false; | 174 can_read_raw_cookies_ = false; | 
| 163 } | 175 } | 
| 164 | 176 | 
| 165 void GrantPermissionForMidiSysEx() { | 177 void GrantPermissionForMidiSysEx() { | 
| 166 can_send_midi_sysex_ = true; | 178 can_send_midi_sysex_ = true; | 
| 167 } | 179 } | 
| 168 | 180 | 
| 169 // Determine whether permission has been granted to commit |url|. | 181 // Determine whether permission has been granted to commit |url|. | 
| 170 bool CanCommitURL(const GURL& url) { | 182 bool CanCommitURL(const GURL& url) { | 
| 171 // Having permission to a scheme implies permssion to all of its URLs. | 183 // Check for permission for specific scheme and host. | 
| 172 SchemeMap::const_iterator judgment(scheme_policy_.find(url.scheme())); | 184 SchemeHostMap::const_iterator scheme_host_judgment( | 
| 173 if (judgment != scheme_policy_.end()) | 185 scheme_host_policy_.find(std::make_pair(url.scheme(), url.host()))); | 
| 174 return judgment->second; | 186 if (scheme_host_judgment != scheme_host_policy_.end()) | 
| 187 return scheme_host_judgment->second; | |
| 188 | |
| 189 // Otherwise, having permission to a scheme implies permission to all of its | |
| 190 // URLs. | |
| 191 SchemeMap::const_iterator scheme_judgment( | |
| 192 scheme_policy_.find(url.scheme())); | |
| 193 if (scheme_judgment != scheme_policy_.end()) | |
| 194 return scheme_judgment->second; | |
| 175 | 195 | 
| 176 // file:// URLs are more granular. The child may have been given | 196 // file:// URLs are more granular. The child may have been given | 
| 177 // permission to a specific file but not the file:// scheme in general. | 197 // permission to a specific file but not the file:// scheme in general. | 
| 178 if (url.SchemeIs(url::kFileScheme)) { | 198 if (url.SchemeIs(url::kFileScheme)) { | 
| 179 base::FilePath path; | 199 base::FilePath path; | 
| 180 if (net::FileURLToFilePath(url, &path)) | 200 if (net::FileURLToFilePath(url, &path)) | 
| 181 return ContainsKey(request_file_set_, path); | 201 return ContainsKey(request_file_set_, path); | 
| 182 } | 202 } | 
| 183 | 203 | 
| 184 return false; // Unmentioned schemes are disallowed. | 204 return false; // Unmentioned schemes are disallowed. | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 bool can_read_raw_cookies() const { | 255 bool can_read_raw_cookies() const { | 
| 236 return can_read_raw_cookies_; | 256 return can_read_raw_cookies_; | 
| 237 } | 257 } | 
| 238 | 258 | 
| 239 bool can_send_midi_sysex() const { | 259 bool can_send_midi_sysex() const { | 
| 240 return can_send_midi_sysex_; | 260 return can_send_midi_sysex_; | 
| 241 } | 261 } | 
| 242 | 262 | 
| 243 private: | 263 private: | 
| 244 typedef std::map<std::string, bool> SchemeMap; | 264 typedef std::map<std::string, bool> SchemeMap; | 
| 265 typedef std::map<std::pair<std::string, std::string>, bool> SchemeHostMap; | |
| 245 | 266 | 
| 246 typedef int FilePermissionFlags; // bit-set of base::File::Flags | 267 typedef int FilePermissionFlags; // bit-set of base::File::Flags | 
| 247 typedef std::map<base::FilePath, FilePermissionFlags> FileMap; | 268 typedef std::map<base::FilePath, FilePermissionFlags> FileMap; | 
| 248 typedef std::map<std::string, FilePermissionFlags> FileSystemMap; | 269 typedef std::map<std::string, FilePermissionFlags> FileSystemMap; | 
| 249 typedef std::set<base::FilePath> FileSet; | 270 typedef std::set<base::FilePath> FileSet; | 
| 250 | 271 | 
| 251 // Maps URL schemes to whether permission has been granted or revoked: | 272 // Maps URL schemes to whether permission has been granted or revoked: | 
| 252 // |true| means the scheme has been granted. | 273 // |true| means the scheme has been granted. | 
| 253 // |false| means the scheme has been revoked. | 274 // |false| means the scheme has been revoked. | 
| 254 // If a scheme is not present in the map, then it has never been granted | 275 // If a scheme is not present in the map, then it has never been granted | 
| 255 // or revoked. | 276 // or revoked. | 
| 256 SchemeMap scheme_policy_; | 277 SchemeMap scheme_policy_; | 
| 257 | 278 | 
| 279 // Maps URL (scheme, host) pairs to whether permission has been granted or | |
| 280 // revoked: | |
| 281 // |true| means the (scheme, host) pair has been granted. | |
| 282 // |false| means the (scheme, host) pair has been revoked. | |
| 283 // If a (scheme, host) pair is not present in the map, then it has never been | |
| 284 // granted or revoked. | |
| 
 
Charlie Reis
2015/09/22 17:38:15
This seems overly complicated if we don't have any
 
paulmeyer
2015/09/22 22:13:57
Okay, I'll use a set of origins.
 
 | |
| 285 // | |
| 286 // For schemes that are present in both |scheme_policy_| and | |
| 287 // |scheme_host_policy_|, the permission set for specific hosts within a | |
| 288 // scheme in |scheme_host_polcy_| will be respected first, followed by the | |
| 
 
Charlie Reis
2015/09/22 17:38:15
This also seems overly complicated.  If we aren't
 
paulmeyer
2015/09/22 22:13:57
Done.
 
 | |
| 289 // general permission for the scheme in |scheme_policy_| for all other hosts | |
| 290 // within that scheme. | |
| 291 SchemeHostMap scheme_host_policy_; | |
| 292 | |
| 258 // The set of files the child process is permited to upload to the web. | 293 // The set of files the child process is permited to upload to the web. | 
| 259 FileMap file_permissions_; | 294 FileMap file_permissions_; | 
| 260 | 295 | 
| 261 // The set of files the child process is permitted to load. | 296 // The set of files the child process is permitted to load. | 
| 262 FileSet request_file_set_; | 297 FileSet request_file_set_; | 
| 263 | 298 | 
| 264 int enabled_bindings_; | 299 int enabled_bindings_; | 
| 265 | 300 | 
| 266 bool can_read_raw_cookies_; | 301 bool can_read_raw_cookies_; | 
| 267 | 302 | 
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 const std::string& scheme) { | 542 const std::string& scheme) { | 
| 508 base::AutoLock lock(lock_); | 543 base::AutoLock lock(lock_); | 
| 509 | 544 | 
| 510 SecurityStateMap::iterator state = security_state_.find(child_id); | 545 SecurityStateMap::iterator state = security_state_.find(child_id); | 
| 511 if (state == security_state_.end()) | 546 if (state == security_state_.end()) | 
| 512 return; | 547 return; | 
| 513 | 548 | 
| 514 state->second->GrantScheme(scheme); | 549 state->second->GrantScheme(scheme); | 
| 515 } | 550 } | 
| 516 | 551 | 
| 552 void ChildProcessSecurityPolicyImpl::GrantSchemeHost(int child_id, | |
| 553 const std::string& scheme, | |
| 554 const std::string& host) { | |
| 555 base::AutoLock lock(lock_); | |
| 556 | |
| 557 SecurityStateMap::iterator state = security_state_.find(child_id); | |
| 558 if (state == security_state_.end()) | |
| 559 return; | |
| 560 | |
| 561 state->second->GrantSchemeHost(scheme, host); | |
| 562 } | |
| 563 | |
| 517 void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id) { | 564 void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id) { | 
| 518 base::AutoLock lock(lock_); | 565 base::AutoLock lock(lock_); | 
| 519 | 566 | 
| 520 SecurityStateMap::iterator state = security_state_.find(child_id); | 567 SecurityStateMap::iterator state = security_state_.find(child_id); | 
| 521 if (state == security_state_.end()) | 568 if (state == security_state_.end()) | 
| 522 return; | 569 return; | 
| 523 | 570 | 
| 524 state->second->GrantBindings(BINDINGS_POLICY_WEB_UI); | 571 state->second->GrantBindings(BINDINGS_POLICY_WEB_UI); | 
| 525 | 572 | 
| 526 // Web UI bindings need the ability to request chrome: URLs. | 573 // Web UI bindings need the ability to request chrome: URLs. | 
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 838 base::AutoLock lock(lock_); | 885 base::AutoLock lock(lock_); | 
| 839 | 886 | 
| 840 SecurityStateMap::iterator state = security_state_.find(child_id); | 887 SecurityStateMap::iterator state = security_state_.find(child_id); | 
| 841 if (state == security_state_.end()) | 888 if (state == security_state_.end()) | 
| 842 return false; | 889 return false; | 
| 843 | 890 | 
| 844 return state->second->can_send_midi_sysex(); | 891 return state->second->can_send_midi_sysex(); | 
| 845 } | 892 } | 
| 846 | 893 | 
| 847 } // namespace content | 894 } // namespace content | 
| OLD | NEW |