1 // 2 // Copyright (C) 2014 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "update_engine/update_manager/chromeos_policy.h" 18 19 #include <algorithm> 20 #include <set> 21 #include <string> 22 #include <vector> 23 24 #include <base/logging.h> 25 #include <base/strings/string_util.h> 26 #include <base/time/time.h> 27 28 #include "update_engine/common/error_code.h" 29 #include "update_engine/common/error_code_utils.h" 30 #include "update_engine/common/utils.h" 31 #include "update_engine/update_manager/device_policy_provider.h" 32 #include "update_engine/update_manager/enough_slots_ab_updates_policy_impl.h" 33 #include "update_engine/update_manager/enterprise_device_policy_impl.h" 34 #include "update_engine/update_manager/interactive_update_policy_impl.h" 35 #include "update_engine/update_manager/official_build_check_policy_impl.h" 36 #include "update_engine/update_manager/out_of_box_experience_policy_impl.h" 37 #include "update_engine/update_manager/policy_utils.h" 38 #include "update_engine/update_manager/shill_provider.h" 39 #include "update_engine/update_manager/update_time_restrictions_policy_impl.h" 40 41 using base::Time; 42 using base::TimeDelta; 43 using chromeos_update_engine::ConnectionTethering; 44 using chromeos_update_engine::ConnectionType; 45 using chromeos_update_engine::ErrorCode; 46 using chromeos_update_engine::InstallPlan; 47 using std::get; 48 using std::min; 49 using std::set; 50 using std::string; 51 using std::vector; 52 53 namespace { 54 55 // Examines |err_code| and decides whether the URL index needs to be advanced, 56 // the error count for the URL incremented, or none of the above. In the first 57 // case, returns true; in the second case, increments |*url_num_error_p| and 58 // returns false; otherwise just returns false. 59 // 60 // TODO(garnold) Adapted from PayloadState::UpdateFailed() (to be retired). 61 bool HandleErrorCode(ErrorCode err_code, int* url_num_error_p) { 62 err_code = chromeos_update_engine::utils::GetBaseErrorCode(err_code); 63 switch (err_code) { 64 // Errors which are good indicators of a problem with a particular URL or 65 // the protocol used in the URL or entities in the communication channel 66 // (e.g. proxies). We should try the next available URL in the next update 67 // check to quickly recover from these errors. 68 case ErrorCode::kPayloadHashMismatchError: 69 case ErrorCode::kPayloadSizeMismatchError: 70 case ErrorCode::kDownloadPayloadVerificationError: 71 case ErrorCode::kDownloadPayloadPubKeyVerificationError: 72 case ErrorCode::kSignedDeltaPayloadExpectedError: 73 case ErrorCode::kDownloadInvalidMetadataMagicString: 74 case ErrorCode::kDownloadSignatureMissingInManifest: 75 case ErrorCode::kDownloadManifestParseError: 76 case ErrorCode::kDownloadMetadataSignatureError: 77 case ErrorCode::kDownloadMetadataSignatureVerificationError: 78 case ErrorCode::kDownloadMetadataSignatureMismatch: 79 case ErrorCode::kDownloadOperationHashVerificationError: 80 case ErrorCode::kDownloadOperationExecutionError: 81 case ErrorCode::kDownloadOperationHashMismatch: 82 case ErrorCode::kDownloadInvalidMetadataSize: 83 case ErrorCode::kDownloadInvalidMetadataSignature: 84 case ErrorCode::kDownloadOperationHashMissingError: 85 case ErrorCode::kDownloadMetadataSignatureMissingError: 86 case ErrorCode::kPayloadMismatchedType: 87 case ErrorCode::kUnsupportedMajorPayloadVersion: 88 case ErrorCode::kUnsupportedMinorPayloadVersion: 89 case ErrorCode::kPayloadTimestampError: 90 case ErrorCode::kVerityCalculationError: 91 LOG(INFO) << "Advancing download URL due to error " 92 << chromeos_update_engine::utils::ErrorCodeToString(err_code) 93 << " (" << static_cast<int>(err_code) << ")"; 94 return true; 95 96 // Errors which seem to be just transient network/communication related 97 // failures and do not indicate any inherent problem with the URL itself. 98 // So, we should keep the current URL but just increment the 99 // failure count to give it more chances. This way, while we maximize our 100 // chances of downloading from the URLs that appear earlier in the response 101 // (because download from a local server URL that appears earlier in a 102 // response is preferable than downloading from the next URL which could be 103 // an Internet URL and thus could be more expensive). 104 case ErrorCode::kError: 105 case ErrorCode::kDownloadTransferError: 106 case ErrorCode::kDownloadWriteError: 107 case ErrorCode::kDownloadStateInitializationError: 108 case ErrorCode::kOmahaErrorInHTTPResponse: // Aggregate for HTTP errors. 109 LOG(INFO) << "Incrementing URL failure count due to error " 110 << chromeos_update_engine::utils::ErrorCodeToString(err_code) 111 << " (" << static_cast<int>(err_code) << ")"; 112 *url_num_error_p += 1; 113 return false; 114 115 // Errors which are not specific to a URL and hence shouldn't result in 116 // the URL being penalized. This can happen in two cases: 117 // 1. We haven't started downloading anything: These errors don't cost us 118 // anything in terms of actual payload bytes, so we should just do the 119 // regular retries at the next update check. 120 // 2. We have successfully downloaded the payload: In this case, the 121 // payload attempt number would have been incremented and would take care 122 // of the back-off at the next update check. 123 // In either case, there's no need to update URL index or failure count. 124 case ErrorCode::kOmahaRequestError: 125 case ErrorCode::kOmahaResponseHandlerError: 126 case ErrorCode::kPostinstallRunnerError: 127 case ErrorCode::kFilesystemCopierError: 128 case ErrorCode::kInstallDeviceOpenError: 129 case ErrorCode::kKernelDeviceOpenError: 130 case ErrorCode::kDownloadNewPartitionInfoError: 131 case ErrorCode::kNewRootfsVerificationError: 132 case ErrorCode::kNewKernelVerificationError: 133 case ErrorCode::kPostinstallBootedFromFirmwareB: 134 case ErrorCode::kPostinstallFirmwareRONotUpdatable: 135 case ErrorCode::kOmahaRequestEmptyResponseError: 136 case ErrorCode::kOmahaRequestXMLParseError: 137 case ErrorCode::kOmahaResponseInvalid: 138 case ErrorCode::kOmahaUpdateIgnoredPerPolicy: 139 case ErrorCode::kOmahaUpdateDeferredPerPolicy: 140 case ErrorCode::kNonCriticalUpdateInOOBE: 141 case ErrorCode::kOmahaUpdateDeferredForBackoff: 142 case ErrorCode::kPostinstallPowerwashError: 143 case ErrorCode::kUpdateCanceledByChannelChange: 144 case ErrorCode::kOmahaRequestXMLHasEntityDecl: 145 case ErrorCode::kFilesystemVerifierError: 146 case ErrorCode::kUserCanceled: 147 case ErrorCode::kOmahaUpdateIgnoredOverCellular: 148 case ErrorCode::kUpdatedButNotActive: 149 case ErrorCode::kNoUpdate: 150 case ErrorCode::kRollbackNotPossible: 151 case ErrorCode::kFirstActiveOmahaPingSentPersistenceError: 152 case ErrorCode::kInternalLibCurlError: 153 case ErrorCode::kUnresolvedHostError: 154 case ErrorCode::kUnresolvedHostRecovered: 155 case ErrorCode::kNotEnoughSpace: 156 case ErrorCode::kDeviceCorrupted: 157 LOG(INFO) << "Not changing URL index or failure count due to error " 158 << chromeos_update_engine::utils::ErrorCodeToString(err_code) 159 << " (" << static_cast<int>(err_code) << ")"; 160 return false; 161 162 case ErrorCode::kSuccess: // success code 163 case ErrorCode::kUmaReportedMax: // not an error code 164 case ErrorCode::kOmahaRequestHTTPResponseBase: // aggregated already 165 case ErrorCode::kDevModeFlag: // not an error code 166 case ErrorCode::kResumedFlag: // not an error code 167 case ErrorCode::kTestImageFlag: // not an error code 168 case ErrorCode::kTestOmahaUrlFlag: // not an error code 169 case ErrorCode::kSpecialFlags: // not an error code 170 // These shouldn't happen. Enumerating these explicitly here so that we 171 // can let the compiler warn about new error codes that are added to 172 // action_processor.h but not added here. 173 LOG(WARNING) << "Unexpected error " 174 << chromeos_update_engine::utils::ErrorCodeToString(err_code) 175 << " (" << static_cast<int>(err_code) << ")"; 176 // Note: Not adding a default here so as to let the compiler warn us of 177 // any new enums that were added in the .h but not listed in this switch. 178 } 179 return false; 180 } 181 182 // Checks whether |url| can be used under given download restrictions. 183 bool IsUrlUsable(const string& url, bool http_allowed) { 184 return http_allowed || 185 !base::StartsWith( 186 url, "http://", base::CompareCase::INSENSITIVE_ASCII); 187 } 188 189 } // namespace 190 191 namespace chromeos_update_manager { 192 193 const NextUpdateCheckPolicyConstants 194 ChromeOSPolicy::kNextUpdateCheckPolicyConstants = { 195 .timeout_initial_interval = 7 * 60, 196 .timeout_periodic_interval = 45 * 60, 197 .timeout_max_backoff_interval = 4 * 60 * 60, 198 .timeout_regular_fuzz = 10 * 60, 199 .attempt_backoff_max_interval_in_days = 16, 200 .attempt_backoff_fuzz_in_hours = 12, 201 }; 202 203 const int ChromeOSPolicy::kMaxP2PAttempts = 10; 204 const int ChromeOSPolicy::kMaxP2PAttemptsPeriodInSeconds = 5 * 24 * 60 * 60; 205 206 EvalStatus ChromeOSPolicy::UpdateCheckAllowed(EvaluationContext* ec, 207 State* state, 208 string* error, 209 UpdateCheckParams* result) const { 210 // Set the default return values. 211 result->updates_enabled = true; 212 result->target_channel.clear(); 213 result->target_version_prefix.clear(); 214 result->rollback_allowed = false; 215 result->rollback_allowed_milestones = -1; 216 result->interactive = false; 217 218 EnoughSlotsAbUpdatesPolicyImpl enough_slots_ab_updates_policy; 219 EnterpriseDevicePolicyImpl enterprise_device_policy; 220 OnlyUpdateOfficialBuildsPolicyImpl only_update_official_builds_policy; 221 InteractiveUpdatePolicyImpl interactive_update_policy; 222 OobePolicyImpl oobe_policy; 223 NextUpdateCheckTimePolicyImpl next_update_check_time_policy( 224 kNextUpdateCheckPolicyConstants); 225 226 vector<Policy const*> policies_to_consult = { 227 // Do not perform any updates if there are not enough slots to do A/B 228 // updates. 229 &enough_slots_ab_updates_policy, 230 231 // Check to see if Enterprise-managed (has DevicePolicy) and/or 232 // Kiosk-mode. If so, then defer to those settings. 233 &enterprise_device_policy, 234 235 // Check to see if an interactive update was requested. 236 &interactive_update_policy, 237 238 // Unofficial builds should not perform periodic update checks. 239 &only_update_official_builds_policy, 240 241 // If OOBE is enabled, wait until it is completed. 242 &oobe_policy, 243 244 // Ensure that periodic update checks are timed properly. 245 &next_update_check_time_policy, 246 }; 247 248 // Now that the list of policy implementations, and the order to consult them, 249 // has been setup, consult the policies. If none of the policies make a 250 // definitive decisions about whether or not to check for updates, then allow 251 // the update check to happen. 252 EvalStatus status = ConsultPolicies(policies_to_consult, 253 &Policy::UpdateCheckAllowed, 254 ec, 255 state, 256 error, 257 result); 258 if (EvalStatus::kContinue != status) { 259 return status; 260 } else { 261 // It is time to check for an update. 262 LOG(INFO) << "Allowing update check."; 263 return EvalStatus::kSucceeded; 264 } 265 } 266 267 EvalStatus ChromeOSPolicy::UpdateCanBeApplied(EvaluationContext* ec, 268 State* state, 269 std::string* error, 270 ErrorCode* result, 271 InstallPlan* install_plan) const { 272 UpdateTimeRestrictionsPolicyImpl update_time_restrictions_policy; 273 InteractiveUpdatePolicyImpl interactive_update_policy; 274 275 vector<Policy const*> policies_to_consult = { 276 // Check to see if an interactive update has been requested. 277 &interactive_update_policy, 278 279 // Do not apply or download an update if we are inside one of the 280 // restricted times. 281 &update_time_restrictions_policy, 282 }; 283 284 EvalStatus status = ConsultPolicies(policies_to_consult, 285 &Policy::UpdateCanBeApplied, 286 ec, 287 state, 288 error, 289 result, 290 install_plan); 291 if (EvalStatus::kContinue != status) { 292 return status; 293 } else { 294 // The update can proceed. 295 LOG(INFO) << "Allowing update to be applied."; 296 *result = ErrorCode::kSuccess; 297 return EvalStatus::kSucceeded; 298 } 299 } 300 301 EvalStatus ChromeOSPolicy::UpdateCanStart( 302 EvaluationContext* ec, 303 State* state, 304 string* error, 305 UpdateDownloadParams* result, 306 const UpdateState update_state) const { 307 // Set the default return values. Note that we set persisted values (backoff, 308 // scattering) to the same values presented in the update state. The reason is 309 // that preemptive returns, such as the case where an update check is due, 310 // should not clear off the said values; rather, it is the deliberate 311 // inference of new values that should cause them to be reset. 312 result->update_can_start = false; 313 result->cannot_start_reason = UpdateCannotStartReason::kUndefined; 314 result->download_url_idx = -1; 315 result->download_url_allowed = true; 316 result->download_url_num_errors = 0; 317 result->p2p_downloading_allowed = false; 318 result->p2p_sharing_allowed = false; 319 result->do_increment_failures = false; 320 result->backoff_expiry = update_state.backoff_expiry; 321 result->scatter_wait_period = update_state.scatter_wait_period; 322 result->scatter_check_threshold = update_state.scatter_check_threshold; 323 324 // Make sure that we're not due for an update check. 325 UpdateCheckParams check_result; 326 EvalStatus check_status = UpdateCheckAllowed(ec, state, error, &check_result); 327 if (check_status == EvalStatus::kFailed) 328 return EvalStatus::kFailed; 329 bool is_check_due = (check_status == EvalStatus::kSucceeded && 330 check_result.updates_enabled == true); 331 332 // Check whether backoff applies, and if not then which URL can be used for 333 // downloading. These require scanning the download error log, and so they are 334 // done together. 335 UpdateBackoffAndDownloadUrlResult backoff_url_result; 336 EvalStatus backoff_url_status = UpdateBackoffAndDownloadUrl( 337 ec, state, error, &backoff_url_result, update_state); 338 if (backoff_url_status == EvalStatus::kFailed) 339 return EvalStatus::kFailed; 340 result->download_url_idx = backoff_url_result.url_idx; 341 result->download_url_num_errors = backoff_url_result.url_num_errors; 342 result->do_increment_failures = backoff_url_result.do_increment_failures; 343 result->backoff_expiry = backoff_url_result.backoff_expiry; 344 bool is_backoff_active = 345 (backoff_url_status == EvalStatus::kAskMeAgainLater) || 346 !backoff_url_result.backoff_expiry.is_null(); 347 348 DevicePolicyProvider* const dp_provider = state->device_policy_provider(); 349 bool is_scattering_active = false; 350 EvalStatus scattering_status = EvalStatus::kSucceeded; 351 352 const bool* device_policy_is_loaded_p = 353 ec->GetValue(dp_provider->var_device_policy_is_loaded()); 354 if (device_policy_is_loaded_p && *device_policy_is_loaded_p) { 355 // Check whether scattering applies to this update attempt. We should not be 356 // scattering if this is an interactive update check, or if OOBE is enabled 357 // but not completed. 358 // 359 // Note: current code further suppresses scattering if a "deadline" 360 // attribute is found in the Omaha response. However, it appears that the 361 // presence of this attribute is merely indicative of an OOBE update, during 362 // which we suppress scattering anyway. 363 bool is_scattering_applicable = false; 364 result->scatter_wait_period = kZeroInterval; 365 result->scatter_check_threshold = 0; 366 if (!update_state.interactive) { 367 const bool* is_oobe_enabled_p = 368 ec->GetValue(state->config_provider()->var_is_oobe_enabled()); 369 if (is_oobe_enabled_p && !(*is_oobe_enabled_p)) { 370 is_scattering_applicable = true; 371 } else { 372 const bool* is_oobe_complete_p = 373 ec->GetValue(state->system_provider()->var_is_oobe_complete()); 374 is_scattering_applicable = (is_oobe_complete_p && *is_oobe_complete_p); 375 } 376 } 377 378 // Compute scattering values. 379 if (is_scattering_applicable) { 380 UpdateScatteringResult scatter_result; 381 scattering_status = 382 UpdateScattering(ec, state, error, &scatter_result, update_state); 383 if (scattering_status == EvalStatus::kFailed) { 384 return EvalStatus::kFailed; 385 } else { 386 result->scatter_wait_period = scatter_result.wait_period; 387 result->scatter_check_threshold = scatter_result.check_threshold; 388 if (scattering_status == EvalStatus::kAskMeAgainLater || 389 scatter_result.is_scattering) 390 is_scattering_active = true; 391 } 392 } 393 } 394 395 // Find out whether P2P is globally enabled. 396 bool p2p_enabled; 397 EvalStatus p2p_enabled_status = P2PEnabled(ec, state, error, &p2p_enabled); 398 if (p2p_enabled_status != EvalStatus::kSucceeded) 399 return EvalStatus::kFailed; 400 401 // Is P2P is enabled, consider allowing it for downloading and/or sharing. 402 if (p2p_enabled) { 403 // Sharing via P2P is allowed if not disabled by Omaha. 404 if (update_state.p2p_sharing_disabled) { 405 LOG(INFO) << "Blocked P2P sharing because it is disabled by Omaha."; 406 } else { 407 result->p2p_sharing_allowed = true; 408 } 409 410 // Downloading via P2P is allowed if not disabled by Omaha, an update is not 411 // interactive, and other limits haven't been reached. 412 if (update_state.p2p_downloading_disabled) { 413 LOG(INFO) << "Blocked P2P downloading because it is disabled by Omaha."; 414 } else if (update_state.interactive) { 415 LOG(INFO) << "Blocked P2P downloading because update is interactive."; 416 } else if (update_state.p2p_num_attempts >= kMaxP2PAttempts) { 417 LOG(INFO) << "Blocked P2P downloading as it was attempted too many " 418 "times."; 419 } else if (!update_state.p2p_first_attempted.is_null() && 420 ec->IsWallclockTimeGreaterThan( 421 update_state.p2p_first_attempted + 422 TimeDelta::FromSeconds(kMaxP2PAttemptsPeriodInSeconds))) { 423 LOG(INFO) << "Blocked P2P downloading as its usage timespan exceeds " 424 "limit."; 425 } else { 426 // P2P download is allowed; if backoff or scattering are active, be sure 427 // to suppress them, yet prevent any download URL from being used. 428 result->p2p_downloading_allowed = true; 429 if (is_backoff_active || is_scattering_active) { 430 is_backoff_active = is_scattering_active = false; 431 result->download_url_allowed = false; 432 } 433 } 434 } 435 436 // Check for various deterrents. 437 if (is_check_due) { 438 result->cannot_start_reason = UpdateCannotStartReason::kCheckDue; 439 return EvalStatus::kSucceeded; 440 } 441 if (is_backoff_active) { 442 result->cannot_start_reason = UpdateCannotStartReason::kBackoff; 443 return backoff_url_status; 444 } 445 if (is_scattering_active) { 446 result->cannot_start_reason = UpdateCannotStartReason::kScattering; 447 return scattering_status; 448 } 449 if (result->download_url_idx < 0 && !result->p2p_downloading_allowed) { 450 result->cannot_start_reason = UpdateCannotStartReason::kCannotDownload; 451 return EvalStatus::kSucceeded; 452 } 453 454 // Update is good to go. 455 result->update_can_start = true; 456 return EvalStatus::kSucceeded; 457 } 458 459 // TODO(garnold) Logic in this method is based on 460 // ConnectionManager::IsUpdateAllowedOver(); be sure to deprecate the latter. 461 // 462 // TODO(garnold) The current logic generally treats the list of allowed 463 // connections coming from the device policy as a whitelist, meaning that it 464 // can only be used for enabling connections, but not disable them. Further, 465 // certain connection types (like Bluetooth) cannot be enabled even by policy. 466 // In effect, the only thing that device policy can change is to enable 467 // updates over a cellular network (disabled by default). We may want to 468 // revisit this semantics, allowing greater flexibility in defining specific 469 // permissions over all types of networks. 470 EvalStatus ChromeOSPolicy::UpdateDownloadAllowed(EvaluationContext* ec, 471 State* state, 472 string* error, 473 bool* result) const { 474 // Get the current connection type. 475 ShillProvider* const shill_provider = state->shill_provider(); 476 const ConnectionType* conn_type_p = 477 ec->GetValue(shill_provider->var_conn_type()); 478 POLICY_CHECK_VALUE_AND_FAIL(conn_type_p, error); 479 ConnectionType conn_type = *conn_type_p; 480 481 // If we're tethering, treat it as a cellular connection. 482 if (conn_type != ConnectionType::kCellular) { 483 const ConnectionTethering* conn_tethering_p = 484 ec->GetValue(shill_provider->var_conn_tethering()); 485 POLICY_CHECK_VALUE_AND_FAIL(conn_tethering_p, error); 486 if (*conn_tethering_p == ConnectionTethering::kConfirmed) 487 conn_type = ConnectionType::kCellular; 488 } 489 490 // By default, we allow updates for all connection types, with exceptions as 491 // noted below. This also determines whether a device policy can override the 492 // default. 493 *result = true; 494 bool device_policy_can_override = false; 495 switch (conn_type) { 496 case ConnectionType::kBluetooth: 497 *result = false; 498 break; 499 500 case ConnectionType::kCellular: 501 *result = false; 502 device_policy_can_override = true; 503 break; 504 505 case ConnectionType::kUnknown: 506 if (error) 507 *error = "Unknown connection type"; 508 return EvalStatus::kFailed; 509 510 default: 511 break; // Nothing to do. 512 } 513 514 // If update is allowed, we're done. 515 if (*result) 516 return EvalStatus::kSucceeded; 517 518 // Check whether the device policy specifically allows this connection. 519 if (device_policy_can_override) { 520 DevicePolicyProvider* const dp_provider = state->device_policy_provider(); 521 const bool* device_policy_is_loaded_p = 522 ec->GetValue(dp_provider->var_device_policy_is_loaded()); 523 if (device_policy_is_loaded_p && *device_policy_is_loaded_p) { 524 const set<ConnectionType>* allowed_conn_types_p = 525 ec->GetValue(dp_provider->var_allowed_connection_types_for_update()); 526 if (allowed_conn_types_p) { 527 if (allowed_conn_types_p->count(conn_type)) { 528 *result = true; 529 return EvalStatus::kSucceeded; 530 } 531 } else if (conn_type == ConnectionType::kCellular) { 532 // Local user settings can allow updates over cellular iff a policy was 533 // loaded but no allowed connections were specified in it. 534 const bool* update_over_cellular_allowed_p = 535 ec->GetValue(state->updater_provider()->var_cellular_enabled()); 536 if (update_over_cellular_allowed_p && *update_over_cellular_allowed_p) 537 *result = true; 538 } 539 } 540 } 541 542 return (*result ? EvalStatus::kSucceeded : EvalStatus::kAskMeAgainLater); 543 } 544 545 EvalStatus ChromeOSPolicy::P2PEnabled(EvaluationContext* ec, 546 State* state, 547 string* error, 548 bool* result) const { 549 bool enabled = false; 550 551 // Determine whether use of P2P is allowed by policy. Even if P2P is not 552 // explicitly allowed, we allow it if the device is enterprise enrolled (that 553 // is, missing or empty owner string). 554 DevicePolicyProvider* const dp_provider = state->device_policy_provider(); 555 const bool* device_policy_is_loaded_p = 556 ec->GetValue(dp_provider->var_device_policy_is_loaded()); 557 if (device_policy_is_loaded_p && *device_policy_is_loaded_p) { 558 const bool* policy_au_p2p_enabled_p = 559 ec->GetValue(dp_provider->var_au_p2p_enabled()); 560 if (policy_au_p2p_enabled_p) { 561 enabled = *policy_au_p2p_enabled_p; 562 } else { 563 const string* policy_owner_p = ec->GetValue(dp_provider->var_owner()); 564 if (!policy_owner_p || policy_owner_p->empty()) 565 enabled = true; 566 } 567 } 568 569 // Enable P2P, if so mandated by the updater configuration. This is additive 570 // to whether or not P2P is enabled by device policy. 571 if (!enabled) { 572 const bool* updater_p2p_enabled_p = 573 ec->GetValue(state->updater_provider()->var_p2p_enabled()); 574 enabled = updater_p2p_enabled_p && *updater_p2p_enabled_p; 575 } 576 577 *result = enabled; 578 return EvalStatus::kSucceeded; 579 } 580 581 EvalStatus ChromeOSPolicy::P2PEnabledChanged(EvaluationContext* ec, 582 State* state, 583 string* error, 584 bool* result, 585 bool prev_result) const { 586 EvalStatus status = P2PEnabled(ec, state, error, result); 587 if (status == EvalStatus::kSucceeded && *result == prev_result) 588 return EvalStatus::kAskMeAgainLater; 589 return status; 590 } 591 592 EvalStatus ChromeOSPolicy::UpdateBackoffAndDownloadUrl( 593 EvaluationContext* ec, 594 State* state, 595 string* error, 596 UpdateBackoffAndDownloadUrlResult* result, 597 const UpdateState& update_state) const { 598 // Sanity checks. 599 DCHECK_GE(update_state.download_errors_max, 0); 600 601 // Set default result values. 602 result->do_increment_failures = false; 603 result->backoff_expiry = update_state.backoff_expiry; 604 result->url_idx = -1; 605 result->url_num_errors = 0; 606 607 const bool* is_official_build_p = 608 ec->GetValue(state->system_provider()->var_is_official_build()); 609 bool is_official_build = (is_official_build_p ? *is_official_build_p : true); 610 611 // Check whether backoff is enabled. 612 bool may_backoff = false; 613 if (update_state.is_backoff_disabled) { 614 LOG(INFO) << "Backoff disabled by Omaha."; 615 } else if (update_state.interactive) { 616 LOG(INFO) << "No backoff for interactive updates."; 617 } else if (update_state.is_delta_payload) { 618 LOG(INFO) << "No backoff for delta payloads."; 619 } else if (!is_official_build) { 620 LOG(INFO) << "No backoff for unofficial builds."; 621 } else { 622 may_backoff = true; 623 } 624 625 // If previous backoff still in effect, block. 626 if (may_backoff && !update_state.backoff_expiry.is_null() && 627 !ec->IsWallclockTimeGreaterThan(update_state.backoff_expiry)) { 628 LOG(INFO) << "Previous backoff has not expired, waiting."; 629 return EvalStatus::kAskMeAgainLater; 630 } 631 632 // Determine whether HTTP downloads are forbidden by policy. This only 633 // applies to official system builds; otherwise, HTTP is always enabled. 634 bool http_allowed = true; 635 if (is_official_build) { 636 DevicePolicyProvider* const dp_provider = state->device_policy_provider(); 637 const bool* device_policy_is_loaded_p = 638 ec->GetValue(dp_provider->var_device_policy_is_loaded()); 639 if (device_policy_is_loaded_p && *device_policy_is_loaded_p) { 640 const bool* policy_http_downloads_enabled_p = 641 ec->GetValue(dp_provider->var_http_downloads_enabled()); 642 http_allowed = (!policy_http_downloads_enabled_p || 643 *policy_http_downloads_enabled_p); 644 } 645 } 646 647 int url_idx = update_state.last_download_url_idx; 648 if (url_idx < 0) 649 url_idx = -1; 650 bool do_advance_url = false; 651 bool is_failure_occurred = false; 652 Time err_time; 653 654 // Scan the relevant part of the download error log, tracking which URLs are 655 // being used, and accounting the number of errors for each URL. Note that 656 // this process may not traverse all errors provided, as it may decide to bail 657 // out midway depending on the particular errors exhibited, the number of 658 // failures allowed, etc. When this ends, |url_idx| will point to the last URL 659 // used (-1 if starting fresh), |do_advance_url| will determine whether the 660 // URL needs to be advanced, and |err_time| the point in time when the last 661 // reported error occurred. Additionally, if the error log indicates that an 662 // update attempt has failed (abnormal), then |is_failure_occurred| will be 663 // set to true. 664 const int num_urls = update_state.download_urls.size(); 665 int prev_url_idx = -1; 666 int url_num_errors = update_state.last_download_url_num_errors; 667 Time prev_err_time; 668 bool is_first = true; 669 for (const auto& err_tuple : update_state.download_errors) { 670 // Do some sanity checks. 671 int used_url_idx = get<0>(err_tuple); 672 if (is_first && url_idx >= 0 && used_url_idx != url_idx) { 673 LOG(WARNING) << "First URL in error log (" << used_url_idx 674 << ") not as expected (" << url_idx << ")"; 675 } 676 is_first = false; 677 url_idx = used_url_idx; 678 if (url_idx < 0 || url_idx >= num_urls) { 679 LOG(ERROR) << "Download error log contains an invalid URL index (" 680 << url_idx << ")"; 681 return EvalStatus::kFailed; 682 } 683 err_time = get<2>(err_tuple); 684 if (!(prev_err_time.is_null() || err_time >= prev_err_time)) { 685 // TODO(garnold) Monotonicity cannot really be assumed when dealing with 686 // wallclock-based timestamps. However, we're making a simplifying 687 // assumption so as to keep the policy implementation straightforward, for 688 // now. In general, we should convert all timestamp handling in the 689 // UpdateManager to use monotonic time (instead of wallclock), including 690 // the computation of various expiration times (backoff, scattering, etc). 691 // The client will do whatever conversions necessary when 692 // persisting/retrieving these values across reboots. See chromium:408794. 693 LOG(ERROR) << "Download error timestamps not monotonically increasing."; 694 return EvalStatus::kFailed; 695 } 696 prev_err_time = err_time; 697 698 // Ignore errors that happened before the last known failed attempt. 699 if (!update_state.failures_last_updated.is_null() && 700 err_time <= update_state.failures_last_updated) 701 continue; 702 703 if (prev_url_idx >= 0) { 704 if (url_idx < prev_url_idx) { 705 LOG(ERROR) << "The URLs in the download error log have wrapped around (" 706 << prev_url_idx << "->" << url_idx 707 << "). This should not have happened and means that there's " 708 "a bug. To be conservative, we record a failed attempt " 709 "(invalidating the rest of the error log) and resume " 710 "download from the first usable URL."; 711 url_idx = -1; 712 is_failure_occurred = true; 713 break; 714 } 715 716 if (url_idx > prev_url_idx) { 717 url_num_errors = 0; 718 do_advance_url = false; 719 } 720 } 721 722 if (HandleErrorCode(get<1>(err_tuple), &url_num_errors) || 723 url_num_errors > update_state.download_errors_max) 724 do_advance_url = true; 725 726 prev_url_idx = url_idx; 727 } 728 729 // If required, advance to the next usable URL. If the URLs wraparound, we 730 // mark an update attempt failure. Also be sure to set the download error 731 // count to zero. 732 if (url_idx < 0 || do_advance_url) { 733 url_num_errors = 0; 734 int start_url_idx = -1; 735 do { 736 if (++url_idx == num_urls) { 737 url_idx = 0; 738 // We only mark failure if an actual advancing of a URL was required. 739 if (do_advance_url) 740 is_failure_occurred = true; 741 } 742 743 if (start_url_idx < 0) 744 start_url_idx = url_idx; 745 else if (url_idx == start_url_idx) 746 url_idx = -1; // No usable URL. 747 } while (url_idx >= 0 && 748 !IsUrlUsable(update_state.download_urls[url_idx], http_allowed)); 749 } 750 751 // If we have a download URL but a failure was observed, compute a new backoff 752 // expiry (if allowed). The backoff period is generally 2 ^ (num_failures - 1) 753 // days, bounded by the size of int and kAttemptBackoffMaxIntervalInDays, and 754 // fuzzed by kAttemptBackoffFuzzInHours hours. Backoff expiry is computed from 755 // the latest recorded time of error. 756 Time backoff_expiry; 757 if (url_idx >= 0 && is_failure_occurred && may_backoff) { 758 CHECK(!err_time.is_null()) 759 << "We must have an error timestamp if a failure occurred!"; 760 const uint64_t* seed = ec->GetValue(state->random_provider()->var_seed()); 761 POLICY_CHECK_VALUE_AND_FAIL(seed, error); 762 PRNG prng(*seed); 763 int exp = 764 min(update_state.num_failures, static_cast<int>(sizeof(int)) * 8 - 2); 765 TimeDelta backoff_interval = TimeDelta::FromDays(min( 766 1 << exp, 767 kNextUpdateCheckPolicyConstants.attempt_backoff_max_interval_in_days)); 768 TimeDelta backoff_fuzz = TimeDelta::FromHours( 769 kNextUpdateCheckPolicyConstants.attempt_backoff_fuzz_in_hours); 770 TimeDelta wait_period = NextUpdateCheckTimePolicyImpl::FuzzedInterval( 771 &prng, backoff_interval.InSeconds(), backoff_fuzz.InSeconds()); 772 backoff_expiry = err_time + wait_period; 773 774 // If the newly computed backoff already expired, nullify it. 775 if (ec->IsWallclockTimeGreaterThan(backoff_expiry)) 776 backoff_expiry = Time(); 777 } 778 779 result->do_increment_failures = is_failure_occurred; 780 result->backoff_expiry = backoff_expiry; 781 result->url_idx = url_idx; 782 result->url_num_errors = url_num_errors; 783 return EvalStatus::kSucceeded; 784 } 785 786 EvalStatus ChromeOSPolicy::UpdateScattering( 787 EvaluationContext* ec, 788 State* state, 789 string* error, 790 UpdateScatteringResult* result, 791 const UpdateState& update_state) const { 792 // Preconditions. These stem from the postconditions and usage contract. 793 DCHECK(update_state.scatter_wait_period >= kZeroInterval); 794 DCHECK_GE(update_state.scatter_check_threshold, 0); 795 796 // Set default result values. 797 result->is_scattering = false; 798 result->wait_period = kZeroInterval; 799 result->check_threshold = 0; 800 801 DevicePolicyProvider* const dp_provider = state->device_policy_provider(); 802 803 // Ensure that a device policy is loaded. 804 const bool* device_policy_is_loaded_p = 805 ec->GetValue(dp_provider->var_device_policy_is_loaded()); 806 if (!(device_policy_is_loaded_p && *device_policy_is_loaded_p)) 807 return EvalStatus::kSucceeded; 808 809 // Is scattering enabled by policy? 810 const TimeDelta* scatter_factor_p = 811 ec->GetValue(dp_provider->var_scatter_factor()); 812 if (!scatter_factor_p || *scatter_factor_p == kZeroInterval) 813 return EvalStatus::kSucceeded; 814 815 // Obtain a pseudo-random number generator. 816 const uint64_t* seed = ec->GetValue(state->random_provider()->var_seed()); 817 POLICY_CHECK_VALUE_AND_FAIL(seed, error); 818 PRNG prng(*seed); 819 820 // Step 1: Maintain the scattering wait period. 821 // 822 // If no wait period was previously determined, or it no longer fits in the 823 // scatter factor, then generate a new one. Otherwise, keep the one we have. 824 TimeDelta wait_period = update_state.scatter_wait_period; 825 if (wait_period == kZeroInterval || wait_period > *scatter_factor_p) { 826 wait_period = TimeDelta::FromSeconds( 827 prng.RandMinMax(1, scatter_factor_p->InSeconds())); 828 } 829 830 // If we surpassed the wait period or the max scatter period associated with 831 // the update, then no wait is needed. 832 Time wait_expires = (update_state.first_seen + 833 min(wait_period, update_state.scatter_wait_period_max)); 834 if (ec->IsWallclockTimeGreaterThan(wait_expires)) 835 wait_period = kZeroInterval; 836 837 // Step 2: Maintain the update check threshold count. 838 // 839 // If an update check threshold is not specified then generate a new 840 // one. 841 int check_threshold = update_state.scatter_check_threshold; 842 if (check_threshold == 0) { 843 check_threshold = prng.RandMinMax(update_state.scatter_check_threshold_min, 844 update_state.scatter_check_threshold_max); 845 } 846 847 // If the update check threshold is not within allowed range then nullify it. 848 // TODO(garnold) This is compliant with current logic found in 849 // OmahaRequestAction::IsUpdateCheckCountBasedWaitingSatisfied(). We may want 850 // to change it so that it behaves similarly to the wait period case, namely 851 // if the current value exceeds the maximum, we set a new one within range. 852 if (check_threshold > update_state.scatter_check_threshold_max) 853 check_threshold = 0; 854 855 // If the update check threshold is non-zero and satisfied, then nullify it. 856 if (check_threshold > 0 && update_state.num_checks >= check_threshold) 857 check_threshold = 0; 858 859 bool is_scattering = (wait_period != kZeroInterval || check_threshold); 860 EvalStatus ret = EvalStatus::kSucceeded; 861 if (is_scattering && wait_period == update_state.scatter_wait_period && 862 check_threshold == update_state.scatter_check_threshold) 863 ret = EvalStatus::kAskMeAgainLater; 864 result->is_scattering = is_scattering; 865 result->wait_period = wait_period; 866 result->check_threshold = check_threshold; 867 return ret; 868 } 869 870 } // namespace chromeos_update_manager 871