1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "install.h"
18 
19 #include <ctype.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <inttypes.h>
23 #include <limits.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/wait.h>
27 #include <unistd.h>
28 
29 #include <algorithm>
30 #include <atomic>
31 #include <chrono>
32 #include <condition_variable>
33 #include <functional>
34 #include <limits>
35 #include <map>
36 #include <mutex>
37 #include <string>
38 #include <thread>
39 #include <vector>
40 
41 #include <android-base/file.h>
42 #include <android-base/logging.h>
43 #include <android-base/parsedouble.h>
44 #include <android-base/parseint.h>
45 #include <android-base/properties.h>
46 #include <android-base/stringprintf.h>
47 #include <android-base/strings.h>
48 #include <vintf/VintfObjectRecovery.h>
49 #include <ziparchive/zip_archive.h>
50 
51 #include "common.h"
52 #include "otautil/SysUtil.h"
53 #include "otautil/ThermalUtil.h"
54 #include "otautil/error_code.h"
55 #include "private/install.h"
56 #include "roots.h"
57 #include "ui.h"
58 #include "verifier.h"
59 
60 using namespace std::chrono_literals;
61 
62 // Default allocation of progress bar segments to operations
63 static constexpr int VERIFICATION_PROGRESS_TIME = 60;
64 static constexpr float VERIFICATION_PROGRESS_FRACTION = 0.25;
65 
66 static std::condition_variable finish_log_temperature;
67 
68 // This function parses and returns the build.version.incremental
parse_build_number(const std::string & str)69 static std::string parse_build_number(const std::string& str) {
70     size_t pos = str.find('=');
71     if (pos != std::string::npos) {
72         return android::base::Trim(str.substr(pos+1));
73     }
74 
75     LOG(ERROR) << "Failed to parse build number in " << str;
76     return "";
77 }
78 
read_metadata_from_package(ZipArchiveHandle zip,std::string * metadata)79 bool read_metadata_from_package(ZipArchiveHandle zip, std::string* metadata) {
80   CHECK(metadata != nullptr);
81 
82   static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
83   ZipString path(METADATA_PATH);
84   ZipEntry entry;
85   if (FindEntry(zip, path, &entry) != 0) {
86     LOG(ERROR) << "Failed to find " << METADATA_PATH;
87     return false;
88   }
89 
90   uint32_t length = entry.uncompressed_length;
91   metadata->resize(length, '\0');
92   int32_t err = ExtractToMemory(zip, &entry, reinterpret_cast<uint8_t*>(&(*metadata)[0]), length);
93   if (err != 0) {
94     LOG(ERROR) << "Failed to extract " << METADATA_PATH << ": " << ErrorCodeString(err);
95     return false;
96   }
97   return true;
98 }
99 
100 // Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
read_source_target_build(ZipArchiveHandle zip,std::vector<std::string> * log_buffer)101 static void read_source_target_build(ZipArchiveHandle zip, std::vector<std::string>* log_buffer) {
102   std::string metadata;
103   if (!read_metadata_from_package(zip, &metadata)) {
104     return;
105   }
106   // Examples of the pre-build and post-build strings in metadata:
107   //   pre-build-incremental=2943039
108   //   post-build-incremental=2951741
109   std::vector<std::string> lines = android::base::Split(metadata, "\n");
110   for (const std::string& line : lines) {
111     std::string str = android::base::Trim(line);
112     if (android::base::StartsWith(str, "pre-build-incremental")) {
113       std::string source_build = parse_build_number(str);
114       if (!source_build.empty()) {
115         log_buffer->push_back("source_build: " + source_build);
116       }
117     } else if (android::base::StartsWith(str, "post-build-incremental")) {
118       std::string target_build = parse_build_number(str);
119       if (!target_build.empty()) {
120         log_buffer->push_back("target_build: " + target_build);
121       }
122     }
123   }
124 }
125 
126 #ifdef AB_OTA_UPDATER
127 
128 // Parses the metadata of the OTA package in |zip| and checks whether we are
129 // allowed to accept this A/B package. Downgrading is not allowed unless
130 // explicitly enabled in the package and only for incremental packages.
check_newer_ab_build(ZipArchiveHandle zip)131 static int check_newer_ab_build(ZipArchiveHandle zip) {
132   std::string metadata_str;
133   if (!read_metadata_from_package(zip, &metadata_str)) {
134     return INSTALL_CORRUPT;
135   }
136   std::map<std::string, std::string> metadata;
137   for (const std::string& line : android::base::Split(metadata_str, "\n")) {
138     size_t eq = line.find('=');
139     if (eq != std::string::npos) {
140       metadata[line.substr(0, eq)] = line.substr(eq + 1);
141     }
142   }
143 
144   std::string value = android::base::GetProperty("ro.product.device", "");
145   const std::string& pkg_device = metadata["pre-device"];
146   if (pkg_device != value || pkg_device.empty()) {
147     LOG(ERROR) << "Package is for product " << pkg_device << " but expected " << value;
148     return INSTALL_ERROR;
149   }
150 
151   // We allow the package to not have any serialno; and we also allow it to carry multiple serial
152   // numbers split by "|"; e.g. serialno=serialno1|serialno2|serialno3 ... We will fail the
153   // verification if the device's serialno doesn't match any of these carried numbers.
154   value = android::base::GetProperty("ro.serialno", "");
155   const std::string& pkg_serial_no = metadata["serialno"];
156   if (!pkg_serial_no.empty()) {
157     bool match = false;
158     for (const std::string& number : android::base::Split(pkg_serial_no, "|")) {
159       if (value == android::base::Trim(number)) {
160         match = true;
161         break;
162       }
163     }
164     if (!match) {
165       LOG(ERROR) << "Package is for serial " << pkg_serial_no;
166       return INSTALL_ERROR;
167     }
168   }
169 
170   if (metadata["ota-type"] != "AB") {
171     LOG(ERROR) << "Package is not A/B";
172     return INSTALL_ERROR;
173   }
174 
175   // Incremental updates should match the current build.
176   value = android::base::GetProperty("ro.build.version.incremental", "");
177   const std::string& pkg_pre_build = metadata["pre-build-incremental"];
178   if (!pkg_pre_build.empty() && pkg_pre_build != value) {
179     LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " << value;
180     return INSTALL_ERROR;
181   }
182 
183   value = android::base::GetProperty("ro.build.fingerprint", "");
184   const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
185   if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != value) {
186     LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
187                << value;
188     return INSTALL_ERROR;
189   }
190 
191   // Check for downgrade version.
192   int64_t build_timestamp =
193       android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
194   int64_t pkg_post_timestamp = 0;
195   // We allow to full update to the same version we are running, in case there
196   // is a problem with the current copy of that version.
197   if (metadata["post-timestamp"].empty() ||
198       !android::base::ParseInt(metadata["post-timestamp"].c_str(), &pkg_post_timestamp) ||
199       pkg_post_timestamp < build_timestamp) {
200     if (metadata["ota-downgrade"] != "yes") {
201       LOG(ERROR) << "Update package is older than the current build, expected a build "
202                     "newer than timestamp "
203                  << build_timestamp << " but package has timestamp " << pkg_post_timestamp
204                  << " and downgrade not allowed.";
205       return INSTALL_ERROR;
206     }
207     if (pkg_pre_build_fingerprint.empty()) {
208       LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
209       return INSTALL_ERROR;
210     }
211   }
212 
213   return 0;
214 }
215 
update_binary_command(const std::string & package,ZipArchiveHandle zip,const std::string & binary_path,int,int status_fd,std::vector<std::string> * cmd)216 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
217                           const std::string& binary_path, int /* retry_count */, int status_fd,
218                           std::vector<std::string>* cmd) {
219   CHECK(cmd != nullptr);
220   int ret = check_newer_ab_build(zip);
221   if (ret != 0) {
222     return ret;
223   }
224 
225   // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
226   // in the zip file.
227   static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
228   ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
229   ZipEntry properties_entry;
230   if (FindEntry(zip, property_name, &properties_entry) != 0) {
231     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
232     return INSTALL_CORRUPT;
233   }
234   uint32_t properties_entry_length = properties_entry.uncompressed_length;
235   std::vector<uint8_t> payload_properties(properties_entry_length);
236   int32_t err =
237       ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
238   if (err != 0) {
239     LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
240     return INSTALL_CORRUPT;
241   }
242 
243   static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
244   ZipString payload_name(AB_OTA_PAYLOAD);
245   ZipEntry payload_entry;
246   if (FindEntry(zip, payload_name, &payload_entry) != 0) {
247     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
248     return INSTALL_CORRUPT;
249   }
250   long payload_offset = payload_entry.offset;
251   *cmd = {
252     binary_path,
253     "--payload=file://" + package,
254     android::base::StringPrintf("--offset=%ld", payload_offset),
255     "--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
256     android::base::StringPrintf("--status_fd=%d", status_fd),
257   };
258   return 0;
259 }
260 
261 #else  // !AB_OTA_UPDATER
262 
update_binary_command(const std::string & package,ZipArchiveHandle zip,const std::string & binary_path,int retry_count,int status_fd,std::vector<std::string> * cmd)263 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
264                           const std::string& binary_path, int retry_count, int status_fd,
265                           std::vector<std::string>* cmd) {
266   CHECK(cmd != nullptr);
267 
268   // On traditional updates we extract the update binary from the package.
269   static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
270   ZipString binary_name(UPDATE_BINARY_NAME);
271   ZipEntry binary_entry;
272   if (FindEntry(zip, binary_name, &binary_entry) != 0) {
273     LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
274     return INSTALL_CORRUPT;
275   }
276 
277   unlink(binary_path.c_str());
278   int fd = open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755);
279   if (fd == -1) {
280     PLOG(ERROR) << "Failed to create " << binary_path;
281     return INSTALL_ERROR;
282   }
283 
284   int32_t error = ExtractEntryToFile(zip, &binary_entry, fd);
285   close(fd);
286   if (error != 0) {
287     LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
288     return INSTALL_ERROR;
289   }
290 
291   *cmd = {
292     binary_path,
293     std::to_string(kRecoveryApiVersion),
294     std::to_string(status_fd),
295     package,
296   };
297   if (retry_count > 0) {
298     cmd->push_back("retry");
299   }
300   return 0;
301 }
302 #endif  // !AB_OTA_UPDATER
303 
log_max_temperature(int * max_temperature,const std::atomic<bool> & logger_finished)304 static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
305   CHECK(max_temperature != nullptr);
306   std::mutex mtx;
307   std::unique_lock<std::mutex> lck(mtx);
308   while (!logger_finished.load() &&
309          finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
310     *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
311   }
312 }
313 
314 // If the package contains an update binary, extract it and run it.
try_update_binary(const std::string & package,ZipArchiveHandle zip,bool * wipe_cache,std::vector<std::string> * log_buffer,int retry_count,int * max_temperature)315 static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache,
316                              std::vector<std::string>* log_buffer, int retry_count,
317                              int* max_temperature) {
318   read_source_target_build(zip, log_buffer);
319 
320   int pipefd[2];
321   pipe(pipefd);
322 
323   std::vector<std::string> args;
324 #ifdef AB_OTA_UPDATER
325   int ret = update_binary_command(package, zip, "/sbin/update_engine_sideload", retry_count,
326                                   pipefd[1], &args);
327 #else
328   int ret = update_binary_command(package, zip, "/tmp/update-binary", retry_count, pipefd[1],
329                                   &args);
330 #endif
331   if (ret) {
332     close(pipefd[0]);
333     close(pipefd[1]);
334     log_buffer->push_back(android::base::StringPrintf("error: %d", kUpdateBinaryCommandFailure));
335     return ret;
336   }
337 
338   // When executing the update binary contained in the package, the
339   // arguments passed are:
340   //
341   //   - the version number for this interface
342   //
343   //   - an FD to which the program can write in order to update the
344   //     progress bar.  The program can write single-line commands:
345   //
346   //        progress <frac> <secs>
347   //            fill up the next <frac> part of of the progress bar
348   //            over <secs> seconds.  If <secs> is zero, use
349   //            set_progress commands to manually control the
350   //            progress of this segment of the bar.
351   //
352   //        set_progress <frac>
353   //            <frac> should be between 0.0 and 1.0; sets the
354   //            progress bar within the segment defined by the most
355   //            recent progress command.
356   //
357   //        ui_print <string>
358   //            display <string> on the screen.
359   //
360   //        wipe_cache
361   //            a wipe of cache will be performed following a successful
362   //            installation.
363   //
364   //        clear_display
365   //            turn off the text display.
366   //
367   //        enable_reboot
368   //            packages can explicitly request that they want the user
369   //            to be able to reboot during installation (useful for
370   //            debugging packages that don't exit).
371   //
372   //        retry_update
373   //            updater encounters some issue during the update. It requests
374   //            a reboot to retry the same package automatically.
375   //
376   //        log <string>
377   //            updater requests logging the string (e.g. cause of the
378   //            failure).
379   //
380   //   - the name of the package zip file.
381   //
382   //   - an optional argument "retry" if this update is a retry of a failed
383   //   update attempt.
384   //
385 
386   // Convert the vector to a NULL-terminated char* array suitable for execv.
387   const char* chr_args[args.size() + 1];
388   chr_args[args.size()] = nullptr;
389   for (size_t i = 0; i < args.size(); i++) {
390     chr_args[i] = args[i].c_str();
391   }
392 
393   pid_t pid = fork();
394 
395   if (pid == -1) {
396     close(pipefd[0]);
397     close(pipefd[1]);
398     PLOG(ERROR) << "Failed to fork update binary";
399     log_buffer->push_back(android::base::StringPrintf("error: %d", kForkUpdateBinaryFailure));
400     return INSTALL_ERROR;
401   }
402 
403   if (pid == 0) {
404     umask(022);
405     close(pipefd[0]);
406     execv(chr_args[0], const_cast<char**>(chr_args));
407     // Bug: 34769056
408     // We shouldn't use LOG/PLOG in the forked process, since they may cause
409     // the child process to hang. This deadlock results from an improperly
410     // copied mutex in the ui functions.
411     fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
412     _exit(EXIT_FAILURE);
413   }
414   close(pipefd[1]);
415 
416   std::atomic<bool> logger_finished(false);
417   std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
418 
419   *wipe_cache = false;
420   bool retry_update = false;
421 
422   char buffer[1024];
423   FILE* from_child = fdopen(pipefd[0], "r");
424   while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
425     std::string line(buffer);
426     size_t space = line.find_first_of(" \n");
427     std::string command(line.substr(0, space));
428     if (command.empty()) continue;
429 
430     // Get rid of the leading and trailing space and/or newline.
431     std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
432 
433     if (command == "progress") {
434       std::vector<std::string> tokens = android::base::Split(args, " ");
435       double fraction;
436       int seconds;
437       if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
438           android::base::ParseInt(tokens[1], &seconds)) {
439         ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
440       } else {
441         LOG(ERROR) << "invalid \"progress\" parameters: " << line;
442       }
443     } else if (command == "set_progress") {
444       std::vector<std::string> tokens = android::base::Split(args, " ");
445       double fraction;
446       if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
447         ui->SetProgress(fraction);
448       } else {
449         LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
450       }
451     } else if (command == "ui_print") {
452       ui->PrintOnScreenOnly("%s\n", args.c_str());
453       fflush(stdout);
454     } else if (command == "wipe_cache") {
455       *wipe_cache = true;
456     } else if (command == "clear_display") {
457       ui->SetBackground(RecoveryUI::NONE);
458     } else if (command == "enable_reboot") {
459       // packages can explicitly request that they want the user
460       // to be able to reboot during installation (useful for
461       // debugging packages that don't exit).
462       ui->SetEnableReboot(true);
463     } else if (command == "retry_update") {
464       retry_update = true;
465     } else if (command == "log") {
466       if (!args.empty()) {
467         // Save the logging request from updater and write to last_install later.
468         log_buffer->push_back(args);
469       } else {
470         LOG(ERROR) << "invalid \"log\" parameters: " << line;
471       }
472     } else {
473       LOG(ERROR) << "unknown command [" << command << "]";
474     }
475   }
476   fclose(from_child);
477 
478   int status;
479   waitpid(pid, &status, 0);
480 
481   logger_finished.store(true);
482   finish_log_temperature.notify_one();
483   temperature_logger.join();
484 
485   if (retry_update) {
486     return INSTALL_RETRY;
487   }
488   if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
489     LOG(ERROR) << "Error in " << package << " (Status " << WEXITSTATUS(status) << ")";
490     return INSTALL_ERROR;
491   }
492 
493   return INSTALL_SUCCESS;
494 }
495 
496 // Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
497 // entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
498 // package.
verify_package_compatibility(ZipArchiveHandle package_zip)499 bool verify_package_compatibility(ZipArchiveHandle package_zip) {
500   LOG(INFO) << "Verifying package compatibility...";
501 
502   static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
503   ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
504   ZipEntry compatibility_entry;
505   if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
506     LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " entry";
507     return true;
508   }
509 
510   std::string zip_content(compatibility_entry.uncompressed_length, '\0');
511   int32_t ret;
512   if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
513                              reinterpret_cast<uint8_t*>(&zip_content[0]),
514                              compatibility_entry.uncompressed_length)) != 0) {
515     LOG(ERROR) << "Failed to read " << COMPATIBILITY_ZIP_ENTRY << ": " << ErrorCodeString(ret);
516     return false;
517   }
518 
519   ZipArchiveHandle zip_handle;
520   ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
521                               zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
522   if (ret != 0) {
523     LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << ErrorCodeString(ret);
524     return false;
525   }
526 
527   // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
528   void* cookie;
529   ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
530   if (ret != 0) {
531     LOG(ERROR) << "Failed to start iterating zip entries: " << ErrorCodeString(ret);
532     CloseArchive(zip_handle);
533     return false;
534   }
535   std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
536 
537   std::vector<std::string> compatibility_info;
538   ZipEntry info_entry;
539   ZipString info_name;
540   while (Next(cookie, &info_entry, &info_name) == 0) {
541     std::string content(info_entry.uncompressed_length, '\0');
542     int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
543                                   info_entry.uncompressed_length);
544     if (ret != 0) {
545       LOG(ERROR) << "Failed to read " << info_name.name << ": " << ErrorCodeString(ret);
546       CloseArchive(zip_handle);
547       return false;
548     }
549     compatibility_info.emplace_back(std::move(content));
550   }
551   CloseArchive(zip_handle);
552 
553   // VintfObjectRecovery::CheckCompatibility returns zero on success.
554   std::string err;
555   int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
556   if (result == 0) {
557     return true;
558   }
559 
560   LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
561   return false;
562 }
563 
really_install_package(const std::string & path,bool * wipe_cache,bool needs_mount,std::vector<std::string> * log_buffer,int retry_count,int * max_temperature)564 static int really_install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
565                                   std::vector<std::string>* log_buffer, int retry_count,
566                                   int* max_temperature) {
567   ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
568   ui->Print("Finding update package...\n");
569   // Give verification half the progress bar...
570   ui->SetProgressType(RecoveryUI::DETERMINATE);
571   ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
572   LOG(INFO) << "Update location: " << path;
573 
574   // Map the update package into memory.
575   ui->Print("Opening update package...\n");
576 
577   if (needs_mount) {
578     if (path[0] == '@') {
579       ensure_path_mounted(path.substr(1).c_str());
580     } else {
581       ensure_path_mounted(path.c_str());
582     }
583   }
584 
585   MemMapping map;
586   if (!map.MapFile(path)) {
587     LOG(ERROR) << "failed to map file";
588     log_buffer->push_back(android::base::StringPrintf("error: %d", kMapFileFailure));
589     return INSTALL_CORRUPT;
590   }
591 
592   // Verify package.
593   if (!verify_package(map.addr, map.length)) {
594     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
595     return INSTALL_CORRUPT;
596   }
597 
598   // Try to open the package.
599   ZipArchiveHandle zip;
600   int err = OpenArchiveFromMemory(map.addr, map.length, path.c_str(), &zip);
601   if (err != 0) {
602     LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err);
603     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
604 
605     CloseArchive(zip);
606     return INSTALL_CORRUPT;
607   }
608 
609   // Additionally verify the compatibility of the package.
610   if (!verify_package_compatibility(zip)) {
611     log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
612     CloseArchive(zip);
613     return INSTALL_CORRUPT;
614   }
615 
616   // Verify and install the contents of the package.
617   ui->Print("Installing update...\n");
618   if (retry_count > 0) {
619     ui->Print("Retry attempt: %d\n", retry_count);
620   }
621   ui->SetEnableReboot(false);
622   int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
623   ui->SetEnableReboot(true);
624   ui->Print("\n");
625 
626   CloseArchive(zip);
627   return result;
628 }
629 
install_package(const std::string & path,bool * wipe_cache,const std::string & install_file,bool needs_mount,int retry_count)630 int install_package(const std::string& path, bool* wipe_cache, const std::string& install_file,
631                     bool needs_mount, int retry_count) {
632   CHECK(!path.empty());
633   CHECK(!install_file.empty());
634   CHECK(wipe_cache != nullptr);
635 
636   modified_flash = true;
637   auto start = std::chrono::system_clock::now();
638 
639   int start_temperature = GetMaxValueFromThermalZone();
640   int max_temperature = start_temperature;
641 
642   int result;
643   std::vector<std::string> log_buffer;
644   if (setup_install_mounts() != 0) {
645     LOG(ERROR) << "failed to set up expected mounts for install; aborting";
646     result = INSTALL_ERROR;
647   } else {
648     result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,
649                                     &max_temperature);
650   }
651 
652   // Measure the time spent to apply OTA update in seconds.
653   std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
654   int time_total = static_cast<int>(duration.count());
655 
656   bool has_cache = volume_for_mount_point("/cache") != nullptr;
657   // Skip logging the uncrypt_status on devices without /cache.
658   if (has_cache) {
659     static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
660     if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
661       LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
662     } else {
663       std::string uncrypt_status;
664       if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
665         PLOG(WARNING) << "failed to read uncrypt status";
666       } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
667         LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
668       } else {
669         log_buffer.push_back(android::base::Trim(uncrypt_status));
670       }
671     }
672   }
673 
674   // The first two lines need to be the package name and install result.
675   std::vector<std::string> log_header = {
676     path,
677     result == INSTALL_SUCCESS ? "1" : "0",
678     "time_total: " + std::to_string(time_total),
679     "retry: " + std::to_string(retry_count),
680   };
681 
682   int end_temperature = GetMaxValueFromThermalZone();
683   max_temperature = std::max(end_temperature, max_temperature);
684   if (start_temperature > 0) {
685     log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
686   }
687   if (end_temperature > 0) {
688     log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
689   }
690   if (max_temperature > 0) {
691     log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
692   }
693 
694   std::string log_content =
695       android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
696   if (!android::base::WriteStringToFile(log_content, install_file)) {
697     PLOG(ERROR) << "failed to write " << install_file;
698   }
699 
700   // Write a copy into last_log.
701   LOG(INFO) << log_content;
702 
703   return result;
704 }
705 
verify_package(const unsigned char * package_data,size_t package_size)706 bool verify_package(const unsigned char* package_data, size_t package_size) {
707   static constexpr const char* PUBLIC_KEYS_FILE = "/res/keys";
708   std::vector<Certificate> loadedKeys;
709   if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {
710     LOG(ERROR) << "Failed to load keys";
711     return false;
712   }
713   LOG(INFO) << loadedKeys.size() << " key(s) loaded from " << PUBLIC_KEYS_FILE;
714 
715   // Verify package.
716   ui->Print("Verifying update package...\n");
717   auto t0 = std::chrono::system_clock::now();
718   int err = verify_file(package_data, package_size, loadedKeys,
719                         std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
720   std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
721   ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
722   if (err != VERIFY_SUCCESS) {
723     LOG(ERROR) << "Signature verification failed";
724     LOG(ERROR) << "error: " << kZipVerificationFailure;
725     return false;
726   }
727   return true;
728 }
729