1 /* 2 * Copyright (C) 2007 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 <ctype.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <inttypes.h> 21 #include <limits.h> 22 #include <string.h> 23 #include <sys/stat.h> 24 #include <sys/wait.h> 25 #include <unistd.h> 26 27 #include <chrono> 28 #include <limits> 29 #include <map> 30 #include <string> 31 #include <vector> 32 33 #include <android-base/parseint.h> 34 #include <android-base/stringprintf.h> 35 #include <android-base/strings.h> 36 #include <cutils/properties.h> 37 38 #include "common.h" 39 #include "error_code.h" 40 #include "install.h" 41 #include "minui/minui.h" 42 #include "minzip/SysUtil.h" 43 #include "minzip/Zip.h" 44 #include "mtdutils/mounts.h" 45 #include "mtdutils/mtdutils.h" 46 #include "roots.h" 47 #include "ui.h" 48 #include "verifier.h" 49 50 extern RecoveryUI* ui; 51 52 #define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary" 53 static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt"; 54 static constexpr const char* AB_OTA_PAYLOAD = "payload.bin"; 55 #define PUBLIC_KEYS_FILE "/res/keys" 56 static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata"; 57 58 // Default allocation of progress bar segments to operations 59 static const int VERIFICATION_PROGRESS_TIME = 60; 60 static const float VERIFICATION_PROGRESS_FRACTION = 0.25; 61 static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4; 62 static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1; 63 64 // This function parses and returns the build.version.incremental 65 static int parse_build_number(std::string str) { 66 size_t pos = str.find("="); 67 if (pos != std::string::npos) { 68 std::string num_string = android::base::Trim(str.substr(pos+1)); 69 int build_number; 70 if (android::base::ParseInt(num_string.c_str(), &build_number, 0)) { 71 return build_number; 72 } 73 } 74 75 LOGE("Failed to parse build number in %s.\n", str.c_str()); 76 return -1; 77 } 78 79 bool read_metadata_from_package(ZipArchive* zip, std::string* meta_data) { 80 const ZipEntry* meta_entry = mzFindZipEntry(zip, METADATA_PATH); 81 if (meta_entry == nullptr) { 82 LOGE("Failed to find %s in update package.\n", METADATA_PATH); 83 return false; 84 } 85 86 meta_data->resize(meta_entry->uncompLen, '\0'); 87 if (!mzReadZipEntry(zip, meta_entry, &(*meta_data)[0], meta_entry->uncompLen)) { 88 LOGE("Failed to read metadata in update package.\n"); 89 return false; 90 } 91 return true; 92 } 93 94 // Read the build.version.incremental of src/tgt from the metadata and log it to last_install. 95 static void read_source_target_build(ZipArchive* zip, std::vector<std::string>& log_buffer) { 96 std::string meta_data; 97 if (!read_metadata_from_package(zip, &meta_data)) { 98 return; 99 } 100 // Examples of the pre-build and post-build strings in metadata: 101 // pre-build-incremental=2943039 102 // post-build-incremental=2951741 103 std::vector<std::string> lines = android::base::Split(meta_data, "\n"); 104 for (const std::string& line : lines) { 105 std::string str = android::base::Trim(line); 106 if (android::base::StartsWith(str, "pre-build-incremental")){ 107 int source_build = parse_build_number(str); 108 if (source_build != -1) { 109 log_buffer.push_back(android::base::StringPrintf("source_build: %d", 110 source_build)); 111 } 112 } else if (android::base::StartsWith(str, "post-build-incremental")) { 113 int target_build = parse_build_number(str); 114 if (target_build != -1) { 115 log_buffer.push_back(android::base::StringPrintf("target_build: %d", 116 target_build)); 117 } 118 } 119 } 120 } 121 122 // Extract the update binary from the open zip archive |zip| located at |path| 123 // and store into |cmd| the command line that should be called. The |status_fd| 124 // is the file descriptor the child process should use to report back the 125 // progress of the update. 126 static int 127 update_binary_command(const char* path, ZipArchive* zip, int retry_count, 128 int status_fd, std::vector<std::string>* cmd); 129 130 #ifdef AB_OTA_UPDATER 131 132 // Parses the metadata of the OTA package in |zip| and checks whether we are 133 // allowed to accept this A/B package. Downgrading is not allowed unless 134 // explicitly enabled in the package and only for incremental packages. 135 static int check_newer_ab_build(ZipArchive* zip) 136 { 137 std::string metadata_str; 138 if (!read_metadata_from_package(zip, &metadata_str)) { 139 return INSTALL_CORRUPT; 140 } 141 std::map<std::string, std::string> metadata; 142 for (const std::string& line : android::base::Split(metadata_str, "\n")) { 143 size_t eq = line.find('='); 144 if (eq != std::string::npos) { 145 metadata[line.substr(0, eq)] = line.substr(eq + 1); 146 } 147 } 148 char value[PROPERTY_VALUE_MAX]; 149 150 property_get("ro.product.device", value, ""); 151 const std::string& pkg_device = metadata["pre-device"]; 152 if (pkg_device != value || pkg_device.empty()) { 153 LOGE("Package is for product %s but expected %s\n", 154 pkg_device.c_str(), value); 155 return INSTALL_ERROR; 156 } 157 158 // We allow the package to not have any serialno, but if it has a non-empty 159 // value it should match. 160 property_get("ro.serialno", value, ""); 161 const std::string& pkg_serial_no = metadata["serialno"]; 162 if (!pkg_serial_no.empty() && pkg_serial_no != value) { 163 LOGE("Package is for serial %s\n", pkg_serial_no.c_str()); 164 return INSTALL_ERROR; 165 } 166 167 if (metadata["ota-type"] != "AB") { 168 LOGE("Package is not A/B\n"); 169 return INSTALL_ERROR; 170 } 171 172 // Incremental updates should match the current build. 173 property_get("ro.build.version.incremental", value, ""); 174 const std::string& pkg_pre_build = metadata["pre-build-incremental"]; 175 if (!pkg_pre_build.empty() && pkg_pre_build != value) { 176 LOGE("Package is for source build %s but expected %s\n", 177 pkg_pre_build.c_str(), value); 178 return INSTALL_ERROR; 179 } 180 property_get("ro.build.fingerprint", value, ""); 181 const std::string& pkg_pre_build_fingerprint = metadata["pre-build"]; 182 if (!pkg_pre_build_fingerprint.empty() && 183 pkg_pre_build_fingerprint != value) { 184 LOGE("Package is for source build %s but expected %s\n", 185 pkg_pre_build_fingerprint.c_str(), value); 186 return INSTALL_ERROR; 187 } 188 189 // Check for downgrade version. 190 int64_t build_timestampt = property_get_int64( 191 "ro.build.date.utc", std::numeric_limits<int64_t>::max()); 192 int64_t pkg_post_timespampt = 0; 193 // We allow to full update to the same version we are running, in case there 194 // is a problem with the current copy of that version. 195 if (metadata["post-timestamp"].empty() || 196 !android::base::ParseInt(metadata["post-timestamp"].c_str(), 197 &pkg_post_timespampt) || 198 pkg_post_timespampt < build_timestampt) { 199 if (metadata["ota-downgrade"] != "yes") { 200 LOGE("Update package is older than the current build, expected a " 201 "build newer than timestamp %" PRIu64 " but package has " 202 "timestamp %" PRIu64 " and downgrade not allowed.\n", 203 build_timestampt, pkg_post_timespampt); 204 return INSTALL_ERROR; 205 } 206 if (pkg_pre_build_fingerprint.empty()) { 207 LOGE("Downgrade package must have a pre-build version set, not " 208 "allowed.\n"); 209 return INSTALL_ERROR; 210 } 211 } 212 213 return 0; 214 } 215 216 static int 217 update_binary_command(const char* path, ZipArchive* zip, int retry_count, 218 int status_fd, std::vector<std::string>* cmd) 219 { 220 int ret = check_newer_ab_build(zip); 221 if (ret) { 222 return ret; 223 } 224 225 // For A/B updates we extract the payload properties to a buffer and obtain 226 // the RAW payload offset in the zip file. 227 const ZipEntry* properties_entry = 228 mzFindZipEntry(zip, AB_OTA_PAYLOAD_PROPERTIES); 229 if (!properties_entry) { 230 LOGE("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES); 231 return INSTALL_CORRUPT; 232 } 233 std::vector<unsigned char> payload_properties( 234 mzGetZipEntryUncompLen(properties_entry)); 235 if (!mzExtractZipEntryToBuffer(zip, properties_entry, 236 payload_properties.data())) { 237 LOGE("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES); 238 return INSTALL_CORRUPT; 239 } 240 241 const ZipEntry* payload_entry = mzFindZipEntry(zip, AB_OTA_PAYLOAD); 242 if (!payload_entry) { 243 LOGE("Can't find %s\n", AB_OTA_PAYLOAD); 244 return INSTALL_CORRUPT; 245 } 246 long payload_offset = mzGetZipEntryOffset(payload_entry); 247 *cmd = { 248 "/sbin/update_engine_sideload", 249 android::base::StringPrintf("--payload=file://%s", path), 250 android::base::StringPrintf("--offset=%ld", payload_offset), 251 "--headers=" + std::string(payload_properties.begin(), 252 payload_properties.end()), 253 android::base::StringPrintf("--status_fd=%d", status_fd), 254 }; 255 return 0; 256 } 257 258 #else // !AB_OTA_UPDATER 259 260 static int 261 update_binary_command(const char* path, ZipArchive* zip, int retry_count, 262 int status_fd, std::vector<std::string>* cmd) 263 { 264 // On traditional updates we extract the update binary from the package. 265 const ZipEntry* binary_entry = 266 mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME); 267 if (binary_entry == NULL) { 268 return INSTALL_CORRUPT; 269 } 270 271 const char* binary = "/tmp/update_binary"; 272 unlink(binary); 273 int fd = creat(binary, 0755); 274 if (fd < 0) { 275 LOGE("Can't make %s\n", binary); 276 return INSTALL_ERROR; 277 } 278 bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd); 279 close(fd); 280 281 if (!ok) { 282 LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME); 283 return INSTALL_ERROR; 284 } 285 286 *cmd = { 287 binary, 288 EXPAND(RECOVERY_API_VERSION), // defined in Android.mk 289 std::to_string(status_fd), 290 path, 291 }; 292 if (retry_count > 0) 293 cmd->push_back("retry"); 294 return 0; 295 } 296 #endif // !AB_OTA_UPDATER 297 298 // If the package contains an update binary, extract it and run it. 299 static int 300 try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache, 301 std::vector<std::string>& log_buffer, int retry_count) 302 { 303 read_source_target_build(zip, log_buffer); 304 305 int pipefd[2]; 306 pipe(pipefd); 307 308 std::vector<std::string> args; 309 int ret = update_binary_command(path, zip, retry_count, pipefd[1], &args); 310 mzCloseZipArchive(zip); 311 if (ret) { 312 close(pipefd[0]); 313 close(pipefd[1]); 314 return ret; 315 } 316 317 // When executing the update binary contained in the package, the 318 // arguments passed are: 319 // 320 // - the version number for this interface 321 // 322 // - an fd to which the program can write in order to update the 323 // progress bar. The program can write single-line commands: 324 // 325 // progress <frac> <secs> 326 // fill up the next <frac> part of of the progress bar 327 // over <secs> seconds. If <secs> is zero, use 328 // set_progress commands to manually control the 329 // progress of this segment of the bar. 330 // 331 // set_progress <frac> 332 // <frac> should be between 0.0 and 1.0; sets the 333 // progress bar within the segment defined by the most 334 // recent progress command. 335 // 336 // firmware <"hboot"|"radio"> <filename> 337 // arrange to install the contents of <filename> in the 338 // given partition on reboot. 339 // 340 // (API v2: <filename> may start with "PACKAGE:" to 341 // indicate taking a file from the OTA package.) 342 // 343 // (API v3: this command no longer exists.) 344 // 345 // ui_print <string> 346 // display <string> on the screen. 347 // 348 // wipe_cache 349 // a wipe of cache will be performed following a successful 350 // installation. 351 // 352 // clear_display 353 // turn off the text display. 354 // 355 // enable_reboot 356 // packages can explicitly request that they want the user 357 // to be able to reboot during installation (useful for 358 // debugging packages that don't exit). 359 // 360 // - the name of the package zip file. 361 // 362 // - an optional argument "retry" if this update is a retry of a failed 363 // update attempt. 364 // 365 366 // Convert the vector to a NULL-terminated char* array suitable for execv. 367 const char* chr_args[args.size() + 1]; 368 chr_args[args.size()] = NULL; 369 for (size_t i = 0; i < args.size(); i++) { 370 chr_args[i] = args[i].c_str(); 371 } 372 373 pid_t pid = fork(); 374 if (pid == 0) { 375 umask(022); 376 close(pipefd[0]); 377 execv(chr_args[0], const_cast<char**>(chr_args)); 378 fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno)); 379 _exit(-1); 380 } 381 close(pipefd[1]); 382 383 *wipe_cache = false; 384 bool retry_update = false; 385 386 char buffer[1024]; 387 FILE* from_child = fdopen(pipefd[0], "r"); 388 while (fgets(buffer, sizeof(buffer), from_child) != NULL) { 389 char* command = strtok(buffer, " \n"); 390 if (command == NULL) { 391 continue; 392 } else if (strcmp(command, "progress") == 0) { 393 char* fraction_s = strtok(NULL, " \n"); 394 char* seconds_s = strtok(NULL, " \n"); 395 396 float fraction = strtof(fraction_s, NULL); 397 int seconds = strtol(seconds_s, NULL, 10); 398 399 ui->ShowProgress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds); 400 } else if (strcmp(command, "set_progress") == 0) { 401 char* fraction_s = strtok(NULL, " \n"); 402 float fraction = strtof(fraction_s, NULL); 403 ui->SetProgress(fraction); 404 } else if (strcmp(command, "ui_print") == 0) { 405 char* str = strtok(NULL, "\n"); 406 if (str) { 407 ui->PrintOnScreenOnly("%s", str); 408 } else { 409 ui->PrintOnScreenOnly("\n"); 410 } 411 fflush(stdout); 412 } else if (strcmp(command, "wipe_cache") == 0) { 413 *wipe_cache = true; 414 } else if (strcmp(command, "clear_display") == 0) { 415 ui->SetBackground(RecoveryUI::NONE); 416 } else if (strcmp(command, "enable_reboot") == 0) { 417 // packages can explicitly request that they want the user 418 // to be able to reboot during installation (useful for 419 // debugging packages that don't exit). 420 ui->SetEnableReboot(true); 421 } else if (strcmp(command, "retry_update") == 0) { 422 retry_update = true; 423 } else if (strcmp(command, "log") == 0) { 424 // Save the logging request from updater and write to 425 // last_install later. 426 log_buffer.push_back(std::string(strtok(NULL, "\n"))); 427 } else { 428 LOGE("unknown command [%s]\n", command); 429 } 430 } 431 fclose(from_child); 432 433 int status; 434 waitpid(pid, &status, 0); 435 if (retry_update) { 436 return INSTALL_RETRY; 437 } 438 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 439 LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status)); 440 return INSTALL_ERROR; 441 } 442 443 return INSTALL_SUCCESS; 444 } 445 446 static int 447 really_install_package(const char *path, bool* wipe_cache, bool needs_mount, 448 std::vector<std::string>& log_buffer, int retry_count) 449 { 450 ui->SetBackground(RecoveryUI::INSTALLING_UPDATE); 451 ui->Print("Finding update package...\n"); 452 // Give verification half the progress bar... 453 ui->SetProgressType(RecoveryUI::DETERMINATE); 454 ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); 455 LOGI("Update location: %s\n", path); 456 457 // Map the update package into memory. 458 ui->Print("Opening update package...\n"); 459 460 if (path && needs_mount) { 461 if (path[0] == '@') { 462 ensure_path_mounted(path+1); 463 } else { 464 ensure_path_mounted(path); 465 } 466 } 467 468 MemMapping map; 469 if (sysMapFile(path, &map) != 0) { 470 LOGE("failed to map file\n"); 471 return INSTALL_CORRUPT; 472 } 473 474 // Verify package. 475 if (!verify_package(map.addr, map.length)) { 476 log_buffer.push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure)); 477 sysReleaseMap(&map); 478 return INSTALL_CORRUPT; 479 } 480 481 // Try to open the package. 482 ZipArchive zip; 483 int err = mzOpenZipArchive(map.addr, map.length, &zip); 484 if (err != 0) { 485 LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); 486 log_buffer.push_back(android::base::StringPrintf("error: %d", kZipOpenFailure)); 487 488 sysReleaseMap(&map); 489 return INSTALL_CORRUPT; 490 } 491 492 // Verify and install the contents of the package. 493 ui->Print("Installing update...\n"); 494 if (retry_count > 0) { 495 ui->Print("Retry attempt: %d\n", retry_count); 496 } 497 ui->SetEnableReboot(false); 498 int result = try_update_binary(path, &zip, wipe_cache, log_buffer, retry_count); 499 ui->SetEnableReboot(true); 500 ui->Print("\n"); 501 502 sysReleaseMap(&map); 503 504 return result; 505 } 506 507 int 508 install_package(const char* path, bool* wipe_cache, const char* install_file, 509 bool needs_mount, int retry_count) 510 { 511 modified_flash = true; 512 auto start = std::chrono::system_clock::now(); 513 514 FILE* install_log = fopen_path(install_file, "w"); 515 if (install_log) { 516 fputs(path, install_log); 517 fputc('\n', install_log); 518 } else { 519 LOGE("failed to open last_install: %s\n", strerror(errno)); 520 } 521 int result; 522 std::vector<std::string> log_buffer; 523 if (setup_install_mounts() != 0) { 524 LOGE("failed to set up expected mounts for install; aborting\n"); 525 result = INSTALL_ERROR; 526 } else { 527 result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count); 528 } 529 if (install_log != nullptr) { 530 fputc(result == INSTALL_SUCCESS ? '1' : '0', install_log); 531 fputc('\n', install_log); 532 std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; 533 int count = static_cast<int>(duration.count()); 534 // Report the time spent to apply OTA update in seconds. 535 fprintf(install_log, "time_total: %d\n", count); 536 fprintf(install_log, "retry: %d\n", retry_count); 537 538 for (const auto& s : log_buffer) { 539 fprintf(install_log, "%s\n", s.c_str()); 540 } 541 542 fclose(install_log); 543 } 544 return result; 545 } 546 547 bool verify_package(const unsigned char* package_data, size_t package_size) { 548 std::vector<Certificate> loadedKeys; 549 if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) { 550 LOGE("Failed to load keys\n"); 551 return false; 552 } 553 LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE); 554 555 // Verify package. 556 ui->Print("Verifying update package...\n"); 557 auto t0 = std::chrono::system_clock::now(); 558 int err = verify_file(const_cast<unsigned char*>(package_data), package_size, loadedKeys); 559 std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0; 560 ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err); 561 if (err != VERIFY_SUCCESS) { 562 LOGE("Signature verification failed\n"); 563 LOGE("error: %d\n", kZipVerificationFailure); 564 return false; 565 } 566 return true; 567 } 568