• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "error_code.h"
53 #include "otautil/SysUtil.h"
54 #include "otautil/ThermalUtil.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, but if it has a non-empty
152   // value it should match.
153   value = android::base::GetProperty("ro.serialno", "");
154   const std::string& pkg_serial_no = metadata["serialno"];
155   if (!pkg_serial_no.empty() && pkg_serial_no != value) {
156     LOG(ERROR) << "Package is for serial " << pkg_serial_no;
157     return INSTALL_ERROR;
158   }
159 
160   if (metadata["ota-type"] != "AB") {
161     LOG(ERROR) << "Package is not A/B";
162     return INSTALL_ERROR;
163   }
164 
165   // Incremental updates should match the current build.
166   value = android::base::GetProperty("ro.build.version.incremental", "");
167   const std::string& pkg_pre_build = metadata["pre-build-incremental"];
168   if (!pkg_pre_build.empty() && pkg_pre_build != value) {
169     LOG(ERROR) << "Package is for source build " << pkg_pre_build << " but expected " << value;
170     return INSTALL_ERROR;
171   }
172 
173   value = android::base::GetProperty("ro.build.fingerprint", "");
174   const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
175   if (!pkg_pre_build_fingerprint.empty() && pkg_pre_build_fingerprint != value) {
176     LOG(ERROR) << "Package is for source build " << pkg_pre_build_fingerprint << " but expected "
177                << value;
178     return INSTALL_ERROR;
179   }
180 
181   // Check for downgrade version.
182   int64_t build_timestamp =
183       android::base::GetIntProperty("ro.build.date.utc", std::numeric_limits<int64_t>::max());
184   int64_t pkg_post_timestamp = 0;
185   // We allow to full update to the same version we are running, in case there
186   // is a problem with the current copy of that version.
187   if (metadata["post-timestamp"].empty() ||
188       !android::base::ParseInt(metadata["post-timestamp"].c_str(), &pkg_post_timestamp) ||
189       pkg_post_timestamp < build_timestamp) {
190     if (metadata["ota-downgrade"] != "yes") {
191       LOG(ERROR) << "Update package is older than the current build, expected a build "
192                     "newer than timestamp "
193                  << build_timestamp << " but package has timestamp " << pkg_post_timestamp
194                  << " and downgrade not allowed.";
195       return INSTALL_ERROR;
196     }
197     if (pkg_pre_build_fingerprint.empty()) {
198       LOG(ERROR) << "Downgrade package must have a pre-build version set, not allowed.";
199       return INSTALL_ERROR;
200     }
201   }
202 
203   return 0;
204 }
205 
update_binary_command(const std::string & package,ZipArchiveHandle zip,const std::string & binary_path,int,int status_fd,std::vector<std::string> * cmd)206 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
207                           const std::string& binary_path, int /* retry_count */, int status_fd,
208                           std::vector<std::string>* cmd) {
209   CHECK(cmd != nullptr);
210   int ret = check_newer_ab_build(zip);
211   if (ret != 0) {
212     return ret;
213   }
214 
215   // For A/B updates we extract the payload properties to a buffer and obtain the RAW payload offset
216   // in the zip file.
217   static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
218   ZipString property_name(AB_OTA_PAYLOAD_PROPERTIES);
219   ZipEntry properties_entry;
220   if (FindEntry(zip, property_name, &properties_entry) != 0) {
221     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD_PROPERTIES;
222     return INSTALL_CORRUPT;
223   }
224   uint32_t properties_entry_length = properties_entry.uncompressed_length;
225   std::vector<uint8_t> payload_properties(properties_entry_length);
226   int32_t err =
227       ExtractToMemory(zip, &properties_entry, payload_properties.data(), properties_entry_length);
228   if (err != 0) {
229     LOG(ERROR) << "Failed to extract " << AB_OTA_PAYLOAD_PROPERTIES << ": " << ErrorCodeString(err);
230     return INSTALL_CORRUPT;
231   }
232 
233   static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
234   ZipString payload_name(AB_OTA_PAYLOAD);
235   ZipEntry payload_entry;
236   if (FindEntry(zip, payload_name, &payload_entry) != 0) {
237     LOG(ERROR) << "Failed to find " << AB_OTA_PAYLOAD;
238     return INSTALL_CORRUPT;
239   }
240   long payload_offset = payload_entry.offset;
241   *cmd = {
242     binary_path,
243     "--payload=file://" + package,
244     android::base::StringPrintf("--offset=%ld", payload_offset),
245     "--headers=" + std::string(payload_properties.begin(), payload_properties.end()),
246     android::base::StringPrintf("--status_fd=%d", status_fd),
247   };
248   return 0;
249 }
250 
251 #else  // !AB_OTA_UPDATER
252 
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)253 int update_binary_command(const std::string& package, ZipArchiveHandle zip,
254                           const std::string& binary_path, int retry_count, int status_fd,
255                           std::vector<std::string>* cmd) {
256   CHECK(cmd != nullptr);
257 
258   // On traditional updates we extract the update binary from the package.
259   static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
260   ZipString binary_name(UPDATE_BINARY_NAME);
261   ZipEntry binary_entry;
262   if (FindEntry(zip, binary_name, &binary_entry) != 0) {
263     LOG(ERROR) << "Failed to find update binary " << UPDATE_BINARY_NAME;
264     return INSTALL_CORRUPT;
265   }
266 
267   unlink(binary_path.c_str());
268   int fd = open(binary_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755);
269   if (fd == -1) {
270     PLOG(ERROR) << "Failed to create " << binary_path;
271     return INSTALL_ERROR;
272   }
273 
274   int32_t error = ExtractEntryToFile(zip, &binary_entry, fd);
275   close(fd);
276   if (error != 0) {
277     LOG(ERROR) << "Failed to extract " << UPDATE_BINARY_NAME << ": " << ErrorCodeString(error);
278     return INSTALL_ERROR;
279   }
280 
281   *cmd = {
282     binary_path,
283     EXPAND(RECOVERY_API_VERSION),  // defined in Android.mk
284     std::to_string(status_fd),
285     package,
286   };
287   if (retry_count > 0) {
288     cmd->push_back("retry");
289   }
290   return 0;
291 }
292 #endif  // !AB_OTA_UPDATER
293 
log_max_temperature(int * max_temperature,const std::atomic<bool> & logger_finished)294 static void log_max_temperature(int* max_temperature, const std::atomic<bool>& logger_finished) {
295   CHECK(max_temperature != nullptr);
296   std::mutex mtx;
297   std::unique_lock<std::mutex> lck(mtx);
298   while (!logger_finished.load() &&
299          finish_log_temperature.wait_for(lck, 20s) == std::cv_status::timeout) {
300     *max_temperature = std::max(*max_temperature, GetMaxValueFromThermalZone());
301   }
302 }
303 
304 // 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)305 static int try_update_binary(const std::string& package, ZipArchiveHandle zip, bool* wipe_cache,
306                              std::vector<std::string>* log_buffer, int retry_count,
307                              int* max_temperature) {
308   read_source_target_build(zip, log_buffer);
309 
310   int pipefd[2];
311   pipe(pipefd);
312 
313   std::vector<std::string> args;
314 #ifdef AB_OTA_UPDATER
315   int ret = update_binary_command(package, zip, "/sbin/update_engine_sideload", retry_count,
316                                   pipefd[1], &args);
317 #else
318   int ret = update_binary_command(package, zip, "/tmp/update-binary", retry_count, pipefd[1],
319                                   &args);
320 #endif
321   if (ret) {
322     close(pipefd[0]);
323     close(pipefd[1]);
324     return ret;
325   }
326 
327   // When executing the update binary contained in the package, the
328   // arguments passed are:
329   //
330   //   - the version number for this interface
331   //
332   //   - an FD to which the program can write in order to update the
333   //     progress bar.  The program can write single-line commands:
334   //
335   //        progress <frac> <secs>
336   //            fill up the next <frac> part of of the progress bar
337   //            over <secs> seconds.  If <secs> is zero, use
338   //            set_progress commands to manually control the
339   //            progress of this segment of the bar.
340   //
341   //        set_progress <frac>
342   //            <frac> should be between 0.0 and 1.0; sets the
343   //            progress bar within the segment defined by the most
344   //            recent progress command.
345   //
346   //        ui_print <string>
347   //            display <string> on the screen.
348   //
349   //        wipe_cache
350   //            a wipe of cache will be performed following a successful
351   //            installation.
352   //
353   //        clear_display
354   //            turn off the text display.
355   //
356   //        enable_reboot
357   //            packages can explicitly request that they want the user
358   //            to be able to reboot during installation (useful for
359   //            debugging packages that don't exit).
360   //
361   //        retry_update
362   //            updater encounters some issue during the update. It requests
363   //            a reboot to retry the same package automatically.
364   //
365   //        log <string>
366   //            updater requests logging the string (e.g. cause of the
367   //            failure).
368   //
369   //   - the name of the package zip file.
370   //
371   //   - an optional argument "retry" if this update is a retry of a failed
372   //   update attempt.
373   //
374 
375   // Convert the vector to a NULL-terminated char* array suitable for execv.
376   const char* chr_args[args.size() + 1];
377   chr_args[args.size()] = nullptr;
378   for (size_t i = 0; i < args.size(); i++) {
379     chr_args[i] = args[i].c_str();
380   }
381 
382   pid_t pid = fork();
383 
384   if (pid == -1) {
385     close(pipefd[0]);
386     close(pipefd[1]);
387     PLOG(ERROR) << "Failed to fork update binary";
388     return INSTALL_ERROR;
389   }
390 
391   if (pid == 0) {
392     umask(022);
393     close(pipefd[0]);
394     execv(chr_args[0], const_cast<char**>(chr_args));
395     // Bug: 34769056
396     // We shouldn't use LOG/PLOG in the forked process, since they may cause
397     // the child process to hang. This deadlock results from an improperly
398     // copied mutex in the ui functions.
399     fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
400     _exit(EXIT_FAILURE);
401   }
402   close(pipefd[1]);
403 
404   std::atomic<bool> logger_finished(false);
405   std::thread temperature_logger(log_max_temperature, max_temperature, std::ref(logger_finished));
406 
407   *wipe_cache = false;
408   bool retry_update = false;
409 
410   char buffer[1024];
411   FILE* from_child = fdopen(pipefd[0], "r");
412   while (fgets(buffer, sizeof(buffer), from_child) != nullptr) {
413     std::string line(buffer);
414     size_t space = line.find_first_of(" \n");
415     std::string command(line.substr(0, space));
416     if (command.empty()) continue;
417 
418     // Get rid of the leading and trailing space and/or newline.
419     std::string args = space == std::string::npos ? "" : android::base::Trim(line.substr(space));
420 
421     if (command == "progress") {
422       std::vector<std::string> tokens = android::base::Split(args, " ");
423       double fraction;
424       int seconds;
425       if (tokens.size() == 2 && android::base::ParseDouble(tokens[0].c_str(), &fraction) &&
426           android::base::ParseInt(tokens[1], &seconds)) {
427         ui->ShowProgress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), seconds);
428       } else {
429         LOG(ERROR) << "invalid \"progress\" parameters: " << line;
430       }
431     } else if (command == "set_progress") {
432       std::vector<std::string> tokens = android::base::Split(args, " ");
433       double fraction;
434       if (tokens.size() == 1 && android::base::ParseDouble(tokens[0].c_str(), &fraction)) {
435         ui->SetProgress(fraction);
436       } else {
437         LOG(ERROR) << "invalid \"set_progress\" parameters: " << line;
438       }
439     } else if (command == "ui_print") {
440       ui->PrintOnScreenOnly("%s\n", args.c_str());
441       fflush(stdout);
442     } else if (command == "wipe_cache") {
443       *wipe_cache = true;
444     } else if (command == "clear_display") {
445       ui->SetBackground(RecoveryUI::NONE);
446     } else if (command == "enable_reboot") {
447       // packages can explicitly request that they want the user
448       // to be able to reboot during installation (useful for
449       // debugging packages that don't exit).
450       ui->SetEnableReboot(true);
451     } else if (command == "retry_update") {
452       retry_update = true;
453     } else if (command == "log") {
454       if (!args.empty()) {
455         // Save the logging request from updater and write to last_install later.
456         log_buffer->push_back(args);
457       } else {
458         LOG(ERROR) << "invalid \"log\" parameters: " << line;
459       }
460     } else {
461       LOG(ERROR) << "unknown command [" << command << "]";
462     }
463   }
464   fclose(from_child);
465 
466   int status;
467   waitpid(pid, &status, 0);
468 
469   logger_finished.store(true);
470   finish_log_temperature.notify_one();
471   temperature_logger.join();
472 
473   if (retry_update) {
474     return INSTALL_RETRY;
475   }
476   if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
477     LOG(ERROR) << "Error in " << package << " (Status " << WEXITSTATUS(status) << ")";
478     return INSTALL_ERROR;
479   }
480 
481   return INSTALL_SUCCESS;
482 }
483 
484 // Verifes the compatibility info in a Treble-compatible package. Returns true directly if the
485 // entry doesn't exist. Note that the compatibility info is packed in a zip file inside the OTA
486 // package.
verify_package_compatibility(ZipArchiveHandle package_zip)487 bool verify_package_compatibility(ZipArchiveHandle package_zip) {
488   LOG(INFO) << "Verifying package compatibility...";
489 
490   static constexpr const char* COMPATIBILITY_ZIP_ENTRY = "compatibility.zip";
491   ZipString compatibility_entry_name(COMPATIBILITY_ZIP_ENTRY);
492   ZipEntry compatibility_entry;
493   if (FindEntry(package_zip, compatibility_entry_name, &compatibility_entry) != 0) {
494     LOG(INFO) << "Package doesn't contain " << COMPATIBILITY_ZIP_ENTRY << " entry";
495     return true;
496   }
497 
498   std::string zip_content(compatibility_entry.uncompressed_length, '\0');
499   int32_t ret;
500   if ((ret = ExtractToMemory(package_zip, &compatibility_entry,
501                              reinterpret_cast<uint8_t*>(&zip_content[0]),
502                              compatibility_entry.uncompressed_length)) != 0) {
503     LOG(ERROR) << "Failed to read " << COMPATIBILITY_ZIP_ENTRY << ": " << ErrorCodeString(ret);
504     return false;
505   }
506 
507   ZipArchiveHandle zip_handle;
508   ret = OpenArchiveFromMemory(static_cast<void*>(const_cast<char*>(zip_content.data())),
509                               zip_content.size(), COMPATIBILITY_ZIP_ENTRY, &zip_handle);
510   if (ret != 0) {
511     LOG(ERROR) << "Failed to OpenArchiveFromMemory: " << ErrorCodeString(ret);
512     return false;
513   }
514 
515   // Iterate all the entries inside COMPATIBILITY_ZIP_ENTRY and read the contents.
516   void* cookie;
517   ret = StartIteration(zip_handle, &cookie, nullptr, nullptr);
518   if (ret != 0) {
519     LOG(ERROR) << "Failed to start iterating zip entries: " << ErrorCodeString(ret);
520     CloseArchive(zip_handle);
521     return false;
522   }
523   std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
524 
525   std::vector<std::string> compatibility_info;
526   ZipEntry info_entry;
527   ZipString info_name;
528   while (Next(cookie, &info_entry, &info_name) == 0) {
529     std::string content(info_entry.uncompressed_length, '\0');
530     int32_t ret = ExtractToMemory(zip_handle, &info_entry, reinterpret_cast<uint8_t*>(&content[0]),
531                                   info_entry.uncompressed_length);
532     if (ret != 0) {
533       LOG(ERROR) << "Failed to read " << info_name.name << ": " << ErrorCodeString(ret);
534       CloseArchive(zip_handle);
535       return false;
536     }
537     compatibility_info.emplace_back(std::move(content));
538   }
539   CloseArchive(zip_handle);
540 
541   // VintfObjectRecovery::CheckCompatibility returns zero on success.
542   std::string err;
543   int result = android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err);
544   if (result == 0) {
545     return true;
546   }
547 
548   LOG(ERROR) << "Failed to verify package compatibility (result " << result << "): " << err;
549   return false;
550 }
551 
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)552 static int really_install_package(const std::string& path, bool* wipe_cache, bool needs_mount,
553                                   std::vector<std::string>* log_buffer, int retry_count,
554                                   int* max_temperature) {
555   ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
556   ui->Print("Finding update package...\n");
557   // Give verification half the progress bar...
558   ui->SetProgressType(RecoveryUI::DETERMINATE);
559   ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
560   LOG(INFO) << "Update location: " << path;
561 
562   // Map the update package into memory.
563   ui->Print("Opening update package...\n");
564 
565   if (needs_mount) {
566     if (path[0] == '@') {
567       ensure_path_mounted(path.substr(1).c_str());
568     } else {
569       ensure_path_mounted(path.c_str());
570     }
571   }
572 
573   MemMapping map;
574   if (!map.MapFile(path)) {
575     LOG(ERROR) << "failed to map file";
576     return INSTALL_CORRUPT;
577   }
578 
579   // Verify package.
580   if (!verify_package(map.addr, map.length)) {
581     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
582     return INSTALL_CORRUPT;
583   }
584 
585   // Try to open the package.
586   ZipArchiveHandle zip;
587   int err = OpenArchiveFromMemory(map.addr, map.length, path.c_str(), &zip);
588   if (err != 0) {
589     LOG(ERROR) << "Can't open " << path << " : " << ErrorCodeString(err);
590     log_buffer->push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
591 
592     CloseArchive(zip);
593     return INSTALL_CORRUPT;
594   }
595 
596   // Additionally verify the compatibility of the package.
597   if (!verify_package_compatibility(zip)) {
598     log_buffer->push_back(android::base::StringPrintf("error: %d", kPackageCompatibilityFailure));
599     CloseArchive(zip);
600     return INSTALL_CORRUPT;
601   }
602 
603   // Verify and install the contents of the package.
604   ui->Print("Installing update...\n");
605   if (retry_count > 0) {
606     ui->Print("Retry attempt: %d\n", retry_count);
607   }
608   ui->SetEnableReboot(false);
609   int result = try_update_binary(path, zip, wipe_cache, log_buffer, retry_count, max_temperature);
610   ui->SetEnableReboot(true);
611   ui->Print("\n");
612 
613   CloseArchive(zip);
614   return result;
615 }
616 
install_package(const std::string & path,bool * wipe_cache,const std::string & install_file,bool needs_mount,int retry_count)617 int install_package(const std::string& path, bool* wipe_cache, const std::string& install_file,
618                     bool needs_mount, int retry_count) {
619   CHECK(!path.empty());
620   CHECK(!install_file.empty());
621   CHECK(wipe_cache != nullptr);
622 
623   modified_flash = true;
624   auto start = std::chrono::system_clock::now();
625 
626   int start_temperature = GetMaxValueFromThermalZone();
627   int max_temperature = start_temperature;
628 
629   int result;
630   std::vector<std::string> log_buffer;
631   if (setup_install_mounts() != 0) {
632     LOG(ERROR) << "failed to set up expected mounts for install; aborting";
633     result = INSTALL_ERROR;
634   } else {
635     result = really_install_package(path, wipe_cache, needs_mount, &log_buffer, retry_count,
636                                     &max_temperature);
637   }
638 
639   // Measure the time spent to apply OTA update in seconds.
640   std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
641   int time_total = static_cast<int>(duration.count());
642 
643   bool has_cache = volume_for_path("/cache") != nullptr;
644   // Skip logging the uncrypt_status on devices without /cache.
645   if (has_cache) {
646     static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
647     if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
648       LOG(WARNING) << "Can't mount " << UNCRYPT_STATUS;
649     } else {
650       std::string uncrypt_status;
651       if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
652         PLOG(WARNING) << "failed to read uncrypt status";
653       } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
654         LOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
655       } else {
656         log_buffer.push_back(android::base::Trim(uncrypt_status));
657       }
658     }
659   }
660 
661   // The first two lines need to be the package name and install result.
662   std::vector<std::string> log_header = {
663     path,
664     result == INSTALL_SUCCESS ? "1" : "0",
665     "time_total: " + std::to_string(time_total),
666     "retry: " + std::to_string(retry_count),
667   };
668 
669   int end_temperature = GetMaxValueFromThermalZone();
670   max_temperature = std::max(end_temperature, max_temperature);
671   if (start_temperature > 0) {
672     log_buffer.push_back("temperature_start: " + std::to_string(start_temperature));
673   }
674   if (end_temperature > 0) {
675     log_buffer.push_back("temperature_end: " + std::to_string(end_temperature));
676   }
677   if (max_temperature > 0) {
678     log_buffer.push_back("temperature_max: " + std::to_string(max_temperature));
679   }
680 
681   std::string log_content =
682       android::base::Join(log_header, "\n") + "\n" + android::base::Join(log_buffer, "\n") + "\n";
683   if (!android::base::WriteStringToFile(log_content, install_file)) {
684     PLOG(ERROR) << "failed to write " << install_file;
685   }
686 
687   // Write a copy into last_log.
688   LOG(INFO) << log_content;
689 
690   return result;
691 }
692 
verify_package(const unsigned char * package_data,size_t package_size)693 bool verify_package(const unsigned char* package_data, size_t package_size) {
694   static constexpr const char* PUBLIC_KEYS_FILE = "/res/keys";
695   std::vector<Certificate> loadedKeys;
696   if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {
697     LOG(ERROR) << "Failed to load keys";
698     return false;
699   }
700   LOG(INFO) << loadedKeys.size() << " key(s) loaded from " << PUBLIC_KEYS_FILE;
701 
702   // Verify package.
703   ui->Print("Verifying update package...\n");
704   auto t0 = std::chrono::system_clock::now();
705   int err = verify_file(package_data, package_size, loadedKeys,
706                         std::bind(&RecoveryUI::SetProgress, ui, std::placeholders::_1));
707   std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
708   ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
709   if (err != VERIFY_SUCCESS) {
710     LOG(ERROR) << "Signature verification failed";
711     LOG(ERROR) << "error: " << kZipVerificationFailure;
712     return false;
713   }
714   return true;
715 }
716