1 /* 2 * Copyright (C) 2008 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 "applypatch/applypatch.h" 18 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <libgen.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/stat.h> 26 #include <sys/statfs.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 30 #include <memory> 31 #include <string> 32 #include <utility> 33 #include <vector> 34 35 #include <android-base/logging.h> 36 #include <android-base/parseint.h> 37 #include <android-base/strings.h> 38 #include <openssl/sha.h> 39 40 #include "edify/expr.h" 41 #include "ota_io.h" 42 #include "print_sha1.h" 43 44 static int LoadPartitionContents(const std::string& filename, FileContents* file); 45 static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token); 46 static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch, 47 const std::string& target_filename, 48 const uint8_t target_sha1[SHA_DIGEST_LENGTH], const Value* bonus_data); 49 50 // Read a file into memory; store the file contents and associated metadata in *file. 51 // Return 0 on success. 52 int LoadFileContents(const char* filename, FileContents* file) { 53 // A special 'filename' beginning with "EMMC:" means to load the contents of a partition. 54 if (strncmp(filename, "EMMC:", 5) == 0) { 55 return LoadPartitionContents(filename, file); 56 } 57 58 if (stat(filename, &file->st) == -1) { 59 printf("failed to stat \"%s\": %s\n", filename, strerror(errno)); 60 return -1; 61 } 62 63 std::vector<unsigned char> data(file->st.st_size); 64 unique_file f(ota_fopen(filename, "rb")); 65 if (!f) { 66 printf("failed to open \"%s\": %s\n", filename, strerror(errno)); 67 return -1; 68 } 69 70 size_t bytes_read = ota_fread(data.data(), 1, data.size(), f.get()); 71 if (bytes_read != data.size()) { 72 printf("short read of \"%s\" (%zu bytes of %zu)\n", filename, bytes_read, data.size()); 73 return -1; 74 } 75 file->data = std::move(data); 76 SHA1(file->data.data(), file->data.size(), file->sha1); 77 return 0; 78 } 79 80 // Load the contents of an EMMC partition into the provided 81 // FileContents. filename should be a string of the form 82 // "EMMC:<partition_device>:...". The smallest size_n bytes for 83 // which that prefix of the partition contents has the corresponding 84 // sha1 hash will be loaded. It is acceptable for a size value to be 85 // repeated with different sha1s. Will return 0 on success. 86 // 87 // This complexity is needed because if an OTA installation is 88 // interrupted, the partition might contain either the source or the 89 // target data, which might be of different lengths. We need to know 90 // the length in order to read from a partition (there is no 91 // "end-of-file" marker), so the caller must specify the possible 92 // lengths and the hash of the data, and we'll do the load expecting 93 // to find one of those hashes. 94 static int LoadPartitionContents(const std::string& filename, FileContents* file) { 95 std::vector<std::string> pieces = android::base::Split(filename, ":"); 96 if (pieces.size() < 4 || pieces.size() % 2 != 0 || pieces[0] != "EMMC") { 97 printf("LoadPartitionContents called with bad filename \"%s\"\n", filename.c_str()); 98 return -1; 99 } 100 101 size_t pair_count = (pieces.size() - 2) / 2; // # of (size, sha1) pairs in filename 102 std::vector<std::pair<size_t, std::string>> pairs; 103 for (size_t i = 0; i < pair_count; ++i) { 104 size_t size; 105 if (!android::base::ParseUint(pieces[i * 2 + 2], &size) || size == 0) { 106 printf("LoadPartitionContents called with bad size \"%s\"\n", pieces[i * 2 + 2].c_str()); 107 return -1; 108 } 109 pairs.push_back({ size, pieces[i * 2 + 3] }); 110 } 111 112 // Sort the pairs array so that they are in order of increasing size. 113 std::sort(pairs.begin(), pairs.end()); 114 115 const char* partition = pieces[1].c_str(); 116 unique_file dev(ota_fopen(partition, "rb")); 117 if (!dev) { 118 printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno)); 119 return -1; 120 } 121 122 SHA_CTX sha_ctx; 123 SHA1_Init(&sha_ctx); 124 125 // Allocate enough memory to hold the largest size. 126 std::vector<unsigned char> buffer(pairs[pair_count - 1].first); 127 unsigned char* buffer_ptr = buffer.data(); 128 size_t buffer_size = 0; // # bytes read so far 129 bool found = false; 130 131 for (const auto& pair : pairs) { 132 size_t current_size = pair.first; 133 const std::string& current_sha1 = pair.second; 134 135 // Read enough additional bytes to get us up to the next size. (Again, 136 // we're trying the possibilities in order of increasing size). 137 size_t next = current_size - buffer_size; 138 if (next > 0) { 139 size_t read = ota_fread(buffer_ptr, 1, next, dev.get()); 140 if (next != read) { 141 printf("short read (%zu bytes of %zu) for partition \"%s\"\n", read, next, partition); 142 return -1; 143 } 144 SHA1_Update(&sha_ctx, buffer_ptr, read); 145 buffer_size += read; 146 buffer_ptr += read; 147 } 148 149 // Duplicate the SHA context and finalize the duplicate so we can 150 // check it against this pair's expected hash. 151 SHA_CTX temp_ctx; 152 memcpy(&temp_ctx, &sha_ctx, sizeof(SHA_CTX)); 153 uint8_t sha_so_far[SHA_DIGEST_LENGTH]; 154 SHA1_Final(sha_so_far, &temp_ctx); 155 156 uint8_t parsed_sha[SHA_DIGEST_LENGTH]; 157 if (ParseSha1(current_sha1.c_str(), parsed_sha) != 0) { 158 printf("failed to parse SHA-1 %s in %s\n", current_sha1.c_str(), filename.c_str()); 159 return -1; 160 } 161 162 if (memcmp(sha_so_far, parsed_sha, SHA_DIGEST_LENGTH) == 0) { 163 // We have a match. Stop reading the partition; we'll return the data we've read so far. 164 printf("partition read matched size %zu SHA-1 %s\n", current_size, current_sha1.c_str()); 165 found = true; 166 break; 167 } 168 } 169 170 if (!found) { 171 // Ran off the end of the list of (size, sha1) pairs without finding a match. 172 printf("contents of partition \"%s\" didn't match %s\n", partition, filename.c_str()); 173 return -1; 174 } 175 176 SHA1_Final(file->sha1, &sha_ctx); 177 178 buffer.resize(buffer_size); 179 file->data = std::move(buffer); 180 // Fake some stat() info. 181 file->st.st_mode = 0644; 182 file->st.st_uid = 0; 183 file->st.st_gid = 0; 184 185 return 0; 186 } 187 188 // Save the contents of the given FileContents object under the given 189 // filename. Return 0 on success. 190 int SaveFileContents(const char* filename, const FileContents* file) { 191 unique_fd fd(ota_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR)); 192 if (fd == -1) { 193 printf("failed to open \"%s\" for write: %s\n", filename, strerror(errno)); 194 return -1; 195 } 196 197 ssize_t bytes_written = FileSink(file->data.data(), file->data.size(), &fd); 198 if (bytes_written != static_cast<ssize_t>(file->data.size())) { 199 printf("short write of \"%s\" (%zd bytes of %zu): %s\n", filename, bytes_written, 200 file->data.size(), strerror(errno)); 201 return -1; 202 } 203 if (ota_fsync(fd) != 0) { 204 printf("fsync of \"%s\" failed: %s\n", filename, strerror(errno)); 205 return -1; 206 } 207 if (ota_close(fd) != 0) { 208 printf("close of \"%s\" failed: %s\n", filename, strerror(errno)); 209 return -1; 210 } 211 212 if (chmod(filename, file->st.st_mode) != 0) { 213 printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno)); 214 return -1; 215 } 216 if (chown(filename, file->st.st_uid, file->st.st_gid) != 0) { 217 printf("chown of \"%s\" failed: %s\n", filename, strerror(errno)); 218 return -1; 219 } 220 221 return 0; 222 } 223 224 // Write a memory buffer to 'target' partition, a string of the form 225 // "EMMC:<partition_device>[:...]". The target name 226 // might contain multiple colons, but WriteToPartition() only uses the first 227 // two and ignores the rest. Return 0 on success. 228 int WriteToPartition(const unsigned char* data, size_t len, const std::string& target) { 229 std::vector<std::string> pieces = android::base::Split(target, ":"); 230 if (pieces.size() < 2 || pieces[0] != "EMMC") { 231 printf("WriteToPartition called with bad target (%s)\n", target.c_str()); 232 return -1; 233 } 234 235 const char* partition = pieces[1].c_str(); 236 unique_fd fd(ota_open(partition, O_RDWR)); 237 if (fd == -1) { 238 printf("failed to open %s: %s\n", partition, strerror(errno)); 239 return -1; 240 } 241 242 size_t start = 0; 243 bool success = false; 244 for (size_t attempt = 0; attempt < 2; ++attempt) { 245 if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) { 246 printf("failed seek on %s: %s\n", partition, strerror(errno)); 247 return -1; 248 } 249 while (start < len) { 250 size_t to_write = len - start; 251 if (to_write > 1 << 20) to_write = 1 << 20; 252 253 ssize_t written = TEMP_FAILURE_RETRY(ota_write(fd, data + start, to_write)); 254 if (written == -1) { 255 printf("failed write writing to %s: %s\n", partition, strerror(errno)); 256 return -1; 257 } 258 start += written; 259 } 260 261 if (ota_fsync(fd) != 0) { 262 printf("failed to sync to %s: %s\n", partition, strerror(errno)); 263 return -1; 264 } 265 if (ota_close(fd) != 0) { 266 printf("failed to close %s: %s\n", partition, strerror(errno)); 267 return -1; 268 } 269 270 fd.reset(ota_open(partition, O_RDONLY)); 271 if (fd == -1) { 272 printf("failed to reopen %s for verify: %s\n", partition, strerror(errno)); 273 return -1; 274 } 275 276 // Drop caches so our subsequent verification read won't just be reading the cache. 277 sync(); 278 unique_fd dc(ota_open("/proc/sys/vm/drop_caches", O_WRONLY)); 279 if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) { 280 printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno)); 281 } else { 282 printf(" caches dropped\n"); 283 } 284 ota_close(dc); 285 sleep(1); 286 287 // Verify. 288 if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) { 289 printf("failed to seek back to beginning of %s: %s\n", partition, strerror(errno)); 290 return -1; 291 } 292 293 unsigned char buffer[4096]; 294 start = len; 295 for (size_t p = 0; p < len; p += sizeof(buffer)) { 296 size_t to_read = len - p; 297 if (to_read > sizeof(buffer)) { 298 to_read = sizeof(buffer); 299 } 300 301 size_t so_far = 0; 302 while (so_far < to_read) { 303 ssize_t read_count = TEMP_FAILURE_RETRY(ota_read(fd, buffer + so_far, to_read - so_far)); 304 if (read_count == -1) { 305 printf("verify read error %s at %zu: %s\n", partition, p, strerror(errno)); 306 return -1; 307 } else if (read_count == 0) { 308 printf("verify read reached unexpected EOF, %s at %zu\n", partition, p); 309 return -1; 310 } 311 if (static_cast<size_t>(read_count) < to_read) { 312 printf("short verify read %s at %zu: %zd %zu\n", partition, p, read_count, to_read); 313 } 314 so_far += read_count; 315 } 316 317 if (memcmp(buffer, data + p, to_read) != 0) { 318 printf("verification failed starting at %zu\n", p); 319 start = p; 320 break; 321 } 322 } 323 324 if (start == len) { 325 printf("verification read succeeded (attempt %zu)\n", attempt + 1); 326 success = true; 327 break; 328 } 329 330 if (ota_close(fd) != 0) { 331 printf("failed to close %s: %s\n", partition, strerror(errno)); 332 return -1; 333 } 334 335 fd.reset(ota_open(partition, O_RDWR)); 336 if (fd == -1) { 337 printf("failed to reopen %s for retry write && verify: %s\n", partition, strerror(errno)); 338 return -1; 339 } 340 } 341 342 if (!success) { 343 printf("failed to verify after all attempts\n"); 344 return -1; 345 } 346 347 if (ota_close(fd) == -1) { 348 printf("error closing %s: %s\n", partition, strerror(errno)); 349 return -1; 350 } 351 sync(); 352 353 return 0; 354 } 355 356 // Take a string 'str' of 40 hex digits and parse it into the 20 357 // byte array 'digest'. 'str' may contain only the digest or be of 358 // the form "<digest>:<anything>". Return 0 on success, -1 on any 359 // error. 360 int ParseSha1(const char* str, uint8_t* digest) { 361 const char* ps = str; 362 uint8_t* pd = digest; 363 for (int i = 0; i < SHA_DIGEST_LENGTH * 2; ++i, ++ps) { 364 int digit; 365 if (*ps >= '0' && *ps <= '9') { 366 digit = *ps - '0'; 367 } else if (*ps >= 'a' && *ps <= 'f') { 368 digit = *ps - 'a' + 10; 369 } else if (*ps >= 'A' && *ps <= 'F') { 370 digit = *ps - 'A' + 10; 371 } else { 372 return -1; 373 } 374 if (i % 2 == 0) { 375 *pd = digit << 4; 376 } else { 377 *pd |= digit; 378 ++pd; 379 } 380 } 381 if (*ps != '\0') return -1; 382 return 0; 383 } 384 385 // Search an array of sha1 strings for one matching the given sha1. 386 // Return the index of the match on success, or -1 if no match is 387 // found. 388 static int FindMatchingPatch(uint8_t* sha1, const std::vector<std::string>& patch_sha1_str) { 389 for (size_t i = 0; i < patch_sha1_str.size(); ++i) { 390 uint8_t patch_sha1[SHA_DIGEST_LENGTH]; 391 if (ParseSha1(patch_sha1_str[i].c_str(), patch_sha1) == 0 && 392 memcmp(patch_sha1, sha1, SHA_DIGEST_LENGTH) == 0) { 393 return i; 394 } 395 } 396 return -1; 397 } 398 399 // Returns 0 if the contents of the file (argv[2]) or the cached file 400 // match any of the sha1's on the command line (argv[3:]). Returns 401 // nonzero otherwise. 402 int applypatch_check(const char* filename, const std::vector<std::string>& patch_sha1_str) { 403 FileContents file; 404 405 // It's okay to specify no sha1s; the check will pass if the 406 // LoadFileContents is successful. (Useful for reading 407 // partitions, where the filename encodes the sha1s; no need to 408 // check them twice.) 409 if (LoadFileContents(filename, &file) != 0 || 410 (!patch_sha1_str.empty() && FindMatchingPatch(file.sha1, patch_sha1_str) < 0)) { 411 printf("file \"%s\" doesn't have any of expected sha1 sums; checking cache\n", filename); 412 413 // If the source file is missing or corrupted, it might be because 414 // we were killed in the middle of patching it. A copy of it 415 // should have been made in CACHE_TEMP_SOURCE. If that file 416 // exists and matches the sha1 we're looking for, the check still 417 // passes. 418 if (LoadFileContents(CACHE_TEMP_SOURCE, &file) != 0) { 419 printf("failed to load cache file\n"); 420 return 1; 421 } 422 423 if (FindMatchingPatch(file.sha1, patch_sha1_str) < 0) { 424 printf("cache bits don't match any sha1 for \"%s\"\n", filename); 425 return 1; 426 } 427 } 428 return 0; 429 } 430 431 int ShowLicenses() { 432 ShowBSDiffLicense(); 433 return 0; 434 } 435 436 ssize_t FileSink(const unsigned char* data, ssize_t len, void* token) { 437 int fd = *static_cast<int*>(token); 438 ssize_t done = 0; 439 ssize_t wrote; 440 while (done < len) { 441 wrote = TEMP_FAILURE_RETRY(ota_write(fd, data+done, len-done)); 442 if (wrote == -1) { 443 printf("error writing %zd bytes: %s\n", (len-done), strerror(errno)); 444 return done; 445 } 446 done += wrote; 447 } 448 return done; 449 } 450 451 ssize_t MemorySink(const unsigned char* data, ssize_t len, void* token) { 452 std::string* s = static_cast<std::string*>(token); 453 s->append(reinterpret_cast<const char*>(data), len); 454 return len; 455 } 456 457 // Return the amount of free space (in bytes) on the filesystem 458 // containing filename. filename must exist. Return -1 on error. 459 size_t FreeSpaceForFile(const char* filename) { 460 struct statfs sf; 461 if (statfs(filename, &sf) != 0) { 462 printf("failed to statfs %s: %s\n", filename, strerror(errno)); 463 return -1; 464 } 465 return sf.f_bsize * sf.f_bavail; 466 } 467 468 int CacheSizeCheck(size_t bytes) { 469 if (MakeFreeSpaceOnCache(bytes) < 0) { 470 printf("unable to make %zu bytes available on /cache\n", bytes); 471 return 1; 472 } else { 473 return 0; 474 } 475 } 476 477 // This function applies binary patches to EMMC target files in a way that is safe (the original 478 // file is not touched until we have the desired replacement for it) and idempotent (it's okay to 479 // run this program multiple times). 480 // 481 // - If the SHA-1 hash of <target_filename> is <target_sha1_string>, does nothing and exits 482 // successfully. 483 // 484 // - Otherwise, if the SHA-1 hash of <source_filename> is one of the entries in <patch_sha1_str>, 485 // the corresponding patch from <patch_data> (which must be a VAL_BLOB) is applied to produce a 486 // new file (the type of patch is automatically detected from the blob data). If that new file 487 // has SHA-1 hash <target_sha1_str>, moves it to replace <target_filename>, and exits 488 // successfully. Note that if <source_filename> and <target_filename> are not the same, 489 // <source_filename> is NOT deleted on success. <target_filename> may be the string "-" to mean 490 // "the same as <source_filename>". 491 // 492 // - Otherwise, or if any error is encountered, exits with non-zero status. 493 // 494 // <source_filename> must refer to an EMMC partition to read the source data. See the comments for 495 // the LoadPartitionContents() function above for the format of such a filename. <target_size> has 496 // become obsolete since we have dropped the support for patching non-EMMC targets (EMMC targets 497 // have the size embedded in the filename). 498 int applypatch(const char* source_filename, const char* target_filename, 499 const char* target_sha1_str, size_t target_size __unused, 500 const std::vector<std::string>& patch_sha1_str, 501 const std::vector<std::unique_ptr<Value>>& patch_data, const Value* bonus_data) { 502 printf("patch %s: ", source_filename); 503 504 if (target_filename[0] == '-' && target_filename[1] == '\0') { 505 target_filename = source_filename; 506 } 507 508 if (strncmp(target_filename, "EMMC:", 5) != 0) { 509 printf("Supporting patching EMMC targets only.\n"); 510 return 1; 511 } 512 513 uint8_t target_sha1[SHA_DIGEST_LENGTH]; 514 if (ParseSha1(target_sha1_str, target_sha1) != 0) { 515 printf("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str); 516 return 1; 517 } 518 519 // We try to load the target file into the source_file object. 520 FileContents source_file; 521 if (LoadFileContents(target_filename, &source_file) == 0) { 522 if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_LENGTH) == 0) { 523 // The early-exit case: the patch was already applied, this file has the desired hash, nothing 524 // for us to do. 525 printf("already %s\n", short_sha1(target_sha1).c_str()); 526 return 0; 527 } 528 } 529 530 if (source_file.data.empty() || 531 (target_filename != source_filename && strcmp(target_filename, source_filename) != 0)) { 532 // Need to load the source file: either we failed to load the target file, or we did but it's 533 // different from the expected. 534 source_file.data.clear(); 535 LoadFileContents(source_filename, &source_file); 536 } 537 538 if (!source_file.data.empty()) { 539 int to_use = FindMatchingPatch(source_file.sha1, patch_sha1_str); 540 if (to_use != -1) { 541 return GenerateTarget(source_file, patch_data[to_use], target_filename, target_sha1, 542 bonus_data); 543 } 544 } 545 546 printf("source file is bad; trying copy\n"); 547 548 FileContents copy_file; 549 if (LoadFileContents(CACHE_TEMP_SOURCE, ©_file) < 0) { 550 printf("failed to read copy file\n"); 551 return 1; 552 } 553 554 int to_use = FindMatchingPatch(copy_file.sha1, patch_sha1_str); 555 if (to_use == -1) { 556 printf("copy file doesn't match source SHA-1s either\n"); 557 return 1; 558 } 559 560 return GenerateTarget(copy_file, patch_data[to_use], target_filename, target_sha1, bonus_data); 561 } 562 563 /* 564 * This function flashes a given image to the target partition. It verifies 565 * the target cheksum first, and will return if target has the desired hash. 566 * It checks the checksum of the given source image before flashing, and 567 * verifies the target partition afterwards. The function is idempotent. 568 * Returns zero on success. 569 */ 570 int applypatch_flash(const char* source_filename, const char* target_filename, 571 const char* target_sha1_str, size_t target_size) { 572 printf("flash %s: ", target_filename); 573 574 uint8_t target_sha1[SHA_DIGEST_LENGTH]; 575 if (ParseSha1(target_sha1_str, target_sha1) != 0) { 576 printf("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str); 577 return 1; 578 } 579 580 std::string target_str(target_filename); 581 std::vector<std::string> pieces = android::base::Split(target_str, ":"); 582 if (pieces.size() != 2 || pieces[0] != "EMMC") { 583 printf("invalid target name \"%s\"", target_filename); 584 return 1; 585 } 586 587 // Load the target into the source_file object to see if already applied. 588 pieces.push_back(std::to_string(target_size)); 589 pieces.push_back(target_sha1_str); 590 std::string fullname = android::base::Join(pieces, ':'); 591 FileContents source_file; 592 if (LoadPartitionContents(fullname, &source_file) == 0 && 593 memcmp(source_file.sha1, target_sha1, SHA_DIGEST_LENGTH) == 0) { 594 // The early-exit case: the image was already applied, this partition 595 // has the desired hash, nothing for us to do. 596 printf("already %s\n", short_sha1(target_sha1).c_str()); 597 return 0; 598 } 599 600 if (LoadFileContents(source_filename, &source_file) == 0) { 601 if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_LENGTH) != 0) { 602 // The source doesn't have desired checksum. 603 printf("source \"%s\" doesn't have expected sha1 sum\n", source_filename); 604 printf("expected: %s, found: %s\n", short_sha1(target_sha1).c_str(), 605 short_sha1(source_file.sha1).c_str()); 606 return 1; 607 } 608 } 609 610 if (WriteToPartition(source_file.data.data(), target_size, target_filename) != 0) { 611 printf("write of copied data to %s failed\n", target_filename); 612 return 1; 613 } 614 return 0; 615 } 616 617 static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch, 618 const std::string& target_filename, 619 const uint8_t target_sha1[SHA_DIGEST_LENGTH], const Value* bonus_data) { 620 if (patch->type != VAL_BLOB) { 621 printf("patch is not a blob\n"); 622 return 1; 623 } 624 625 const char* header = &patch->data[0]; 626 size_t header_bytes_read = patch->data.size(); 627 bool use_bsdiff = false; 628 if (header_bytes_read >= 8 && memcmp(header, "BSDIFF40", 8) == 0) { 629 use_bsdiff = true; 630 } else if (header_bytes_read >= 8 && memcmp(header, "IMGDIFF2", 8) == 0) { 631 use_bsdiff = false; 632 } else { 633 printf("Unknown patch file format\n"); 634 return 1; 635 } 636 637 CHECK(android::base::StartsWith(target_filename, "EMMC:")); 638 639 // We still write the original source to cache, in case the partition write is interrupted. 640 if (MakeFreeSpaceOnCache(source_file.data.size()) < 0) { 641 printf("not enough free space on /cache\n"); 642 return 1; 643 } 644 if (SaveFileContents(CACHE_TEMP_SOURCE, &source_file) < 0) { 645 printf("failed to back up source file\n"); 646 return 1; 647 } 648 649 // We store the decoded output in memory. 650 SinkFn sink = MemorySink; 651 std::string memory_sink_str; // Don't need to reserve space. 652 void* token = &memory_sink_str; 653 654 SHA_CTX ctx; 655 SHA1_Init(&ctx); 656 657 int result; 658 if (use_bsdiff) { 659 result = ApplyBSDiffPatch(source_file.data.data(), source_file.data.size(), patch.get(), 0, 660 sink, token, &ctx); 661 } else { 662 result = ApplyImagePatch(source_file.data.data(), source_file.data.size(), patch.get(), sink, 663 token, &ctx, bonus_data); 664 } 665 666 if (result != 0) { 667 printf("applying patch failed\n"); 668 return 1; 669 } 670 671 uint8_t current_target_sha1[SHA_DIGEST_LENGTH]; 672 SHA1_Final(current_target_sha1, &ctx); 673 if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_LENGTH) != 0) { 674 printf("patch did not produce expected sha1\n"); 675 return 1; 676 } else { 677 printf("now %s\n", short_sha1(target_sha1).c_str()); 678 } 679 680 // Write back the temp file to the partition. 681 if (WriteToPartition(reinterpret_cast<const unsigned char*>(memory_sink_str.c_str()), 682 memory_sink_str.size(), target_filename) != 0) { 683 printf("write of patched data to %s failed\n", target_filename.c_str()); 684 return 1; 685 } 686 687 // Delete the backup copy of the source. 688 unlink(CACHE_TEMP_SOURCE); 689 690 // Success! 691 return 0; 692 } 693