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