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