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