• 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 <ctype.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <inttypes.h>
21 #include <limits.h>
22 #include <string.h>
23 #include <sys/stat.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 
27 #include <chrono>
28 #include <limits>
29 #include <map>
30 #include <string>
31 #include <vector>
32 
33 #include <android-base/file.h>
34 #include <android-base/parseint.h>
35 #include <android-base/stringprintf.h>
36 #include <android-base/strings.h>
37 #include <cutils/properties.h>
38 
39 #include "common.h"
40 #include "error_code.h"
41 #include "install.h"
42 #include "minui/minui.h"
43 #include "minzip/SysUtil.h"
44 #include "minzip/Zip.h"
45 #include "mtdutils/mounts.h"
46 #include "mtdutils/mtdutils.h"
47 #include "roots.h"
48 #include "ui.h"
49 #include "verifier.h"
50 
51 extern RecoveryUI* ui;
52 
53 #define ASSUMED_UPDATE_BINARY_NAME  "META-INF/com/google/android/update-binary"
54 static constexpr const char* AB_OTA_PAYLOAD_PROPERTIES = "payload_properties.txt";
55 static constexpr const char* AB_OTA_PAYLOAD = "payload.bin";
56 #define PUBLIC_KEYS_FILE "/res/keys"
57 static constexpr const char* METADATA_PATH = "META-INF/com/android/metadata";
58 static constexpr const char* UNCRYPT_STATUS = "/cache/recovery/uncrypt_status";
59 
60 // Default allocation of progress bar segments to operations
61 static const int VERIFICATION_PROGRESS_TIME = 60;
62 static const float VERIFICATION_PROGRESS_FRACTION = 0.25;
63 static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
64 static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
65 
66 // This function parses and returns the build.version.incremental
parse_build_number(std::string str)67 static int parse_build_number(std::string str) {
68     size_t pos = str.find("=");
69     if (pos != std::string::npos) {
70         std::string num_string = android::base::Trim(str.substr(pos+1));
71         int build_number;
72         if (android::base::ParseInt(num_string.c_str(), &build_number, 0)) {
73             return build_number;
74         }
75     }
76 
77     LOGE("Failed to parse build number in %s.\n", str.c_str());
78     return -1;
79 }
80 
read_metadata_from_package(ZipArchive * zip,std::string * meta_data)81 bool read_metadata_from_package(ZipArchive* zip, std::string* meta_data) {
82     const ZipEntry* meta_entry = mzFindZipEntry(zip, METADATA_PATH);
83     if (meta_entry == nullptr) {
84         LOGE("Failed to find %s in update package.\n", METADATA_PATH);
85         return false;
86     }
87 
88     meta_data->resize(meta_entry->uncompLen, '\0');
89     if (!mzReadZipEntry(zip, meta_entry, &(*meta_data)[0], meta_entry->uncompLen)) {
90         LOGE("Failed to read metadata in update package.\n");
91         return false;
92     }
93     return true;
94 }
95 
96 // Read the build.version.incremental of src/tgt from the metadata and log it to last_install.
read_source_target_build(ZipArchive * zip,std::vector<std::string> & log_buffer)97 static void read_source_target_build(ZipArchive* zip, std::vector<std::string>& log_buffer) {
98     std::string meta_data;
99     if (!read_metadata_from_package(zip, &meta_data)) {
100         return;
101     }
102     // Examples of the pre-build and post-build strings in metadata:
103     // pre-build-incremental=2943039
104     // post-build-incremental=2951741
105     std::vector<std::string> lines = android::base::Split(meta_data, "\n");
106     for (const std::string& line : lines) {
107         std::string str = android::base::Trim(line);
108         if (android::base::StartsWith(str, "pre-build-incremental")){
109             int source_build = parse_build_number(str);
110             if (source_build != -1) {
111                 log_buffer.push_back(android::base::StringPrintf("source_build: %d",
112                         source_build));
113             }
114         } else if (android::base::StartsWith(str, "post-build-incremental")) {
115             int target_build = parse_build_number(str);
116             if (target_build != -1) {
117                 log_buffer.push_back(android::base::StringPrintf("target_build: %d",
118                         target_build));
119             }
120         }
121     }
122 }
123 
124 // Extract the update binary from the open zip archive |zip| located at |path|
125 // and store into |cmd| the command line that should be called. The |status_fd|
126 // is the file descriptor the child process should use to report back the
127 // progress of the update.
128 static int
129 update_binary_command(const char* path, ZipArchive* zip, int retry_count,
130                       int status_fd, std::vector<std::string>* cmd);
131 
132 #ifdef AB_OTA_UPDATER
133 
134 // Parses the metadata of the OTA package in |zip| and checks whether we are
135 // allowed to accept this A/B package. Downgrading is not allowed unless
136 // explicitly enabled in the package and only for incremental packages.
check_newer_ab_build(ZipArchive * zip)137 static int check_newer_ab_build(ZipArchive* zip)
138 {
139     std::string metadata_str;
140     if (!read_metadata_from_package(zip, &metadata_str)) {
141         return INSTALL_CORRUPT;
142     }
143     std::map<std::string, std::string> metadata;
144     for (const std::string& line : android::base::Split(metadata_str, "\n")) {
145         size_t eq = line.find('=');
146         if (eq != std::string::npos) {
147             metadata[line.substr(0, eq)] = line.substr(eq + 1);
148         }
149     }
150     char value[PROPERTY_VALUE_MAX];
151 
152     property_get("ro.product.device", value, "");
153     const std::string& pkg_device = metadata["pre-device"];
154     if (pkg_device != value || pkg_device.empty()) {
155         LOGE("Package is for product %s but expected %s\n",
156              pkg_device.c_str(), value);
157         return INSTALL_ERROR;
158     }
159 
160     // We allow the package to not have any serialno, but if it has a non-empty
161     // value it should match.
162     property_get("ro.serialno", value, "");
163     const std::string& pkg_serial_no = metadata["serialno"];
164     if (!pkg_serial_no.empty() && pkg_serial_no != value) {
165         LOGE("Package is for serial %s\n", pkg_serial_no.c_str());
166         return INSTALL_ERROR;
167     }
168 
169     if (metadata["ota-type"] != "AB") {
170         LOGE("Package is not A/B\n");
171         return INSTALL_ERROR;
172     }
173 
174     // Incremental updates should match the current build.
175     property_get("ro.build.version.incremental", value, "");
176     const std::string& pkg_pre_build = metadata["pre-build-incremental"];
177     if (!pkg_pre_build.empty() && pkg_pre_build != value) {
178         LOGE("Package is for source build %s but expected %s\n",
179              pkg_pre_build.c_str(), value);
180         return INSTALL_ERROR;
181     }
182     property_get("ro.build.fingerprint", value, "");
183     const std::string& pkg_pre_build_fingerprint = metadata["pre-build"];
184     if (!pkg_pre_build_fingerprint.empty() &&
185         pkg_pre_build_fingerprint != value) {
186         LOGE("Package is for source build %s but expected %s\n",
187              pkg_pre_build_fingerprint.c_str(), value);
188         return INSTALL_ERROR;
189     }
190 
191     // Check for downgrade version.
192     int64_t build_timestampt = property_get_int64(
193             "ro.build.date.utc", std::numeric_limits<int64_t>::max());
194     int64_t pkg_post_timespampt = 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(),
199                                  &pkg_post_timespampt) ||
200         pkg_post_timespampt < build_timestampt) {
201         if (metadata["ota-downgrade"] != "yes") {
202             LOGE("Update package is older than the current build, expected a "
203                  "build newer than timestamp %" PRIu64 " but package has "
204                  "timestamp %" PRIu64 " and downgrade not allowed.\n",
205                  build_timestampt, pkg_post_timespampt);
206             return INSTALL_ERROR;
207         }
208         if (pkg_pre_build_fingerprint.empty()) {
209             LOGE("Downgrade package must have a pre-build version set, not "
210                  "allowed.\n");
211             return INSTALL_ERROR;
212         }
213     }
214 
215     return 0;
216 }
217 
218 static int
update_binary_command(const char * path,ZipArchive * zip,int retry_count,int status_fd,std::vector<std::string> * cmd)219 update_binary_command(const char* path, ZipArchive* zip, int retry_count,
220                       int status_fd, std::vector<std::string>* cmd)
221 {
222     int ret = check_newer_ab_build(zip);
223     if (ret) {
224         return ret;
225     }
226 
227     // For A/B updates we extract the payload properties to a buffer and obtain
228     // the RAW payload offset in the zip file.
229     const ZipEntry* properties_entry =
230             mzFindZipEntry(zip, AB_OTA_PAYLOAD_PROPERTIES);
231     if (!properties_entry) {
232         LOGE("Can't find %s\n", AB_OTA_PAYLOAD_PROPERTIES);
233         return INSTALL_CORRUPT;
234     }
235     std::vector<unsigned char> payload_properties(
236             mzGetZipEntryUncompLen(properties_entry));
237     if (!mzExtractZipEntryToBuffer(zip, properties_entry,
238                                    payload_properties.data())) {
239         LOGE("Can't extract %s\n", AB_OTA_PAYLOAD_PROPERTIES);
240         return INSTALL_CORRUPT;
241     }
242 
243     const ZipEntry* payload_entry = mzFindZipEntry(zip, AB_OTA_PAYLOAD);
244     if (!payload_entry) {
245         LOGE("Can't find %s\n", AB_OTA_PAYLOAD);
246         return INSTALL_CORRUPT;
247     }
248     long payload_offset = mzGetZipEntryOffset(payload_entry);
249     *cmd = {
250         "/sbin/update_engine_sideload",
251         android::base::StringPrintf("--payload=file://%s", path),
252         android::base::StringPrintf("--offset=%ld", payload_offset),
253         "--headers=" + std::string(payload_properties.begin(),
254                                    payload_properties.end()),
255         android::base::StringPrintf("--status_fd=%d", status_fd),
256     };
257     return 0;
258 }
259 
260 #else  // !AB_OTA_UPDATER
261 
262 static int
update_binary_command(const char * path,ZipArchive * zip,int retry_count,int status_fd,std::vector<std::string> * cmd)263 update_binary_command(const char* path, ZipArchive* zip, int retry_count,
264                       int status_fd, std::vector<std::string>* cmd)
265 {
266     // On traditional updates we extract the update binary from the package.
267     const ZipEntry* binary_entry =
268             mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME);
269     if (binary_entry == NULL) {
270         return INSTALL_CORRUPT;
271     }
272 
273     const char* binary = "/tmp/update_binary";
274     unlink(binary);
275     int fd = creat(binary, 0755);
276     if (fd < 0) {
277         LOGE("Can't make %s\n", binary);
278         return INSTALL_ERROR;
279     }
280     bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd);
281     close(fd);
282 
283     if (!ok) {
284         LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME);
285         return INSTALL_ERROR;
286     }
287 
288     *cmd = {
289         binary,
290         EXPAND(RECOVERY_API_VERSION),   // defined in Android.mk
291         std::to_string(status_fd),
292         path,
293     };
294     if (retry_count > 0)
295         cmd->push_back("retry");
296     return 0;
297 }
298 #endif  // !AB_OTA_UPDATER
299 
300 // If the package contains an update binary, extract it and run it.
301 static int
try_update_binary(const char * path,ZipArchive * zip,bool * wipe_cache,std::vector<std::string> & log_buffer,int retry_count)302 try_update_binary(const char* path, ZipArchive* zip, bool* wipe_cache,
303                   std::vector<std::string>& log_buffer, int retry_count)
304 {
305     read_source_target_build(zip, log_buffer);
306 
307     int pipefd[2];
308     pipe(pipefd);
309 
310     std::vector<std::string> args;
311     int ret = update_binary_command(path, zip, retry_count, pipefd[1], &args);
312     mzCloseZipArchive(zip);
313     if (ret) {
314         close(pipefd[0]);
315         close(pipefd[1]);
316         return ret;
317     }
318 
319     // When executing the update binary contained in the package, the
320     // arguments passed are:
321     //
322     //   - the version number for this interface
323     //
324     //   - an fd to which the program can write in order to update the
325     //     progress bar.  The program can write single-line commands:
326     //
327     //        progress <frac> <secs>
328     //            fill up the next <frac> part of of the progress bar
329     //            over <secs> seconds.  If <secs> is zero, use
330     //            set_progress commands to manually control the
331     //            progress of this segment of the bar.
332     //
333     //        set_progress <frac>
334     //            <frac> should be between 0.0 and 1.0; sets the
335     //            progress bar within the segment defined by the most
336     //            recent progress command.
337     //
338     //        firmware <"hboot"|"radio"> <filename>
339     //            arrange to install the contents of <filename> in the
340     //            given partition on reboot.
341     //
342     //            (API v2: <filename> may start with "PACKAGE:" to
343     //            indicate taking a file from the OTA package.)
344     //
345     //            (API v3: this command no longer exists.)
346     //
347     //        ui_print <string>
348     //            display <string> on the screen.
349     //
350     //        wipe_cache
351     //            a wipe of cache will be performed following a successful
352     //            installation.
353     //
354     //        clear_display
355     //            turn off the text display.
356     //
357     //        enable_reboot
358     //            packages can explicitly request that they want the user
359     //            to be able to reboot during installation (useful for
360     //            debugging packages that don't exit).
361     //
362     //   - the name of the package zip file.
363     //
364     //   - an optional argument "retry" if this update is a retry of a failed
365     //   update attempt.
366     //
367 
368     // Convert the vector to a NULL-terminated char* array suitable for execv.
369     const char* chr_args[args.size() + 1];
370     chr_args[args.size()] = NULL;
371     for (size_t i = 0; i < args.size(); i++) {
372         chr_args[i] = args[i].c_str();
373     }
374 
375     pid_t pid = fork();
376 
377     if (pid == -1) {
378         close(pipefd[0]);
379         close(pipefd[1]);
380         LOGE("Failed to fork update binary: %s\n", strerror(errno));
381         return INSTALL_ERROR;
382     }
383 
384     if (pid == 0) {
385         umask(022);
386         close(pipefd[0]);
387         execv(chr_args[0], const_cast<char**>(chr_args));
388         fprintf(stdout, "E:Can't run %s (%s)\n", chr_args[0], strerror(errno));
389         _exit(-1);
390     }
391     close(pipefd[1]);
392 
393     *wipe_cache = false;
394     bool retry_update = false;
395 
396     char buffer[1024];
397     FILE* from_child = fdopen(pipefd[0], "r");
398     while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
399         char* command = strtok(buffer, " \n");
400         if (command == NULL) {
401             continue;
402         } else if (strcmp(command, "progress") == 0) {
403             char* fraction_s = strtok(NULL, " \n");
404             char* seconds_s = strtok(NULL, " \n");
405 
406             float fraction = strtof(fraction_s, NULL);
407             int seconds = strtol(seconds_s, NULL, 10);
408 
409             ui->ShowProgress(fraction * (1-VERIFICATION_PROGRESS_FRACTION), seconds);
410         } else if (strcmp(command, "set_progress") == 0) {
411             char* fraction_s = strtok(NULL, " \n");
412             float fraction = strtof(fraction_s, NULL);
413             ui->SetProgress(fraction);
414         } else if (strcmp(command, "ui_print") == 0) {
415             char* str = strtok(NULL, "\n");
416             if (str) {
417                 ui->PrintOnScreenOnly("%s", str);
418             } else {
419                 ui->PrintOnScreenOnly("\n");
420             }
421             fflush(stdout);
422         } else if (strcmp(command, "wipe_cache") == 0) {
423             *wipe_cache = true;
424         } else if (strcmp(command, "clear_display") == 0) {
425             ui->SetBackground(RecoveryUI::NONE);
426         } else if (strcmp(command, "enable_reboot") == 0) {
427             // packages can explicitly request that they want the user
428             // to be able to reboot during installation (useful for
429             // debugging packages that don't exit).
430             ui->SetEnableReboot(true);
431         } else if (strcmp(command, "retry_update") == 0) {
432             retry_update = true;
433         } else if (strcmp(command, "log") == 0) {
434             // Save the logging request from updater and write to
435             // last_install later.
436             log_buffer.push_back(std::string(strtok(NULL, "\n")));
437         } else {
438             LOGE("unknown command [%s]\n", command);
439         }
440     }
441     fclose(from_child);
442 
443     int status;
444     waitpid(pid, &status, 0);
445     if (retry_update) {
446         return INSTALL_RETRY;
447     }
448     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
449         LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status));
450         return INSTALL_ERROR;
451     }
452 
453     return INSTALL_SUCCESS;
454 }
455 
456 static int
really_install_package(const char * path,bool * wipe_cache,bool needs_mount,std::vector<std::string> & log_buffer,int retry_count)457 really_install_package(const char *path, bool* wipe_cache, bool needs_mount,
458                        std::vector<std::string>& log_buffer, int retry_count)
459 {
460     ui->SetBackground(RecoveryUI::INSTALLING_UPDATE);
461     ui->Print("Finding update package...\n");
462     // Give verification half the progress bar...
463     ui->SetProgressType(RecoveryUI::DETERMINATE);
464     ui->ShowProgress(VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME);
465     LOGI("Update location: %s\n", path);
466 
467     // Map the update package into memory.
468     ui->Print("Opening update package...\n");
469 
470     if (path && needs_mount) {
471         if (path[0] == '@') {
472             ensure_path_mounted(path+1);
473         } else {
474             ensure_path_mounted(path);
475         }
476     }
477 
478     MemMapping map;
479     if (sysMapFile(path, &map) != 0) {
480         LOGE("failed to map file\n");
481         return INSTALL_CORRUPT;
482     }
483 
484     // Verify package.
485     if (!verify_package(map.addr, map.length)) {
486         log_buffer.push_back(android::base::StringPrintf("error: %d", kZipVerificationFailure));
487         sysReleaseMap(&map);
488         return INSTALL_CORRUPT;
489     }
490 
491     // Try to open the package.
492     ZipArchive zip;
493     int err = mzOpenZipArchive(map.addr, map.length, &zip);
494     if (err != 0) {
495         LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
496         log_buffer.push_back(android::base::StringPrintf("error: %d", kZipOpenFailure));
497 
498         sysReleaseMap(&map);
499         return INSTALL_CORRUPT;
500     }
501 
502     // Verify and install the contents of the package.
503     ui->Print("Installing update...\n");
504     if (retry_count > 0) {
505         ui->Print("Retry attempt: %d\n", retry_count);
506     }
507     ui->SetEnableReboot(false);
508     int result = try_update_binary(path, &zip, wipe_cache, log_buffer, retry_count);
509     ui->SetEnableReboot(true);
510     ui->Print("\n");
511 
512     sysReleaseMap(&map);
513 
514     return result;
515 }
516 
517 int
install_package(const char * path,bool * wipe_cache,const char * install_file,bool needs_mount,int retry_count)518 install_package(const char* path, bool* wipe_cache, const char* install_file,
519                 bool needs_mount, int retry_count)
520 {
521     modified_flash = true;
522     auto start = std::chrono::system_clock::now();
523 
524     int result;
525     std::vector<std::string> log_buffer;
526     if (setup_install_mounts() != 0) {
527         LOGE("failed to set up expected mounts for install; aborting\n");
528         result = INSTALL_ERROR;
529     } else {
530         result = really_install_package(path, wipe_cache, needs_mount, log_buffer, retry_count);
531     }
532 
533     // Measure the time spent to apply OTA update in seconds.
534     std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
535     int time_total = static_cast<int>(duration.count());
536 
537     if (ensure_path_mounted(UNCRYPT_STATUS) != 0) {
538         LOGW("Can't mount %s\n", UNCRYPT_STATUS);
539     } else {
540         std::string uncrypt_status;
541         if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
542             LOGW("failed to read uncrypt status: %s\n", strerror(errno));
543         } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
544             LOGW("corrupted uncrypt_status: %s: %s\n", uncrypt_status.c_str(), strerror(errno));
545         } else {
546             log_buffer.push_back(android::base::Trim(uncrypt_status));
547         }
548     }
549 
550     // The first two lines need to be the package name and install result.
551     std::vector<std::string> log_header = {
552         path,
553         result == INSTALL_SUCCESS ? "1" : "0",
554         "time_total: " + std::to_string(time_total),
555         "retry: " + std::to_string(retry_count),
556     };
557     std::string log_content = android::base::Join(log_header, "\n") + "\n" +
558             android::base::Join(log_buffer, "\n");
559     if (!android::base::WriteStringToFile(log_content, install_file)) {
560         LOGE("failed to write %s: %s\n", install_file, strerror(errno));
561     }
562 
563     // Write a copy into last_log.
564     LOGI("%s\n", log_content.c_str());
565 
566     return result;
567 }
568 
verify_package(const unsigned char * package_data,size_t package_size)569 bool verify_package(const unsigned char* package_data, size_t package_size) {
570     std::vector<Certificate> loadedKeys;
571     if (!load_keys(PUBLIC_KEYS_FILE, loadedKeys)) {
572         LOGE("Failed to load keys\n");
573         return false;
574     }
575     LOGI("%zu key(s) loaded from %s\n", loadedKeys.size(), PUBLIC_KEYS_FILE);
576 
577     // Verify package.
578     ui->Print("Verifying update package...\n");
579     auto t0 = std::chrono::system_clock::now();
580     int err = verify_file(const_cast<unsigned char*>(package_data), package_size, loadedKeys);
581     std::chrono::duration<double> duration = std::chrono::system_clock::now() - t0;
582     ui->Print("Update package verification took %.1f s (result %d).\n", duration.count(), err);
583     if (err != VERIFY_SUCCESS) {
584         LOGE("Signature verification failed\n");
585         LOGE("error: %d\n", kZipVerificationFailure);
586         return false;
587     }
588     return true;
589 }
590