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 <ctype.h> 18 #include <dirent.h> 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <inttypes.h> 22 #include <linux/fs.h> 23 #include <pthread.h> 24 #include <stdarg.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <sys/ioctl.h> 29 #include <sys/stat.h> 30 #include <sys/types.h> 31 #include <sys/wait.h> 32 #include <time.h> 33 #include <unistd.h> 34 35 #include <functional> 36 #include <limits> 37 #include <memory> 38 #include <string> 39 #include <unordered_map> 40 #include <vector> 41 42 #include <android-base/file.h> 43 #include <android-base/logging.h> 44 #include <android-base/parseint.h> 45 #include <android-base/strings.h> 46 #include <android-base/unique_fd.h> 47 #include <applypatch/applypatch.h> 48 #include <brotli/decode.h> 49 #include <fec/io.h> 50 #include <openssl/sha.h> 51 #include <private/android_filesystem_config.h> 52 #include <verity/hash_tree_builder.h> 53 #include <ziparchive/zip_archive.h> 54 55 #include "edify/expr.h" 56 #include "otautil/dirutil.h" 57 #include "otautil/error_code.h" 58 #include "otautil/paths.h" 59 #include "otautil/print_sha1.h" 60 #include "otautil/rangeset.h" 61 #include "private/commands.h" 62 #include "updater/install.h" 63 #include "updater/updater.h" 64 65 // Set this to 0 to interpret 'erase' transfers to mean do a 66 // BLKDISCARD ioctl (the normal behavior). Set to 1 to interpret 67 // erase to mean fill the region with zeroes. 68 #define DEBUG_ERASE 0 69 70 static constexpr size_t BLOCKSIZE = 4096; 71 static constexpr mode_t STASH_DIRECTORY_MODE = 0700; 72 static constexpr mode_t STASH_FILE_MODE = 0600; 73 static constexpr mode_t MARKER_DIRECTORY_MODE = 0700; 74 75 static CauseCode failure_type = kNoCause; 76 static bool is_retry = false; 77 static std::unordered_map<std::string, RangeSet> stash_map; 78 79 static void DeleteLastCommandFile() { 80 const std::string& last_command_file = Paths::Get().last_command_file(); 81 if (unlink(last_command_file.c_str()) == -1 && errno != ENOENT) { 82 PLOG(ERROR) << "Failed to unlink: " << last_command_file; 83 } 84 } 85 86 // Parse the last command index of the last update and save the result to |last_command_index|. 87 // Return true if we successfully read the index. 88 static bool ParseLastCommandFile(size_t* last_command_index) { 89 const std::string& last_command_file = Paths::Get().last_command_file(); 90 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(last_command_file.c_str(), O_RDONLY))); 91 if (fd == -1) { 92 if (errno != ENOENT) { 93 PLOG(ERROR) << "Failed to open " << last_command_file; 94 return false; 95 } 96 97 LOG(INFO) << last_command_file << " doesn't exist."; 98 return false; 99 } 100 101 // Now that the last_command file exists, parse the last command index of previous update. 102 std::string content; 103 if (!android::base::ReadFdToString(fd.get(), &content)) { 104 LOG(ERROR) << "Failed to read: " << last_command_file; 105 return false; 106 } 107 108 std::vector<std::string> lines = android::base::Split(android::base::Trim(content), "\n"); 109 if (lines.size() != 2) { 110 LOG(ERROR) << "Unexpected line counts in last command file: " << content; 111 return false; 112 } 113 114 if (!android::base::ParseUint(lines[0], last_command_index)) { 115 LOG(ERROR) << "Failed to parse integer in: " << lines[0]; 116 return false; 117 } 118 119 return true; 120 } 121 122 static bool FsyncDir(const std::string& dirname) { 123 android::base::unique_fd dfd(TEMP_FAILURE_RETRY(open(dirname.c_str(), O_RDONLY | O_DIRECTORY))); 124 if (dfd == -1) { 125 failure_type = errno == EIO ? kEioFailure : kFileOpenFailure; 126 PLOG(ERROR) << "Failed to open " << dirname; 127 return false; 128 } 129 if (fsync(dfd) == -1) { 130 failure_type = errno == EIO ? kEioFailure : kFsyncFailure; 131 PLOG(ERROR) << "Failed to fsync " << dirname; 132 return false; 133 } 134 return true; 135 } 136 137 // Update the last executed command index in the last_command_file. 138 static bool UpdateLastCommandIndex(size_t command_index, const std::string& command_string) { 139 const std::string& last_command_file = Paths::Get().last_command_file(); 140 std::string last_command_tmp = last_command_file + ".tmp"; 141 std::string content = std::to_string(command_index) + "\n" + command_string; 142 android::base::unique_fd wfd( 143 TEMP_FAILURE_RETRY(open(last_command_tmp.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0660))); 144 if (wfd == -1 || !android::base::WriteStringToFd(content, wfd)) { 145 PLOG(ERROR) << "Failed to update last command"; 146 return false; 147 } 148 149 if (fsync(wfd) == -1) { 150 PLOG(ERROR) << "Failed to fsync " << last_command_tmp; 151 return false; 152 } 153 154 if (chown(last_command_tmp.c_str(), AID_SYSTEM, AID_SYSTEM) == -1) { 155 PLOG(ERROR) << "Failed to change owner for " << last_command_tmp; 156 return false; 157 } 158 159 if (rename(last_command_tmp.c_str(), last_command_file.c_str()) == -1) { 160 PLOG(ERROR) << "Failed to rename" << last_command_tmp; 161 return false; 162 } 163 164 if (!FsyncDir(android::base::Dirname(last_command_file))) { 165 return false; 166 } 167 168 return true; 169 } 170 171 bool SetUpdatedMarker(const std::string& marker) { 172 auto dirname = android::base::Dirname(marker); 173 auto res = mkdir(dirname.c_str(), MARKER_DIRECTORY_MODE); 174 if (res == -1 && errno != EEXIST) { 175 PLOG(ERROR) << "Failed to create directory for marker: " << dirname; 176 return false; 177 } 178 179 if (!android::base::WriteStringToFile("", marker)) { 180 PLOG(ERROR) << "Failed to write to marker file " << marker; 181 return false; 182 } 183 if (!FsyncDir(dirname)) { 184 return false; 185 } 186 LOG(INFO) << "Wrote updated marker to " << marker; 187 return true; 188 } 189 190 static bool discard_blocks(int fd, off64_t offset, uint64_t size, bool force = false) { 191 // Don't discard blocks unless the update is a retry run or force == true 192 if (!is_retry && !force) { 193 return true; 194 } 195 196 uint64_t args[2] = { static_cast<uint64_t>(offset), size }; 197 if (ioctl(fd, BLKDISCARD, &args) == -1) { 198 // On devices that does not support BLKDISCARD, ignore the error. 199 if (errno == EOPNOTSUPP) { 200 return true; 201 } 202 PLOG(ERROR) << "BLKDISCARD ioctl failed"; 203 return false; 204 } 205 return true; 206 } 207 208 static bool check_lseek(int fd, off64_t offset, int whence) { 209 off64_t rc = TEMP_FAILURE_RETRY(lseek64(fd, offset, whence)); 210 if (rc == -1) { 211 failure_type = kLseekFailure; 212 PLOG(ERROR) << "lseek64 failed"; 213 return false; 214 } 215 return true; 216 } 217 218 static void allocate(size_t size, std::vector<uint8_t>* buffer) { 219 // If the buffer's big enough, reuse it. 220 if (size <= buffer->size()) return; 221 buffer->resize(size); 222 } 223 224 /** 225 * RangeSinkWriter reads data from the given FD, and writes them to the destination specified by the 226 * given RangeSet. 227 */ 228 class RangeSinkWriter { 229 public: 230 RangeSinkWriter(int fd, const RangeSet& tgt) 231 : fd_(fd), 232 tgt_(tgt), 233 next_range_(0), 234 current_range_left_(0), 235 bytes_written_(0) { 236 CHECK_NE(tgt.size(), static_cast<size_t>(0)); 237 }; 238 239 bool Finished() const { 240 return next_range_ == tgt_.size() && current_range_left_ == 0; 241 } 242 243 size_t AvailableSpace() const { 244 return tgt_.blocks() * BLOCKSIZE - bytes_written_; 245 } 246 247 // Return number of bytes written; and 0 indicates a writing failure. 248 size_t Write(const uint8_t* data, size_t size) { 249 if (Finished()) { 250 LOG(ERROR) << "range sink write overrun; can't write " << size << " bytes"; 251 return 0; 252 } 253 254 size_t written = 0; 255 while (size > 0) { 256 // Move to the next range as needed. 257 if (!SeekToOutputRange()) { 258 break; 259 } 260 261 size_t write_now = size; 262 if (current_range_left_ < write_now) { 263 write_now = current_range_left_; 264 } 265 266 if (!android::base::WriteFully(fd_, data, write_now)) { 267 failure_type = errno == EIO ? kEioFailure : kFwriteFailure; 268 PLOG(ERROR) << "Failed to write " << write_now << " bytes of data"; 269 break; 270 } 271 272 data += write_now; 273 size -= write_now; 274 275 current_range_left_ -= write_now; 276 written += write_now; 277 } 278 279 bytes_written_ += written; 280 return written; 281 } 282 283 size_t BytesWritten() const { 284 return bytes_written_; 285 } 286 287 private: 288 // Set up the output cursor, move to next range if needed. 289 bool SeekToOutputRange() { 290 // We haven't finished the current range yet. 291 if (current_range_left_ != 0) { 292 return true; 293 } 294 // We can't write any more; let the write function return how many bytes have been written 295 // so far. 296 if (next_range_ >= tgt_.size()) { 297 return false; 298 } 299 300 const Range& range = tgt_[next_range_]; 301 off64_t offset = static_cast<off64_t>(range.first) * BLOCKSIZE; 302 current_range_left_ = (range.second - range.first) * BLOCKSIZE; 303 next_range_++; 304 305 if (!discard_blocks(fd_, offset, current_range_left_)) { 306 return false; 307 } 308 if (!check_lseek(fd_, offset, SEEK_SET)) { 309 return false; 310 } 311 return true; 312 } 313 314 // The output file descriptor. 315 int fd_; 316 // The destination ranges for the data. 317 const RangeSet& tgt_; 318 // The next range that we should write to. 319 size_t next_range_; 320 // The number of bytes to write before moving to the next range. 321 size_t current_range_left_; 322 // Total bytes written by the writer. 323 size_t bytes_written_; 324 }; 325 326 /** 327 * All of the data for all the 'new' transfers is contained in one file in the update package, 328 * concatenated together in the order in which transfers.list will need it. We want to stream it out 329 * of the archive (it's compressed) without writing it to a temp file, but we can't write each 330 * section until it's that transfer's turn to go. 331 * 332 * To achieve this, we expand the new data from the archive in a background thread, and block that 333 * threads 'receive uncompressed data' function until the main thread has reached a point where we 334 * want some new data to be written. We signal the background thread with the destination for the 335 * data and block the main thread, waiting for the background thread to complete writing that 336 * section. Then it signals the main thread to wake up and goes back to blocking waiting for a 337 * transfer. 338 * 339 * NewThreadInfo is the struct used to pass information back and forth between the two threads. When 340 * the main thread wants some data written, it sets writer to the destination location and signals 341 * the condition. When the background thread is done writing, it clears writer and signals the 342 * condition again. 343 */ 344 struct NewThreadInfo { 345 ZipArchiveHandle za; 346 ZipEntry entry; 347 bool brotli_compressed; 348 349 std::unique_ptr<RangeSinkWriter> writer; 350 BrotliDecoderState* brotli_decoder_state; 351 bool receiver_available; 352 353 pthread_mutex_t mu; 354 pthread_cond_t cv; 355 }; 356 357 static bool receive_new_data(const uint8_t* data, size_t size, void* cookie) { 358 NewThreadInfo* nti = static_cast<NewThreadInfo*>(cookie); 359 360 while (size > 0) { 361 // Wait for nti->writer to be non-null, indicating some of this data is wanted. 362 pthread_mutex_lock(&nti->mu); 363 while (nti->writer == nullptr) { 364 // End the new data receiver if we encounter an error when performing block image update. 365 if (!nti->receiver_available) { 366 pthread_mutex_unlock(&nti->mu); 367 return false; 368 } 369 pthread_cond_wait(&nti->cv, &nti->mu); 370 } 371 pthread_mutex_unlock(&nti->mu); 372 373 // At this point nti->writer is set, and we own it. The main thread is waiting for it to 374 // disappear from nti. 375 size_t write_now = std::min(size, nti->writer->AvailableSpace()); 376 if (nti->writer->Write(data, write_now) != write_now) { 377 LOG(ERROR) << "Failed to write " << write_now << " bytes."; 378 return false; 379 } 380 381 data += write_now; 382 size -= write_now; 383 384 if (nti->writer->Finished()) { 385 // We have written all the bytes desired by this writer. 386 387 pthread_mutex_lock(&nti->mu); 388 nti->writer = nullptr; 389 pthread_cond_broadcast(&nti->cv); 390 pthread_mutex_unlock(&nti->mu); 391 } 392 } 393 394 return true; 395 } 396 397 static bool receive_brotli_new_data(const uint8_t* data, size_t size, void* cookie) { 398 NewThreadInfo* nti = static_cast<NewThreadInfo*>(cookie); 399 400 while (size > 0 || BrotliDecoderHasMoreOutput(nti->brotli_decoder_state)) { 401 // Wait for nti->writer to be non-null, indicating some of this data is wanted. 402 pthread_mutex_lock(&nti->mu); 403 while (nti->writer == nullptr) { 404 // End the receiver if we encounter an error when performing block image update. 405 if (!nti->receiver_available) { 406 pthread_mutex_unlock(&nti->mu); 407 return false; 408 } 409 pthread_cond_wait(&nti->cv, &nti->mu); 410 } 411 pthread_mutex_unlock(&nti->mu); 412 413 // At this point nti->writer is set, and we own it. The main thread is waiting for it to 414 // disappear from nti. 415 416 size_t buffer_size = std::min<size_t>(32768, nti->writer->AvailableSpace()); 417 if (buffer_size == 0) { 418 LOG(ERROR) << "No space left in output range"; 419 return false; 420 } 421 uint8_t buffer[buffer_size]; 422 size_t available_in = size; 423 size_t available_out = buffer_size; 424 uint8_t* next_out = buffer; 425 426 // The brotli decoder will update |data|, |available_in|, |next_out| and |available_out|. 427 BrotliDecoderResult result = BrotliDecoderDecompressStream( 428 nti->brotli_decoder_state, &available_in, &data, &available_out, &next_out, nullptr); 429 430 if (result == BROTLI_DECODER_RESULT_ERROR) { 431 LOG(ERROR) << "Decompression failed with " 432 << BrotliDecoderErrorString(BrotliDecoderGetErrorCode(nti->brotli_decoder_state)); 433 return false; 434 } 435 436 LOG(DEBUG) << "bytes to write: " << buffer_size - available_out << ", bytes consumed " 437 << size - available_in << ", decoder status " << result; 438 439 size_t write_now = buffer_size - available_out; 440 if (nti->writer->Write(buffer, write_now) != write_now) { 441 LOG(ERROR) << "Failed to write " << write_now << " bytes."; 442 return false; 443 } 444 445 // Update the remaining size. The input data ptr is already updated by brotli decoder function. 446 size = available_in; 447 448 if (nti->writer->Finished()) { 449 // We have written all the bytes desired by this writer. 450 451 pthread_mutex_lock(&nti->mu); 452 nti->writer = nullptr; 453 pthread_cond_broadcast(&nti->cv); 454 pthread_mutex_unlock(&nti->mu); 455 } 456 } 457 458 return true; 459 } 460 461 static void* unzip_new_data(void* cookie) { 462 NewThreadInfo* nti = static_cast<NewThreadInfo*>(cookie); 463 if (nti->brotli_compressed) { 464 ProcessZipEntryContents(nti->za, &nti->entry, receive_brotli_new_data, nti); 465 } else { 466 ProcessZipEntryContents(nti->za, &nti->entry, receive_new_data, nti); 467 } 468 pthread_mutex_lock(&nti->mu); 469 nti->receiver_available = false; 470 if (nti->writer != nullptr) { 471 pthread_cond_broadcast(&nti->cv); 472 } 473 pthread_mutex_unlock(&nti->mu); 474 return nullptr; 475 } 476 477 static int ReadBlocks(const RangeSet& src, std::vector<uint8_t>* buffer, int fd) { 478 size_t p = 0; 479 for (const auto& [begin, end] : src) { 480 if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { 481 return -1; 482 } 483 484 size_t size = (end - begin) * BLOCKSIZE; 485 if (!android::base::ReadFully(fd, buffer->data() + p, size)) { 486 failure_type = errno == EIO ? kEioFailure : kFreadFailure; 487 PLOG(ERROR) << "Failed to read " << size << " bytes of data"; 488 return -1; 489 } 490 491 p += size; 492 } 493 494 return 0; 495 } 496 497 static int WriteBlocks(const RangeSet& tgt, const std::vector<uint8_t>& buffer, int fd) { 498 size_t written = 0; 499 for (const auto& [begin, end] : tgt) { 500 off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; 501 size_t size = (end - begin) * BLOCKSIZE; 502 if (!discard_blocks(fd, offset, size)) { 503 return -1; 504 } 505 506 if (!check_lseek(fd, offset, SEEK_SET)) { 507 return -1; 508 } 509 510 if (!android::base::WriteFully(fd, buffer.data() + written, size)) { 511 failure_type = errno == EIO ? kEioFailure : kFwriteFailure; 512 PLOG(ERROR) << "Failed to write " << size << " bytes of data"; 513 return -1; 514 } 515 516 written += size; 517 } 518 519 return 0; 520 } 521 522 // Parameters for transfer list command functions 523 struct CommandParameters { 524 std::vector<std::string> tokens; 525 size_t cpos; 526 std::string cmdname; 527 std::string cmdline; 528 std::string freestash; 529 std::string stashbase; 530 bool canwrite; 531 int createdstash; 532 android::base::unique_fd fd; 533 bool foundwrites; 534 bool isunresumable; 535 int version; 536 size_t written; 537 size_t stashed; 538 NewThreadInfo nti; 539 pthread_t thread; 540 std::vector<uint8_t> buffer; 541 uint8_t* patch_start; 542 bool target_verified; // The target blocks have expected contents already. 543 }; 544 545 // Print the hash in hex for corrupted source blocks (excluding the stashed blocks which is 546 // handled separately). 547 static void PrintHashForCorruptedSourceBlocks(const CommandParameters& params, 548 const std::vector<uint8_t>& buffer) { 549 LOG(INFO) << "unexpected contents of source blocks in cmd:\n" << params.cmdline; 550 CHECK(params.tokens[0] == "move" || params.tokens[0] == "bsdiff" || 551 params.tokens[0] == "imgdiff"); 552 553 size_t pos = 0; 554 // Command example: 555 // move <onehash> <tgt_range> <src_blk_count> <src_range> [<loc_range> <stashed_blocks>] 556 // bsdiff <offset> <len> <src_hash> <tgt_hash> <tgt_range> <src_blk_count> <src_range> 557 // [<loc_range> <stashed_blocks>] 558 if (params.tokens[0] == "move") { 559 // src_range for move starts at the 4th position. 560 if (params.tokens.size() < 5) { 561 LOG(ERROR) << "failed to parse source range in cmd:\n" << params.cmdline; 562 return; 563 } 564 pos = 4; 565 } else { 566 // src_range for diff starts at the 7th position. 567 if (params.tokens.size() < 8) { 568 LOG(ERROR) << "failed to parse source range in cmd:\n" << params.cmdline; 569 return; 570 } 571 pos = 7; 572 } 573 574 // Source blocks in stash only, no work to do. 575 if (params.tokens[pos] == "-") { 576 return; 577 } 578 579 RangeSet src = RangeSet::Parse(params.tokens[pos++]); 580 if (!src) { 581 LOG(ERROR) << "Failed to parse range in " << params.cmdline; 582 return; 583 } 584 585 RangeSet locs; 586 // If there's no stashed blocks, content in the buffer is consecutive and has the same 587 // order as the source blocks. 588 if (pos == params.tokens.size()) { 589 locs = RangeSet(std::vector<Range>{ Range{ 0, src.blocks() } }); 590 } else { 591 // Otherwise, the next token is the offset of the source blocks in the target range. 592 // Example: for the tokens <4,63946,63947,63948,63979> <4,6,7,8,39> <stashed_blocks>; 593 // We want to print SHA-1 for the data in buffer[6], buffer[8], buffer[9] ... buffer[38]; 594 // this corresponds to the 32 src blocks #63946, #63948, #63949 ... #63978. 595 locs = RangeSet::Parse(params.tokens[pos++]); 596 CHECK_EQ(src.blocks(), locs.blocks()); 597 } 598 599 LOG(INFO) << "printing hash in hex for " << src.blocks() << " source blocks"; 600 for (size_t i = 0; i < src.blocks(); i++) { 601 size_t block_num = src.GetBlockNumber(i); 602 size_t buffer_index = locs.GetBlockNumber(i); 603 CHECK_LE((buffer_index + 1) * BLOCKSIZE, buffer.size()); 604 605 uint8_t digest[SHA_DIGEST_LENGTH]; 606 SHA1(buffer.data() + buffer_index * BLOCKSIZE, BLOCKSIZE, digest); 607 std::string hexdigest = print_sha1(digest); 608 LOG(INFO) << " block number: " << block_num << ", SHA-1: " << hexdigest; 609 } 610 } 611 612 // If the calculated hash for the whole stash doesn't match the stash id, print the SHA-1 613 // in hex for each block. 614 static void PrintHashForCorruptedStashedBlocks(const std::string& id, 615 const std::vector<uint8_t>& buffer, 616 const RangeSet& src) { 617 LOG(INFO) << "printing hash in hex for stash_id: " << id; 618 CHECK_EQ(src.blocks() * BLOCKSIZE, buffer.size()); 619 620 for (size_t i = 0; i < src.blocks(); i++) { 621 size_t block_num = src.GetBlockNumber(i); 622 623 uint8_t digest[SHA_DIGEST_LENGTH]; 624 SHA1(buffer.data() + i * BLOCKSIZE, BLOCKSIZE, digest); 625 std::string hexdigest = print_sha1(digest); 626 LOG(INFO) << " block number: " << block_num << ", SHA-1: " << hexdigest; 627 } 628 } 629 630 // If the stash file doesn't exist, read the source blocks this stash contains and print the 631 // SHA-1 for these blocks. 632 static void PrintHashForMissingStashedBlocks(const std::string& id, int fd) { 633 if (stash_map.find(id) == stash_map.end()) { 634 LOG(ERROR) << "No stash saved for id: " << id; 635 return; 636 } 637 638 LOG(INFO) << "print hash in hex for source blocks in missing stash: " << id; 639 const RangeSet& src = stash_map[id]; 640 std::vector<uint8_t> buffer(src.blocks() * BLOCKSIZE); 641 if (ReadBlocks(src, &buffer, fd) == -1) { 642 LOG(ERROR) << "failed to read source blocks for stash: " << id; 643 return; 644 } 645 PrintHashForCorruptedStashedBlocks(id, buffer, src); 646 } 647 648 static int VerifyBlocks(const std::string& expected, const std::vector<uint8_t>& buffer, 649 const size_t blocks, bool printerror) { 650 uint8_t digest[SHA_DIGEST_LENGTH]; 651 const uint8_t* data = buffer.data(); 652 653 SHA1(data, blocks * BLOCKSIZE, digest); 654 655 std::string hexdigest = print_sha1(digest); 656 657 if (hexdigest != expected) { 658 if (printerror) { 659 LOG(ERROR) << "failed to verify blocks (expected " << expected << ", read " << hexdigest 660 << ")"; 661 } 662 return -1; 663 } 664 665 return 0; 666 } 667 668 static std::string GetStashFileName(const std::string& base, const std::string& id, 669 const std::string& postfix) { 670 if (base.empty()) { 671 return ""; 672 } 673 std::string filename = Paths::Get().stash_directory_base() + "/" + base; 674 if (id.empty() && postfix.empty()) { 675 return filename; 676 } 677 return filename + "/" + id + postfix; 678 } 679 680 // Does a best effort enumeration of stash files. Ignores possible non-file items in the stash 681 // directory and continues despite of errors. Calls the 'callback' function for each file. 682 static void EnumerateStash(const std::string& dirname, 683 const std::function<void(const std::string&)>& callback) { 684 if (dirname.empty()) return; 685 686 std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(dirname.c_str()), closedir); 687 688 if (directory == nullptr) { 689 if (errno != ENOENT) { 690 PLOG(ERROR) << "opendir \"" << dirname << "\" failed"; 691 } 692 return; 693 } 694 695 dirent* item; 696 while ((item = readdir(directory.get())) != nullptr) { 697 if (item->d_type != DT_REG) continue; 698 callback(dirname + "/" + item->d_name); 699 } 700 } 701 702 // Deletes the stash directory and all files in it. Assumes that it only 703 // contains files. There is nothing we can do about unlikely, but possible 704 // errors, so they are merely logged. 705 static void DeleteFile(const std::string& fn) { 706 if (fn.empty()) return; 707 708 LOG(INFO) << "deleting " << fn; 709 710 if (unlink(fn.c_str()) == -1 && errno != ENOENT) { 711 PLOG(ERROR) << "unlink \"" << fn << "\" failed"; 712 } 713 } 714 715 static void DeleteStash(const std::string& base) { 716 if (base.empty()) return; 717 718 LOG(INFO) << "deleting stash " << base; 719 720 std::string dirname = GetStashFileName(base, "", ""); 721 EnumerateStash(dirname, DeleteFile); 722 723 if (rmdir(dirname.c_str()) == -1) { 724 if (errno != ENOENT && errno != ENOTDIR) { 725 PLOG(ERROR) << "rmdir \"" << dirname << "\" failed"; 726 } 727 } 728 } 729 730 static int LoadStash(const CommandParameters& params, const std::string& id, bool verify, 731 std::vector<uint8_t>* buffer, bool printnoent) { 732 // In verify mode, if source range_set was saved for the given hash, check contents in the source 733 // blocks first. If the check fails, search for the stashed files on /cache as usual. 734 if (!params.canwrite) { 735 if (stash_map.find(id) != stash_map.end()) { 736 const RangeSet& src = stash_map[id]; 737 allocate(src.blocks() * BLOCKSIZE, buffer); 738 739 if (ReadBlocks(src, buffer, params.fd) == -1) { 740 LOG(ERROR) << "failed to read source blocks in stash map."; 741 return -1; 742 } 743 if (VerifyBlocks(id, *buffer, src.blocks(), true) != 0) { 744 LOG(ERROR) << "failed to verify loaded source blocks in stash map."; 745 if (!is_retry) { 746 PrintHashForCorruptedStashedBlocks(id, *buffer, src); 747 } 748 return -1; 749 } 750 return 0; 751 } 752 } 753 754 std::string fn = GetStashFileName(params.stashbase, id, ""); 755 756 struct stat sb; 757 if (stat(fn.c_str(), &sb) == -1) { 758 if (errno != ENOENT || printnoent) { 759 PLOG(ERROR) << "stat \"" << fn << "\" failed"; 760 PrintHashForMissingStashedBlocks(id, params.fd); 761 } 762 return -1; 763 } 764 765 LOG(INFO) << " loading " << fn; 766 767 if ((sb.st_size % BLOCKSIZE) != 0) { 768 LOG(ERROR) << fn << " size " << sb.st_size << " not multiple of block size " << BLOCKSIZE; 769 return -1; 770 } 771 772 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY))); 773 if (fd == -1) { 774 failure_type = errno == EIO ? kEioFailure : kFileOpenFailure; 775 PLOG(ERROR) << "open \"" << fn << "\" failed"; 776 return -1; 777 } 778 779 allocate(sb.st_size, buffer); 780 781 if (!android::base::ReadFully(fd, buffer->data(), sb.st_size)) { 782 failure_type = errno == EIO ? kEioFailure : kFreadFailure; 783 PLOG(ERROR) << "Failed to read " << sb.st_size << " bytes of data"; 784 return -1; 785 } 786 787 size_t blocks = sb.st_size / BLOCKSIZE; 788 if (verify && VerifyBlocks(id, *buffer, blocks, true) != 0) { 789 LOG(ERROR) << "unexpected contents in " << fn; 790 if (stash_map.find(id) == stash_map.end()) { 791 LOG(ERROR) << "failed to find source blocks number for stash " << id 792 << " when executing command: " << params.cmdname; 793 } else { 794 const RangeSet& src = stash_map[id]; 795 PrintHashForCorruptedStashedBlocks(id, *buffer, src); 796 } 797 DeleteFile(fn); 798 return -1; 799 } 800 801 return 0; 802 } 803 804 static int WriteStash(const std::string& base, const std::string& id, int blocks, 805 const std::vector<uint8_t>& buffer, bool checkspace, bool* exists) { 806 if (base.empty()) { 807 return -1; 808 } 809 810 if (checkspace && !CheckAndFreeSpaceOnCache(blocks * BLOCKSIZE)) { 811 LOG(ERROR) << "not enough space to write stash"; 812 return -1; 813 } 814 815 std::string fn = GetStashFileName(base, id, ".partial"); 816 std::string cn = GetStashFileName(base, id, ""); 817 818 if (exists) { 819 struct stat sb; 820 int res = stat(cn.c_str(), &sb); 821 822 if (res == 0) { 823 // The file already exists and since the name is the hash of the contents, 824 // it's safe to assume the contents are identical (accidental hash collisions 825 // are unlikely) 826 LOG(INFO) << " skipping " << blocks << " existing blocks in " << cn; 827 *exists = true; 828 return 0; 829 } 830 831 *exists = false; 832 } 833 834 LOG(INFO) << " writing " << blocks << " blocks to " << cn; 835 836 android::base::unique_fd fd( 837 TEMP_FAILURE_RETRY(open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE))); 838 if (fd == -1) { 839 failure_type = errno == EIO ? kEioFailure : kFileOpenFailure; 840 PLOG(ERROR) << "failed to create \"" << fn << "\""; 841 return -1; 842 } 843 844 if (fchown(fd, AID_SYSTEM, AID_SYSTEM) != 0) { // system user 845 PLOG(ERROR) << "failed to chown \"" << fn << "\""; 846 return -1; 847 } 848 849 if (!android::base::WriteFully(fd, buffer.data(), blocks * BLOCKSIZE)) { 850 failure_type = errno == EIO ? kEioFailure : kFwriteFailure; 851 PLOG(ERROR) << "Failed to write " << blocks * BLOCKSIZE << " bytes of data"; 852 return -1; 853 } 854 855 if (fsync(fd) == -1) { 856 failure_type = errno == EIO ? kEioFailure : kFsyncFailure; 857 PLOG(ERROR) << "fsync \"" << fn << "\" failed"; 858 return -1; 859 } 860 861 if (rename(fn.c_str(), cn.c_str()) == -1) { 862 PLOG(ERROR) << "rename(\"" << fn << "\", \"" << cn << "\") failed"; 863 return -1; 864 } 865 866 std::string dname = GetStashFileName(base, "", ""); 867 if (!FsyncDir(dname)) { 868 return -1; 869 } 870 871 return 0; 872 } 873 874 // Creates a directory for storing stash files and checks if the /cache partition 875 // hash enough space for the expected amount of blocks we need to store. Returns 876 // >0 if we created the directory, zero if it existed already, and <0 of failure. 877 static int CreateStash(State* state, size_t maxblocks, const std::string& base) { 878 std::string dirname = GetStashFileName(base, "", ""); 879 struct stat sb; 880 int res = stat(dirname.c_str(), &sb); 881 if (res == -1 && errno != ENOENT) { 882 ErrorAbort(state, kStashCreationFailure, "stat \"%s\" failed: %s", dirname.c_str(), 883 strerror(errno)); 884 return -1; 885 } 886 887 size_t max_stash_size = maxblocks * BLOCKSIZE; 888 if (res == -1) { 889 LOG(INFO) << "creating stash " << dirname; 890 res = mkdir_recursively(dirname, STASH_DIRECTORY_MODE, false, nullptr); 891 892 if (res != 0) { 893 ErrorAbort(state, kStashCreationFailure, "mkdir \"%s\" failed: %s", dirname.c_str(), 894 strerror(errno)); 895 return -1; 896 } 897 898 if (chown(dirname.c_str(), AID_SYSTEM, AID_SYSTEM) != 0) { // system user 899 ErrorAbort(state, kStashCreationFailure, "chown \"%s\" failed: %s", dirname.c_str(), 900 strerror(errno)); 901 return -1; 902 } 903 904 if (!CheckAndFreeSpaceOnCache(max_stash_size)) { 905 ErrorAbort(state, kStashCreationFailure, "not enough space for stash (%zu needed)", 906 max_stash_size); 907 return -1; 908 } 909 910 return 1; // Created directory 911 } 912 913 LOG(INFO) << "using existing stash " << dirname; 914 915 // If the directory already exists, calculate the space already allocated to stash files and check 916 // if there's enough for all required blocks. Delete any partially completed stash files first. 917 EnumerateStash(dirname, [](const std::string& fn) { 918 if (android::base::EndsWith(fn, ".partial")) { 919 DeleteFile(fn); 920 } 921 }); 922 923 size_t existing = 0; 924 EnumerateStash(dirname, [&existing](const std::string& fn) { 925 if (fn.empty()) return; 926 struct stat sb; 927 if (stat(fn.c_str(), &sb) == -1) { 928 PLOG(ERROR) << "stat \"" << fn << "\" failed"; 929 return; 930 } 931 existing += static_cast<size_t>(sb.st_size); 932 }); 933 934 if (max_stash_size > existing) { 935 size_t needed = max_stash_size - existing; 936 if (!CheckAndFreeSpaceOnCache(needed)) { 937 ErrorAbort(state, kStashCreationFailure, "not enough space for stash (%zu more needed)", 938 needed); 939 return -1; 940 } 941 } 942 943 return 0; // Using existing directory 944 } 945 946 static int FreeStash(const std::string& base, const std::string& id) { 947 if (base.empty() || id.empty()) { 948 return -1; 949 } 950 951 DeleteFile(GetStashFileName(base, id, "")); 952 953 return 0; 954 } 955 956 // Source contains packed data, which we want to move to the locations given in locs in the dest 957 // buffer. source and dest may be the same buffer. 958 static void MoveRange(std::vector<uint8_t>& dest, const RangeSet& locs, 959 const std::vector<uint8_t>& source) { 960 const uint8_t* from = source.data(); 961 uint8_t* to = dest.data(); 962 size_t start = locs.blocks(); 963 // Must do the movement backward. 964 for (auto it = locs.crbegin(); it != locs.crend(); it++) { 965 size_t blocks = it->second - it->first; 966 start -= blocks; 967 memmove(to + (it->first * BLOCKSIZE), from + (start * BLOCKSIZE), blocks * BLOCKSIZE); 968 } 969 } 970 971 /** 972 * We expect to parse the remainder of the parameter tokens as one of: 973 * 974 * <src_block_count> <src_range> 975 * (loads data from source image only) 976 * 977 * <src_block_count> - <[stash_id:stash_range] ...> 978 * (loads data from stashes only) 979 * 980 * <src_block_count> <src_range> <src_loc> <[stash_id:stash_range] ...> 981 * (loads data from both source image and stashes) 982 * 983 * On return, params.buffer is filled with the loaded source data (rearranged and combined with 984 * stashed data as necessary). buffer may be reallocated if needed to accommodate the source data. 985 * tgt is the target RangeSet for detecting overlaps. Any stashes required are loaded using 986 * LoadStash. 987 */ 988 static int LoadSourceBlocks(CommandParameters& params, const RangeSet& tgt, size_t* src_blocks, 989 bool* overlap) { 990 CHECK(src_blocks != nullptr); 991 CHECK(overlap != nullptr); 992 993 // <src_block_count> 994 const std::string& token = params.tokens[params.cpos++]; 995 if (!android::base::ParseUint(token, src_blocks)) { 996 LOG(ERROR) << "invalid src_block_count \"" << token << "\""; 997 return -1; 998 } 999 1000 allocate(*src_blocks * BLOCKSIZE, ¶ms.buffer); 1001 1002 // "-" or <src_range> [<src_loc>] 1003 if (params.tokens[params.cpos] == "-") { 1004 // no source ranges, only stashes 1005 params.cpos++; 1006 } else { 1007 RangeSet src = RangeSet::Parse(params.tokens[params.cpos++]); 1008 CHECK(static_cast<bool>(src)); 1009 *overlap = src.Overlaps(tgt); 1010 1011 if (ReadBlocks(src, ¶ms.buffer, params.fd) == -1) { 1012 return -1; 1013 } 1014 1015 if (params.cpos >= params.tokens.size()) { 1016 // no stashes, only source range 1017 return 0; 1018 } 1019 1020 RangeSet locs = RangeSet::Parse(params.tokens[params.cpos++]); 1021 CHECK(static_cast<bool>(locs)); 1022 MoveRange(params.buffer, locs, params.buffer); 1023 } 1024 1025 // <[stash_id:stash_range]> 1026 while (params.cpos < params.tokens.size()) { 1027 // Each word is a an index into the stash table, a colon, and then a RangeSet describing where 1028 // in the source block that stashed data should go. 1029 std::vector<std::string> tokens = android::base::Split(params.tokens[params.cpos++], ":"); 1030 if (tokens.size() != 2) { 1031 LOG(ERROR) << "invalid parameter"; 1032 return -1; 1033 } 1034 1035 std::vector<uint8_t> stash; 1036 if (LoadStash(params, tokens[0], false, &stash, true) == -1) { 1037 // These source blocks will fail verification if used later, but we 1038 // will let the caller decide if this is a fatal failure 1039 LOG(ERROR) << "failed to load stash " << tokens[0]; 1040 continue; 1041 } 1042 1043 RangeSet locs = RangeSet::Parse(tokens[1]); 1044 CHECK(static_cast<bool>(locs)); 1045 MoveRange(params.buffer, locs, stash); 1046 } 1047 1048 return 0; 1049 } 1050 1051 /** 1052 * Do a source/target load for move/bsdiff/imgdiff in version 3. 1053 * 1054 * We expect to parse the remainder of the parameter tokens as one of: 1055 * 1056 * <tgt_range> <src_block_count> <src_range> 1057 * (loads data from source image only) 1058 * 1059 * <tgt_range> <src_block_count> - <[stash_id:stash_range] ...> 1060 * (loads data from stashes only) 1061 * 1062 * <tgt_range> <src_block_count> <src_range> <src_loc> <[stash_id:stash_range] ...> 1063 * (loads data from both source image and stashes) 1064 * 1065 * 'onehash' tells whether to expect separate source and targe block hashes, or if they are both the 1066 * same and only one hash should be expected. params.isunresumable will be set to true if block 1067 * verification fails in a way that the update cannot be resumed anymore. 1068 * 1069 * If the function is unable to load the necessary blocks or their contents don't match the hashes, 1070 * the return value is -1 and the command should be aborted. 1071 * 1072 * If the return value is 1, the command has already been completed according to the contents of the 1073 * target blocks, and should not be performed again. 1074 * 1075 * If the return value is 0, source blocks have expected content and the command can be performed. 1076 */ 1077 static int LoadSrcTgtVersion3(CommandParameters& params, RangeSet* tgt, size_t* src_blocks, 1078 bool onehash) { 1079 CHECK(src_blocks != nullptr); 1080 1081 if (params.cpos >= params.tokens.size()) { 1082 LOG(ERROR) << "missing source hash"; 1083 return -1; 1084 } 1085 1086 std::string srchash = params.tokens[params.cpos++]; 1087 std::string tgthash; 1088 1089 if (onehash) { 1090 tgthash = srchash; 1091 } else { 1092 if (params.cpos >= params.tokens.size()) { 1093 LOG(ERROR) << "missing target hash"; 1094 return -1; 1095 } 1096 tgthash = params.tokens[params.cpos++]; 1097 } 1098 1099 // At least it needs to provide three parameters: <tgt_range>, <src_block_count> and 1100 // "-"/<src_range>. 1101 if (params.cpos + 2 >= params.tokens.size()) { 1102 LOG(ERROR) << "invalid parameters"; 1103 return -1; 1104 } 1105 1106 // <tgt_range> 1107 *tgt = RangeSet::Parse(params.tokens[params.cpos++]); 1108 CHECK(static_cast<bool>(*tgt)); 1109 1110 std::vector<uint8_t> tgtbuffer(tgt->blocks() * BLOCKSIZE); 1111 if (ReadBlocks(*tgt, &tgtbuffer, params.fd) == -1) { 1112 return -1; 1113 } 1114 1115 // Return now if target blocks already have expected content. 1116 if (VerifyBlocks(tgthash, tgtbuffer, tgt->blocks(), false) == 0) { 1117 return 1; 1118 } 1119 1120 // Load source blocks. 1121 bool overlap = false; 1122 if (LoadSourceBlocks(params, *tgt, src_blocks, &overlap) == -1) { 1123 return -1; 1124 } 1125 1126 if (VerifyBlocks(srchash, params.buffer, *src_blocks, true) == 0) { 1127 // If source and target blocks overlap, stash the source blocks so we can resume from possible 1128 // write errors. In verify mode, we can skip stashing because the source blocks won't be 1129 // overwritten. 1130 if (overlap && params.canwrite) { 1131 LOG(INFO) << "stashing " << *src_blocks << " overlapping blocks to " << srchash; 1132 1133 bool stash_exists = false; 1134 if (WriteStash(params.stashbase, srchash, *src_blocks, params.buffer, true, 1135 &stash_exists) != 0) { 1136 LOG(ERROR) << "failed to stash overlapping source blocks"; 1137 return -1; 1138 } 1139 1140 params.stashed += *src_blocks; 1141 // Can be deleted when the write has completed. 1142 if (!stash_exists) { 1143 params.freestash = srchash; 1144 } 1145 } 1146 1147 // Source blocks have expected content, command can proceed. 1148 return 0; 1149 } 1150 1151 if (overlap && LoadStash(params, srchash, true, ¶ms.buffer, true) == 0) { 1152 // Overlapping source blocks were previously stashed, command can proceed. We are recovering 1153 // from an interrupted command, so we don't know if the stash can safely be deleted after this 1154 // command. 1155 return 0; 1156 } 1157 1158 // Valid source data not available, update cannot be resumed. 1159 LOG(ERROR) << "partition has unexpected contents"; 1160 PrintHashForCorruptedSourceBlocks(params, params.buffer); 1161 1162 params.isunresumable = true; 1163 1164 return -1; 1165 } 1166 1167 static int PerformCommandMove(CommandParameters& params) { 1168 size_t blocks = 0; 1169 RangeSet tgt; 1170 int status = LoadSrcTgtVersion3(params, &tgt, &blocks, true); 1171 1172 if (status == -1) { 1173 LOG(ERROR) << "failed to read blocks for move"; 1174 return -1; 1175 } 1176 1177 if (status == 0) { 1178 params.foundwrites = true; 1179 } else { 1180 params.target_verified = true; 1181 if (params.foundwrites) { 1182 LOG(WARNING) << "warning: commands executed out of order [" << params.cmdname << "]"; 1183 } 1184 } 1185 1186 if (params.canwrite) { 1187 if (status == 0) { 1188 LOG(INFO) << " moving " << blocks << " blocks"; 1189 1190 if (WriteBlocks(tgt, params.buffer, params.fd) == -1) { 1191 return -1; 1192 } 1193 } else { 1194 LOG(INFO) << "skipping " << blocks << " already moved blocks"; 1195 } 1196 } 1197 1198 if (!params.freestash.empty()) { 1199 FreeStash(params.stashbase, params.freestash); 1200 params.freestash.clear(); 1201 } 1202 1203 params.written += tgt.blocks(); 1204 1205 return 0; 1206 } 1207 1208 static int PerformCommandStash(CommandParameters& params) { 1209 // <stash_id> <src_range> 1210 if (params.cpos + 1 >= params.tokens.size()) { 1211 LOG(ERROR) << "missing id and/or src range fields in stash command"; 1212 return -1; 1213 } 1214 1215 const std::string& id = params.tokens[params.cpos++]; 1216 if (LoadStash(params, id, true, ¶ms.buffer, false) == 0) { 1217 // Stash file already exists and has expected contents. Do not read from source again, as the 1218 // source may have been already overwritten during a previous attempt. 1219 return 0; 1220 } 1221 1222 RangeSet src = RangeSet::Parse(params.tokens[params.cpos++]); 1223 CHECK(static_cast<bool>(src)); 1224 1225 size_t blocks = src.blocks(); 1226 allocate(blocks * BLOCKSIZE, ¶ms.buffer); 1227 if (ReadBlocks(src, ¶ms.buffer, params.fd) == -1) { 1228 return -1; 1229 } 1230 stash_map[id] = src; 1231 1232 if (VerifyBlocks(id, params.buffer, blocks, true) != 0) { 1233 // Source blocks have unexpected contents. If we actually need this data later, this is an 1234 // unrecoverable error. However, the command that uses the data may have already completed 1235 // previously, so the possible failure will occur during source block verification. 1236 LOG(ERROR) << "failed to load source blocks for stash " << id; 1237 return 0; 1238 } 1239 1240 // In verify mode, we don't need to stash any blocks. 1241 if (!params.canwrite) { 1242 return 0; 1243 } 1244 1245 LOG(INFO) << "stashing " << blocks << " blocks to " << id; 1246 int result = WriteStash(params.stashbase, id, blocks, params.buffer, false, nullptr); 1247 if (result == 0) { 1248 params.stashed += blocks; 1249 } 1250 return result; 1251 } 1252 1253 static int PerformCommandFree(CommandParameters& params) { 1254 // <stash_id> 1255 if (params.cpos >= params.tokens.size()) { 1256 LOG(ERROR) << "missing stash id in free command"; 1257 return -1; 1258 } 1259 1260 const std::string& id = params.tokens[params.cpos++]; 1261 stash_map.erase(id); 1262 1263 if (params.createdstash || params.canwrite) { 1264 return FreeStash(params.stashbase, id); 1265 } 1266 1267 return 0; 1268 } 1269 1270 static int PerformCommandZero(CommandParameters& params) { 1271 if (params.cpos >= params.tokens.size()) { 1272 LOG(ERROR) << "missing target blocks for zero"; 1273 return -1; 1274 } 1275 1276 RangeSet tgt = RangeSet::Parse(params.tokens[params.cpos++]); 1277 CHECK(static_cast<bool>(tgt)); 1278 1279 LOG(INFO) << " zeroing " << tgt.blocks() << " blocks"; 1280 1281 allocate(BLOCKSIZE, ¶ms.buffer); 1282 memset(params.buffer.data(), 0, BLOCKSIZE); 1283 1284 if (params.canwrite) { 1285 for (const auto& [begin, end] : tgt) { 1286 off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; 1287 size_t size = (end - begin) * BLOCKSIZE; 1288 if (!discard_blocks(params.fd, offset, size)) { 1289 return -1; 1290 } 1291 1292 if (!check_lseek(params.fd, offset, SEEK_SET)) { 1293 return -1; 1294 } 1295 1296 for (size_t j = begin; j < end; ++j) { 1297 if (!android::base::WriteFully(params.fd, params.buffer.data(), BLOCKSIZE)) { 1298 failure_type = errno == EIO ? kEioFailure : kFwriteFailure; 1299 PLOG(ERROR) << "Failed to write " << BLOCKSIZE << " bytes of data"; 1300 return -1; 1301 } 1302 } 1303 } 1304 } 1305 1306 if (params.cmdname[0] == 'z') { 1307 // Update only for the zero command, as the erase command will call 1308 // this if DEBUG_ERASE is defined. 1309 params.written += tgt.blocks(); 1310 } 1311 1312 return 0; 1313 } 1314 1315 static int PerformCommandNew(CommandParameters& params) { 1316 if (params.cpos >= params.tokens.size()) { 1317 LOG(ERROR) << "missing target blocks for new"; 1318 return -1; 1319 } 1320 1321 RangeSet tgt = RangeSet::Parse(params.tokens[params.cpos++]); 1322 CHECK(static_cast<bool>(tgt)); 1323 1324 if (params.canwrite) { 1325 LOG(INFO) << " writing " << tgt.blocks() << " blocks of new data"; 1326 1327 pthread_mutex_lock(¶ms.nti.mu); 1328 params.nti.writer = std::make_unique<RangeSinkWriter>(params.fd, tgt); 1329 pthread_cond_broadcast(¶ms.nti.cv); 1330 1331 while (params.nti.writer != nullptr) { 1332 if (!params.nti.receiver_available) { 1333 LOG(ERROR) << "missing " << (tgt.blocks() * BLOCKSIZE - params.nti.writer->BytesWritten()) 1334 << " bytes of new data"; 1335 pthread_mutex_unlock(¶ms.nti.mu); 1336 return -1; 1337 } 1338 pthread_cond_wait(¶ms.nti.cv, ¶ms.nti.mu); 1339 } 1340 1341 pthread_mutex_unlock(¶ms.nti.mu); 1342 } 1343 1344 params.written += tgt.blocks(); 1345 1346 return 0; 1347 } 1348 1349 static int PerformCommandDiff(CommandParameters& params) { 1350 // <offset> <length> 1351 if (params.cpos + 1 >= params.tokens.size()) { 1352 LOG(ERROR) << "missing patch offset or length for " << params.cmdname; 1353 return -1; 1354 } 1355 1356 size_t offset; 1357 if (!android::base::ParseUint(params.tokens[params.cpos++], &offset)) { 1358 LOG(ERROR) << "invalid patch offset"; 1359 return -1; 1360 } 1361 1362 size_t len; 1363 if (!android::base::ParseUint(params.tokens[params.cpos++], &len)) { 1364 LOG(ERROR) << "invalid patch len"; 1365 return -1; 1366 } 1367 1368 RangeSet tgt; 1369 size_t blocks = 0; 1370 int status = LoadSrcTgtVersion3(params, &tgt, &blocks, false); 1371 1372 if (status == -1) { 1373 LOG(ERROR) << "failed to read blocks for diff"; 1374 return -1; 1375 } 1376 1377 if (status == 0) { 1378 params.foundwrites = true; 1379 } else { 1380 params.target_verified = true; 1381 if (params.foundwrites) { 1382 LOG(WARNING) << "warning: commands executed out of order [" << params.cmdname << "]"; 1383 } 1384 } 1385 1386 if (params.canwrite) { 1387 if (status == 0) { 1388 LOG(INFO) << "patching " << blocks << " blocks to " << tgt.blocks(); 1389 Value patch_value( 1390 Value::Type::BLOB, 1391 std::string(reinterpret_cast<const char*>(params.patch_start + offset), len)); 1392 1393 RangeSinkWriter writer(params.fd, tgt); 1394 if (params.cmdname[0] == 'i') { // imgdiff 1395 if (ApplyImagePatch(params.buffer.data(), blocks * BLOCKSIZE, patch_value, 1396 std::bind(&RangeSinkWriter::Write, &writer, std::placeholders::_1, 1397 std::placeholders::_2), 1398 nullptr) != 0) { 1399 LOG(ERROR) << "Failed to apply image patch."; 1400 failure_type = kPatchApplicationFailure; 1401 return -1; 1402 } 1403 } else { 1404 if (ApplyBSDiffPatch(params.buffer.data(), blocks * BLOCKSIZE, patch_value, 0, 1405 std::bind(&RangeSinkWriter::Write, &writer, std::placeholders::_1, 1406 std::placeholders::_2)) != 0) { 1407 LOG(ERROR) << "Failed to apply bsdiff patch."; 1408 failure_type = kPatchApplicationFailure; 1409 return -1; 1410 } 1411 } 1412 1413 // We expect the output of the patcher to fill the tgt ranges exactly. 1414 if (!writer.Finished()) { 1415 LOG(ERROR) << "Failed to fully write target blocks (range sink underrun): Missing " 1416 << writer.AvailableSpace() << " bytes"; 1417 failure_type = kPatchApplicationFailure; 1418 return -1; 1419 } 1420 } else { 1421 LOG(INFO) << "skipping " << blocks << " blocks already patched to " << tgt.blocks() << " [" 1422 << params.cmdline << "]"; 1423 } 1424 } 1425 1426 if (!params.freestash.empty()) { 1427 FreeStash(params.stashbase, params.freestash); 1428 params.freestash.clear(); 1429 } 1430 1431 params.written += tgt.blocks(); 1432 1433 return 0; 1434 } 1435 1436 static int PerformCommandErase(CommandParameters& params) { 1437 if (DEBUG_ERASE) { 1438 return PerformCommandZero(params); 1439 } 1440 1441 struct stat sb; 1442 if (fstat(params.fd, &sb) == -1) { 1443 PLOG(ERROR) << "failed to fstat device to erase"; 1444 return -1; 1445 } 1446 1447 if (!S_ISBLK(sb.st_mode)) { 1448 LOG(ERROR) << "not a block device; skipping erase"; 1449 return -1; 1450 } 1451 1452 if (params.cpos >= params.tokens.size()) { 1453 LOG(ERROR) << "missing target blocks for erase"; 1454 return -1; 1455 } 1456 1457 RangeSet tgt = RangeSet::Parse(params.tokens[params.cpos++]); 1458 CHECK(static_cast<bool>(tgt)); 1459 1460 if (params.canwrite) { 1461 LOG(INFO) << " erasing " << tgt.blocks() << " blocks"; 1462 1463 for (const auto& [begin, end] : tgt) { 1464 off64_t offset = static_cast<off64_t>(begin) * BLOCKSIZE; 1465 size_t size = (end - begin) * BLOCKSIZE; 1466 if (!discard_blocks(params.fd, offset, size, true /* force */)) { 1467 return -1; 1468 } 1469 } 1470 } 1471 1472 return 0; 1473 } 1474 1475 static int PerformCommandAbort(CommandParameters&) { 1476 LOG(INFO) << "Aborting as instructed"; 1477 return -1; 1478 } 1479 1480 // Computes the hash_tree bytes based on the parameters, checks if the root hash of the tree 1481 // matches the expected hash and writes the result to the specified range on the block_device. 1482 // Hash_tree computation arguments: 1483 // hash_tree_ranges 1484 // source_ranges 1485 // hash_algorithm 1486 // salt_hex 1487 // root_hash 1488 static int PerformCommandComputeHashTree(CommandParameters& params) { 1489 if (params.cpos + 5 != params.tokens.size()) { 1490 LOG(ERROR) << "Invaild arguments count in hash computation " << params.cmdline; 1491 return -1; 1492 } 1493 1494 // Expects the hash_tree data to be contiguous. 1495 RangeSet hash_tree_ranges = RangeSet::Parse(params.tokens[params.cpos++]); 1496 if (!hash_tree_ranges || hash_tree_ranges.size() != 1) { 1497 LOG(ERROR) << "Invalid hash tree ranges in " << params.cmdline; 1498 return -1; 1499 } 1500 1501 RangeSet source_ranges = RangeSet::Parse(params.tokens[params.cpos++]); 1502 if (!source_ranges) { 1503 LOG(ERROR) << "Invalid source ranges in " << params.cmdline; 1504 return -1; 1505 } 1506 1507 auto hash_function = HashTreeBuilder::HashFunction(params.tokens[params.cpos++]); 1508 if (hash_function == nullptr) { 1509 LOG(ERROR) << "Invalid hash algorithm in " << params.cmdline; 1510 return -1; 1511 } 1512 1513 std::vector<unsigned char> salt; 1514 std::string salt_hex = params.tokens[params.cpos++]; 1515 if (salt_hex.empty() || !HashTreeBuilder::ParseBytesArrayFromString(salt_hex, &salt)) { 1516 LOG(ERROR) << "Failed to parse salt in " << params.cmdline; 1517 return -1; 1518 } 1519 1520 std::string expected_root_hash = params.tokens[params.cpos++]; 1521 if (expected_root_hash.empty()) { 1522 LOG(ERROR) << "Invalid root hash in " << params.cmdline; 1523 return -1; 1524 } 1525 1526 // Starts the hash_tree computation. 1527 HashTreeBuilder builder(BLOCKSIZE, hash_function); 1528 if (!builder.Initialize(static_cast<int64_t>(source_ranges.blocks()) * BLOCKSIZE, salt)) { 1529 LOG(ERROR) << "Failed to initialize hash tree computation, source " << source_ranges.ToString() 1530 << ", salt " << salt_hex; 1531 return -1; 1532 } 1533 1534 // Iterates through every block in the source_ranges and updates the hash tree structure 1535 // accordingly. 1536 for (const auto& [begin, end] : source_ranges) { 1537 uint8_t buffer[BLOCKSIZE]; 1538 if (!check_lseek(params.fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { 1539 PLOG(ERROR) << "Failed to seek to block: " << begin; 1540 return -1; 1541 } 1542 1543 for (size_t i = begin; i < end; i++) { 1544 if (!android::base::ReadFully(params.fd, buffer, BLOCKSIZE)) { 1545 failure_type = errno == EIO ? kEioFailure : kFreadFailure; 1546 LOG(ERROR) << "Failed to read data in " << begin << ":" << end; 1547 return -1; 1548 } 1549 1550 if (!builder.Update(reinterpret_cast<unsigned char*>(buffer), BLOCKSIZE)) { 1551 LOG(ERROR) << "Failed to update hash tree builder"; 1552 return -1; 1553 } 1554 } 1555 } 1556 1557 if (!builder.BuildHashTree()) { 1558 LOG(ERROR) << "Failed to build hash tree"; 1559 return -1; 1560 } 1561 1562 std::string root_hash_hex = HashTreeBuilder::BytesArrayToString(builder.root_hash()); 1563 if (root_hash_hex != expected_root_hash) { 1564 LOG(ERROR) << "Root hash of the verity hash tree doesn't match the expected value. Expected: " 1565 << expected_root_hash << ", actual: " << root_hash_hex; 1566 return -1; 1567 } 1568 1569 uint64_t write_offset = static_cast<uint64_t>(hash_tree_ranges.GetBlockNumber(0)) * BLOCKSIZE; 1570 if (params.canwrite && !builder.WriteHashTreeToFd(params.fd, write_offset)) { 1571 LOG(ERROR) << "Failed to write hash tree to output"; 1572 return -1; 1573 } 1574 1575 // TODO(xunchang) validates the written bytes 1576 1577 return 0; 1578 } 1579 1580 using CommandFunction = std::function<int(CommandParameters&)>; 1581 1582 using CommandMap = std::unordered_map<Command::Type, CommandFunction>; 1583 1584 static bool Sha1DevicePath(const std::string& path, uint8_t digest[SHA_DIGEST_LENGTH]) { 1585 auto device_name = android::base::Basename(path); 1586 auto dm_target_name_path = "/sys/block/" + device_name + "/dm/name"; 1587 1588 struct stat sb; 1589 if (stat(dm_target_name_path.c_str(), &sb) == 0) { 1590 // This is a device mapper target. Use partition name as part of the hash instead. Do not 1591 // include extents as part of the hash, because the size of a partition may be shrunk after 1592 // the patches are applied. 1593 std::string dm_target_name; 1594 if (!android::base::ReadFileToString(dm_target_name_path, &dm_target_name)) { 1595 PLOG(ERROR) << "Cannot read " << dm_target_name_path; 1596 return false; 1597 } 1598 SHA1(reinterpret_cast<const uint8_t*>(dm_target_name.data()), dm_target_name.size(), digest); 1599 return true; 1600 } 1601 1602 if (errno != ENOENT) { 1603 // This is a device mapper target, but its name cannot be retrieved. 1604 PLOG(ERROR) << "Cannot get dm target name for " << path; 1605 return false; 1606 } 1607 1608 // This doesn't appear to be a device mapper target, but if its name starts with dm-, something 1609 // else might have gone wrong. 1610 if (android::base::StartsWith(device_name, "dm-")) { 1611 LOG(WARNING) << "Device " << path << " starts with dm- but is not mapped by device-mapper."; 1612 } 1613 1614 // Stash directory should be different for each partition to avoid conflicts when updating 1615 // multiple partitions at the same time, so we use the hash of the block device name as the base 1616 // directory. 1617 SHA1(reinterpret_cast<const uint8_t*>(path.data()), path.size(), digest); 1618 return true; 1619 } 1620 1621 static Value* PerformBlockImageUpdate(const char* name, State* state, 1622 const std::vector<std::unique_ptr<Expr>>& argv, 1623 const CommandMap& command_map, bool dryrun) { 1624 CommandParameters params = {}; 1625 stash_map.clear(); 1626 params.canwrite = !dryrun; 1627 1628 LOG(INFO) << "performing " << (dryrun ? "verification" : "update"); 1629 if (state->is_retry) { 1630 is_retry = true; 1631 LOG(INFO) << "This update is a retry."; 1632 } 1633 if (argv.size() != 4) { 1634 ErrorAbort(state, kArgsParsingFailure, "block_image_update expects 4 arguments, got %zu", 1635 argv.size()); 1636 return StringValue(""); 1637 } 1638 1639 std::vector<std::unique_ptr<Value>> args; 1640 if (!ReadValueArgs(state, argv, &args)) { 1641 return nullptr; 1642 } 1643 1644 // args: 1645 // - block device (or file) to modify in-place 1646 // - transfer list (blob) 1647 // - new data stream (filename within package.zip) 1648 // - patch stream (filename within package.zip, must be uncompressed) 1649 const std::unique_ptr<Value>& blockdev_filename = args[0]; 1650 const std::unique_ptr<Value>& transfer_list_value = args[1]; 1651 const std::unique_ptr<Value>& new_data_fn = args[2]; 1652 const std::unique_ptr<Value>& patch_data_fn = args[3]; 1653 1654 if (blockdev_filename->type != Value::Type::STRING) { 1655 ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", name); 1656 return StringValue(""); 1657 } 1658 if (transfer_list_value->type != Value::Type::BLOB) { 1659 ErrorAbort(state, kArgsParsingFailure, "transfer_list argument to %s must be blob", name); 1660 return StringValue(""); 1661 } 1662 if (new_data_fn->type != Value::Type::STRING) { 1663 ErrorAbort(state, kArgsParsingFailure, "new_data_fn argument to %s must be string", name); 1664 return StringValue(""); 1665 } 1666 if (patch_data_fn->type != Value::Type::STRING) { 1667 ErrorAbort(state, kArgsParsingFailure, "patch_data_fn argument to %s must be string", name); 1668 return StringValue(""); 1669 } 1670 1671 UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie); 1672 if (ui == nullptr) { 1673 return StringValue(""); 1674 } 1675 1676 FILE* cmd_pipe = ui->cmd_pipe; 1677 ZipArchiveHandle za = ui->package_zip; 1678 1679 if (cmd_pipe == nullptr || za == nullptr) { 1680 return StringValue(""); 1681 } 1682 1683 ZipString path_data(patch_data_fn->data.c_str()); 1684 ZipEntry patch_entry; 1685 if (FindEntry(za, path_data, &patch_entry) != 0) { 1686 LOG(ERROR) << name << "(): no file \"" << patch_data_fn->data << "\" in package"; 1687 return StringValue(""); 1688 } 1689 1690 params.patch_start = ui->package_zip_addr + patch_entry.offset; 1691 ZipString new_data(new_data_fn->data.c_str()); 1692 ZipEntry new_entry; 1693 if (FindEntry(za, new_data, &new_entry) != 0) { 1694 LOG(ERROR) << name << "(): no file \"" << new_data_fn->data << "\" in package"; 1695 return StringValue(""); 1696 } 1697 1698 params.fd.reset(TEMP_FAILURE_RETRY(open(blockdev_filename->data.c_str(), O_RDWR))); 1699 if (params.fd == -1) { 1700 failure_type = errno == EIO ? kEioFailure : kFileOpenFailure; 1701 PLOG(ERROR) << "open \"" << blockdev_filename->data << "\" failed"; 1702 return StringValue(""); 1703 } 1704 1705 uint8_t digest[SHA_DIGEST_LENGTH]; 1706 if (!Sha1DevicePath(blockdev_filename->data, digest)) { 1707 return StringValue(""); 1708 } 1709 params.stashbase = print_sha1(digest); 1710 1711 // Possibly do return early on retry, by checking the marker. If the update on this partition has 1712 // been finished (but interrupted at a later point), there could be leftover on /cache that would 1713 // fail the no-op retry. 1714 std::string updated_marker = GetStashFileName(params.stashbase + ".UPDATED", "", ""); 1715 if (is_retry) { 1716 struct stat sb; 1717 int result = stat(updated_marker.c_str(), &sb); 1718 if (result == 0) { 1719 LOG(INFO) << "Skipping already updated partition " << blockdev_filename->data 1720 << " based on marker"; 1721 return StringValue("t"); 1722 } 1723 } else { 1724 // Delete the obsolete marker if any. 1725 std::string err; 1726 if (!android::base::RemoveFileIfExists(updated_marker, &err)) { 1727 LOG(ERROR) << "Failed to remove partition updated marker " << updated_marker << ": " << err; 1728 return StringValue(""); 1729 } 1730 } 1731 1732 static constexpr size_t kTransferListHeaderLines = 4; 1733 std::vector<std::string> lines = android::base::Split(transfer_list_value->data, "\n"); 1734 if (lines.size() < kTransferListHeaderLines) { 1735 ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zu]", 1736 lines.size()); 1737 return StringValue(""); 1738 } 1739 1740 // First line in transfer list is the version number. 1741 if (!android::base::ParseInt(lines[0], ¶ms.version, 3, 4)) { 1742 LOG(ERROR) << "unexpected transfer list version [" << lines[0] << "]"; 1743 return StringValue(""); 1744 } 1745 1746 LOG(INFO) << "blockimg version is " << params.version; 1747 1748 // Second line in transfer list is the total number of blocks we expect to write. 1749 size_t total_blocks; 1750 if (!android::base::ParseUint(lines[1], &total_blocks)) { 1751 ErrorAbort(state, kArgsParsingFailure, "unexpected block count [%s]", lines[1].c_str()); 1752 return StringValue(""); 1753 } 1754 1755 if (total_blocks == 0) { 1756 return StringValue("t"); 1757 } 1758 1759 // Third line is how many stash entries are needed simultaneously. 1760 LOG(INFO) << "maximum stash entries " << lines[2]; 1761 1762 // Fourth line is the maximum number of blocks that will be stashed simultaneously 1763 size_t stash_max_blocks; 1764 if (!android::base::ParseUint(lines[3], &stash_max_blocks)) { 1765 ErrorAbort(state, kArgsParsingFailure, "unexpected maximum stash blocks [%s]", 1766 lines[3].c_str()); 1767 return StringValue(""); 1768 } 1769 1770 int res = CreateStash(state, stash_max_blocks, params.stashbase); 1771 if (res == -1) { 1772 return StringValue(""); 1773 } 1774 params.createdstash = res; 1775 1776 // Set up the new data writer. 1777 if (params.canwrite) { 1778 params.nti.za = za; 1779 params.nti.entry = new_entry; 1780 params.nti.brotli_compressed = android::base::EndsWith(new_data_fn->data, ".br"); 1781 if (params.nti.brotli_compressed) { 1782 // Initialize brotli decoder state. 1783 params.nti.brotli_decoder_state = BrotliDecoderCreateInstance(nullptr, nullptr, nullptr); 1784 } 1785 params.nti.receiver_available = true; 1786 1787 pthread_mutex_init(¶ms.nti.mu, nullptr); 1788 pthread_cond_init(¶ms.nti.cv, nullptr); 1789 pthread_attr_t attr; 1790 pthread_attr_init(&attr); 1791 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 1792 1793 int error = pthread_create(¶ms.thread, &attr, unzip_new_data, ¶ms.nti); 1794 if (error != 0) { 1795 LOG(ERROR) << "pthread_create failed: " << strerror(error); 1796 return StringValue(""); 1797 } 1798 } 1799 1800 // When performing an update, save the index and cmdline of the current command into the 1801 // last_command_file. 1802 // Upon resuming an update, read the saved index first; then 1803 // 1. In verification mode, check if the 'move' or 'diff' commands before the saved index has 1804 // the expected target blocks already. If not, these commands cannot be skipped and we need 1805 // to attempt to execute them again. Therefore, we will delete the last_command_file so that 1806 // the update will resume from the start of the transfer list. 1807 // 2. In update mode, skip all commands before the saved index. Therefore, we can avoid deleting 1808 // stashes with duplicate id unintentionally (b/69858743); and also speed up the update. 1809 // If an update succeeds or is unresumable, delete the last_command_file. 1810 bool skip_executed_command = true; 1811 size_t saved_last_command_index; 1812 if (!ParseLastCommandFile(&saved_last_command_index)) { 1813 DeleteLastCommandFile(); 1814 // We failed to parse the last command. Disallow skipping executed commands. 1815 skip_executed_command = false; 1816 } 1817 1818 int rc = -1; 1819 1820 // Subsequent lines are all individual transfer commands 1821 for (size_t i = kTransferListHeaderLines; i < lines.size(); i++) { 1822 const std::string& line = lines[i]; 1823 if (line.empty()) continue; 1824 1825 size_t cmdindex = i - kTransferListHeaderLines; 1826 params.tokens = android::base::Split(line, " "); 1827 params.cpos = 0; 1828 params.cmdname = params.tokens[params.cpos++]; 1829 params.cmdline = line; 1830 params.target_verified = false; 1831 1832 Command::Type cmd_type = Command::ParseType(params.cmdname); 1833 if (cmd_type == Command::Type::LAST) { 1834 LOG(ERROR) << "unexpected command [" << params.cmdname << "]"; 1835 goto pbiudone; 1836 } 1837 1838 const CommandFunction& performer = command_map.at(cmd_type); 1839 1840 // Skip the command if we explicitly set the corresponding function pointer to nullptr, e.g. 1841 // "erase" during block_image_verify. 1842 if (performer == nullptr) { 1843 LOG(DEBUG) << "skip executing command [" << line << "]"; 1844 continue; 1845 } 1846 1847 // Skip all commands before the saved last command index when resuming an update, except for 1848 // "new" command. Because new commands read in the data sequentially. 1849 if (params.canwrite && skip_executed_command && cmdindex <= saved_last_command_index && 1850 cmd_type != Command::Type::NEW) { 1851 LOG(INFO) << "Skipping already executed command: " << cmdindex 1852 << ", last executed command for previous update: " << saved_last_command_index; 1853 continue; 1854 } 1855 1856 if (performer(params) == -1) { 1857 LOG(ERROR) << "failed to execute command [" << line << "]"; 1858 if (cmd_type == Command::Type::COMPUTE_HASH_TREE && failure_type == kNoCause) { 1859 failure_type = kHashTreeComputationFailure; 1860 } 1861 goto pbiudone; 1862 } 1863 1864 // In verify mode, check if the commands before the saved last_command_index have been executed 1865 // correctly. If some target blocks have unexpected contents, delete the last command file so 1866 // that we will resume the update from the first command in the transfer list. 1867 if (!params.canwrite && skip_executed_command && cmdindex <= saved_last_command_index) { 1868 // TODO(xunchang) check that the cmdline of the saved index is correct. 1869 if ((cmd_type == Command::Type::MOVE || cmd_type == Command::Type::BSDIFF || 1870 cmd_type == Command::Type::IMGDIFF) && 1871 !params.target_verified) { 1872 LOG(WARNING) << "Previously executed command " << saved_last_command_index << ": " 1873 << params.cmdline << " doesn't produce expected target blocks."; 1874 skip_executed_command = false; 1875 DeleteLastCommandFile(); 1876 } 1877 } 1878 1879 if (params.canwrite) { 1880 if (fsync(params.fd) == -1) { 1881 failure_type = errno == EIO ? kEioFailure : kFsyncFailure; 1882 PLOG(ERROR) << "fsync failed"; 1883 goto pbiudone; 1884 } 1885 1886 if (!UpdateLastCommandIndex(cmdindex, params.cmdline)) { 1887 LOG(WARNING) << "Failed to update the last command file."; 1888 } 1889 1890 fprintf(cmd_pipe, "set_progress %.4f\n", static_cast<double>(params.written) / total_blocks); 1891 fflush(cmd_pipe); 1892 } 1893 } 1894 1895 rc = 0; 1896 1897 pbiudone: 1898 if (params.canwrite) { 1899 pthread_mutex_lock(¶ms.nti.mu); 1900 if (params.nti.receiver_available) { 1901 LOG(WARNING) << "new data receiver is still available after executing all commands."; 1902 } 1903 params.nti.receiver_available = false; 1904 pthread_cond_broadcast(¶ms.nti.cv); 1905 pthread_mutex_unlock(¶ms.nti.mu); 1906 int ret = pthread_join(params.thread, nullptr); 1907 if (ret != 0) { 1908 LOG(WARNING) << "pthread join returned with " << strerror(ret); 1909 } 1910 1911 if (rc == 0) { 1912 LOG(INFO) << "wrote " << params.written << " blocks; expected " << total_blocks; 1913 LOG(INFO) << "stashed " << params.stashed << " blocks"; 1914 LOG(INFO) << "max alloc needed was " << params.buffer.size(); 1915 1916 const char* partition = strrchr(blockdev_filename->data.c_str(), '/'); 1917 if (partition != nullptr && *(partition + 1) != 0) { 1918 fprintf(cmd_pipe, "log bytes_written_%s: %" PRIu64 "\n", partition + 1, 1919 static_cast<uint64_t>(params.written) * BLOCKSIZE); 1920 fprintf(cmd_pipe, "log bytes_stashed_%s: %" PRIu64 "\n", partition + 1, 1921 static_cast<uint64_t>(params.stashed) * BLOCKSIZE); 1922 fflush(cmd_pipe); 1923 } 1924 // Delete stash only after successfully completing the update, as it may contain blocks needed 1925 // to complete the update later. 1926 DeleteStash(params.stashbase); 1927 DeleteLastCommandFile(); 1928 1929 // Create a marker on /cache partition, which allows skipping the update on this partition on 1930 // retry. The marker will be removed once booting into normal boot, or before starting next 1931 // fresh install. 1932 if (!SetUpdatedMarker(updated_marker)) { 1933 LOG(WARNING) << "Failed to set updated marker; continuing"; 1934 } 1935 } 1936 1937 pthread_mutex_destroy(¶ms.nti.mu); 1938 pthread_cond_destroy(¶ms.nti.cv); 1939 } else if (rc == 0) { 1940 LOG(INFO) << "verified partition contents; update may be resumed"; 1941 } 1942 1943 if (fsync(params.fd) == -1) { 1944 failure_type = errno == EIO ? kEioFailure : kFsyncFailure; 1945 PLOG(ERROR) << "fsync failed"; 1946 } 1947 // params.fd will be automatically closed because it's a unique_fd. 1948 1949 if (params.nti.brotli_decoder_state != nullptr) { 1950 BrotliDecoderDestroyInstance(params.nti.brotli_decoder_state); 1951 } 1952 1953 // Delete the last command file if the update cannot be resumed. 1954 if (params.isunresumable) { 1955 DeleteLastCommandFile(); 1956 } 1957 1958 // Only delete the stash if the update cannot be resumed, or it's a verification run and we 1959 // created the stash. 1960 if (params.isunresumable || (!params.canwrite && params.createdstash)) { 1961 DeleteStash(params.stashbase); 1962 } 1963 1964 if (failure_type != kNoCause && state->cause_code == kNoCause) { 1965 state->cause_code = failure_type; 1966 } 1967 1968 return StringValue(rc == 0 ? "t" : ""); 1969 } 1970 1971 /** 1972 * The transfer list is a text file containing commands to transfer data from one place to another 1973 * on the target partition. We parse it and execute the commands in order: 1974 * 1975 * zero [rangeset] 1976 * - Fill the indicated blocks with zeros. 1977 * 1978 * new [rangeset] 1979 * - Fill the blocks with data read from the new_data file. 1980 * 1981 * erase [rangeset] 1982 * - Mark the given blocks as empty. 1983 * 1984 * move <...> 1985 * bsdiff <patchstart> <patchlen> <...> 1986 * imgdiff <patchstart> <patchlen> <...> 1987 * - Read the source blocks, apply a patch (or not in the case of move), write result to target 1988 * blocks. bsdiff or imgdiff specifies the type of patch; move means no patch at all. 1989 * 1990 * See the comments in LoadSrcTgtVersion3() for a description of the <...> format. 1991 * 1992 * stash <stash_id> <src_range> 1993 * - Load the given source range and stash the data in the given slot of the stash table. 1994 * 1995 * free <stash_id> 1996 * - Free the given stash data. 1997 * 1998 * The creator of the transfer list will guarantee that no block is read (ie, used as the source for 1999 * a patch or move) after it has been written. 2000 * 2001 * The creator will guarantee that a given stash is loaded (with a stash command) before it's used 2002 * in a move/bsdiff/imgdiff command. 2003 * 2004 * Within one command the source and target ranges may overlap so in general we need to read the 2005 * entire source into memory before writing anything to the target blocks. 2006 * 2007 * All the patch data is concatenated into one patch_data file in the update package. It must be 2008 * stored uncompressed because we memory-map it in directly from the archive. (Since patches are 2009 * already compressed, we lose very little by not compressing their concatenation.) 2010 * 2011 * Commands that read data from the partition (i.e. move/bsdiff/imgdiff/stash) have one or more 2012 * additional hashes before the range parameters, which are used to check if the command has already 2013 * been completed and verify the integrity of the source data. 2014 */ 2015 Value* BlockImageVerifyFn(const char* name, State* state, 2016 const std::vector<std::unique_ptr<Expr>>& argv) { 2017 // Commands which are not allowed are set to nullptr to skip them completely. 2018 const CommandMap command_map{ 2019 // clang-format off 2020 { Command::Type::ABORT, PerformCommandAbort }, 2021 { Command::Type::BSDIFF, PerformCommandDiff }, 2022 { Command::Type::COMPUTE_HASH_TREE, PerformCommandComputeHashTree }, 2023 { Command::Type::ERASE, nullptr }, 2024 { Command::Type::FREE, PerformCommandFree }, 2025 { Command::Type::IMGDIFF, PerformCommandDiff }, 2026 { Command::Type::MOVE, PerformCommandMove }, 2027 { Command::Type::NEW, nullptr }, 2028 { Command::Type::STASH, PerformCommandStash }, 2029 { Command::Type::ZERO, nullptr }, 2030 // clang-format on 2031 }; 2032 CHECK_EQ(static_cast<size_t>(Command::Type::LAST), command_map.size()); 2033 2034 // Perform a dry run without writing to test if an update can proceed. 2035 return PerformBlockImageUpdate(name, state, argv, command_map, true); 2036 } 2037 2038 Value* BlockImageUpdateFn(const char* name, State* state, 2039 const std::vector<std::unique_ptr<Expr>>& argv) { 2040 const CommandMap command_map{ 2041 // clang-format off 2042 { Command::Type::ABORT, PerformCommandAbort }, 2043 { Command::Type::BSDIFF, PerformCommandDiff }, 2044 { Command::Type::COMPUTE_HASH_TREE, PerformCommandComputeHashTree }, 2045 { Command::Type::ERASE, PerformCommandErase }, 2046 { Command::Type::FREE, PerformCommandFree }, 2047 { Command::Type::IMGDIFF, PerformCommandDiff }, 2048 { Command::Type::MOVE, PerformCommandMove }, 2049 { Command::Type::NEW, PerformCommandNew }, 2050 { Command::Type::STASH, PerformCommandStash }, 2051 { Command::Type::ZERO, PerformCommandZero }, 2052 // clang-format on 2053 }; 2054 CHECK_EQ(static_cast<size_t>(Command::Type::LAST), command_map.size()); 2055 2056 return PerformBlockImageUpdate(name, state, argv, command_map, false); 2057 } 2058 2059 Value* RangeSha1Fn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 2060 if (argv.size() != 2) { 2061 ErrorAbort(state, kArgsParsingFailure, "range_sha1 expects 2 arguments, got %zu", argv.size()); 2062 return StringValue(""); 2063 } 2064 2065 std::vector<std::unique_ptr<Value>> args; 2066 if (!ReadValueArgs(state, argv, &args)) { 2067 return nullptr; 2068 } 2069 2070 const std::unique_ptr<Value>& blockdev_filename = args[0]; 2071 const std::unique_ptr<Value>& ranges = args[1]; 2072 2073 if (blockdev_filename->type != Value::Type::STRING) { 2074 ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", name); 2075 return StringValue(""); 2076 } 2077 if (ranges->type != Value::Type::STRING) { 2078 ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); 2079 return StringValue(""); 2080 } 2081 2082 android::base::unique_fd fd(open(blockdev_filename->data.c_str(), O_RDWR)); 2083 if (fd == -1) { 2084 CauseCode cause_code = errno == EIO ? kEioFailure : kFileOpenFailure; 2085 ErrorAbort(state, cause_code, "open \"%s\" failed: %s", blockdev_filename->data.c_str(), 2086 strerror(errno)); 2087 return StringValue(""); 2088 } 2089 2090 RangeSet rs = RangeSet::Parse(ranges->data); 2091 CHECK(static_cast<bool>(rs)); 2092 2093 SHA_CTX ctx; 2094 SHA1_Init(&ctx); 2095 2096 std::vector<uint8_t> buffer(BLOCKSIZE); 2097 for (const auto& [begin, end] : rs) { 2098 if (!check_lseek(fd, static_cast<off64_t>(begin) * BLOCKSIZE, SEEK_SET)) { 2099 ErrorAbort(state, kLseekFailure, "failed to seek %s: %s", blockdev_filename->data.c_str(), 2100 strerror(errno)); 2101 return StringValue(""); 2102 } 2103 2104 for (size_t j = begin; j < end; ++j) { 2105 if (!android::base::ReadFully(fd, buffer.data(), BLOCKSIZE)) { 2106 CauseCode cause_code = errno == EIO ? kEioFailure : kFreadFailure; 2107 ErrorAbort(state, cause_code, "failed to read %s: %s", blockdev_filename->data.c_str(), 2108 strerror(errno)); 2109 return StringValue(""); 2110 } 2111 2112 SHA1_Update(&ctx, buffer.data(), BLOCKSIZE); 2113 } 2114 } 2115 uint8_t digest[SHA_DIGEST_LENGTH]; 2116 SHA1_Final(digest, &ctx); 2117 2118 return StringValue(print_sha1(digest)); 2119 } 2120 2121 // This function checks if a device has been remounted R/W prior to an incremental 2122 // OTA update. This is an common cause of update abortion. The function reads the 2123 // 1st block of each partition and check for mounting time/count. It return string "t" 2124 // if executes successfully and an empty string otherwise. 2125 2126 Value* CheckFirstBlockFn(const char* name, State* state, 2127 const std::vector<std::unique_ptr<Expr>>& argv) { 2128 if (argv.size() != 1) { 2129 ErrorAbort(state, kArgsParsingFailure, "check_first_block expects 1 argument, got %zu", 2130 argv.size()); 2131 return StringValue(""); 2132 } 2133 2134 std::vector<std::unique_ptr<Value>> args; 2135 if (!ReadValueArgs(state, argv, &args)) { 2136 return nullptr; 2137 } 2138 2139 const std::unique_ptr<Value>& arg_filename = args[0]; 2140 2141 if (arg_filename->type != Value::Type::STRING) { 2142 ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); 2143 return StringValue(""); 2144 } 2145 2146 android::base::unique_fd fd(open(arg_filename->data.c_str(), O_RDONLY)); 2147 if (fd == -1) { 2148 CauseCode cause_code = errno == EIO ? kEioFailure : kFileOpenFailure; 2149 ErrorAbort(state, cause_code, "open \"%s\" failed: %s", arg_filename->data.c_str(), 2150 strerror(errno)); 2151 return StringValue(""); 2152 } 2153 2154 RangeSet blk0(std::vector<Range>{ Range{ 0, 1 } }); 2155 std::vector<uint8_t> block0_buffer(BLOCKSIZE); 2156 2157 if (ReadBlocks(blk0, &block0_buffer, fd) == -1) { 2158 CauseCode cause_code = errno == EIO ? kEioFailure : kFreadFailure; 2159 ErrorAbort(state, cause_code, "failed to read %s: %s", arg_filename->data.c_str(), 2160 strerror(errno)); 2161 return StringValue(""); 2162 } 2163 2164 // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout 2165 // Super block starts from block 0, offset 0x400 2166 // 0x2C: len32 Mount time 2167 // 0x30: len32 Write time 2168 // 0x34: len16 Number of mounts since the last fsck 2169 // 0x38: len16 Magic signature 0xEF53 2170 2171 time_t mount_time = *reinterpret_cast<uint32_t*>(&block0_buffer[0x400 + 0x2C]); 2172 uint16_t mount_count = *reinterpret_cast<uint16_t*>(&block0_buffer[0x400 + 0x34]); 2173 2174 if (mount_count > 0) { 2175 uiPrintf(state, "Device was remounted R/W %" PRIu16 " times", mount_count); 2176 uiPrintf(state, "Last remount happened on %s", ctime(&mount_time)); 2177 } 2178 2179 return StringValue("t"); 2180 } 2181 2182 Value* BlockImageRecoverFn(const char* name, State* state, 2183 const std::vector<std::unique_ptr<Expr>>& argv) { 2184 if (argv.size() != 2) { 2185 ErrorAbort(state, kArgsParsingFailure, "block_image_recover expects 2 arguments, got %zu", 2186 argv.size()); 2187 return StringValue(""); 2188 } 2189 2190 std::vector<std::unique_ptr<Value>> args; 2191 if (!ReadValueArgs(state, argv, &args)) { 2192 return nullptr; 2193 } 2194 2195 const std::unique_ptr<Value>& filename = args[0]; 2196 const std::unique_ptr<Value>& ranges = args[1]; 2197 2198 if (filename->type != Value::Type::STRING) { 2199 ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); 2200 return StringValue(""); 2201 } 2202 if (ranges->type != Value::Type::STRING) { 2203 ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); 2204 return StringValue(""); 2205 } 2206 RangeSet rs = RangeSet::Parse(ranges->data); 2207 if (!rs) { 2208 ErrorAbort(state, kArgsParsingFailure, "failed to parse ranges: %s", ranges->data.c_str()); 2209 return StringValue(""); 2210 } 2211 2212 // Output notice to log when recover is attempted 2213 LOG(INFO) << filename->data << " image corrupted, attempting to recover..."; 2214 2215 // When opened with O_RDWR, libfec rewrites corrupted blocks when they are read 2216 fec::io fh(filename->data, O_RDWR); 2217 2218 if (!fh) { 2219 ErrorAbort(state, kLibfecFailure, "fec_open \"%s\" failed: %s", filename->data.c_str(), 2220 strerror(errno)); 2221 return StringValue(""); 2222 } 2223 2224 if (!fh.has_ecc() || !fh.has_verity()) { 2225 ErrorAbort(state, kLibfecFailure, "unable to use metadata to correct errors"); 2226 return StringValue(""); 2227 } 2228 2229 fec_status status; 2230 if (!fh.get_status(status)) { 2231 ErrorAbort(state, kLibfecFailure, "failed to read FEC status"); 2232 return StringValue(""); 2233 } 2234 2235 uint8_t buffer[BLOCKSIZE]; 2236 for (const auto& [begin, end] : rs) { 2237 for (size_t j = begin; j < end; ++j) { 2238 // Stay within the data area, libfec validates and corrects metadata 2239 if (status.data_size <= static_cast<uint64_t>(j) * BLOCKSIZE) { 2240 continue; 2241 } 2242 2243 if (fh.pread(buffer, BLOCKSIZE, static_cast<off64_t>(j) * BLOCKSIZE) != BLOCKSIZE) { 2244 ErrorAbort(state, kLibfecFailure, "failed to recover %s (block %zu): %s", 2245 filename->data.c_str(), j, strerror(errno)); 2246 return StringValue(""); 2247 } 2248 2249 // If we want to be able to recover from a situation where rewriting a corrected 2250 // block doesn't guarantee the same data will be returned when re-read later, we 2251 // can save a copy of corrected blocks to /cache. Note: 2252 // 2253 // 1. Maximum space required from /cache is the same as the maximum number of 2254 // corrupted blocks we can correct. For RS(255, 253) and a 2 GiB partition, 2255 // this would be ~16 MiB, for example. 2256 // 2257 // 2. To find out if this block was corrupted, call fec_get_status after each 2258 // read and check if the errors field value has increased. 2259 } 2260 } 2261 LOG(INFO) << "..." << filename->data << " image recovered successfully."; 2262 return StringValue("t"); 2263 } 2264 2265 void RegisterBlockImageFunctions() { 2266 RegisterFunction("block_image_verify", BlockImageVerifyFn); 2267 RegisterFunction("block_image_update", BlockImageUpdateFn); 2268 RegisterFunction("block_image_recover", BlockImageRecoverFn); 2269 RegisterFunction("check_first_block", CheckFirstBlockFn); 2270 RegisterFunction("range_sha1", RangeSha1Fn); 2271 } 2272